@superlogic/spree-pay 0.1.16 → 0.1.17

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/build/index.cjs CHANGED
@@ -38,8 +38,8 @@ __export(index_exports, {
38
38
  module.exports = __toCommonJS(index_exports);
39
39
 
40
40
  // src/SpreePay.tsx
41
- var import_react10 = require("react");
42
- var import_nice_modal_react6 = __toESM(require("@ebay/nice-modal-react"), 1);
41
+ var import_react16 = require("react");
42
+ var import_nice_modal_react7 = __toESM(require("@ebay/nice-modal-react"), 1);
43
43
  var import_swr4 = require("swr");
44
44
 
45
45
  // src/context/SpreePayActionsContext.tsx
@@ -123,6 +123,84 @@ var useSpreePayRegister = () => {
123
123
  return { register: ctx.register };
124
124
  };
125
125
 
126
+ // src/context/StaticConfigContext.tsx
127
+ var import_react2 = require("react");
128
+ var import_jsx_runtime2 = require("react/jsx-runtime");
129
+ var CONFIG = {
130
+ dev: {
131
+ bookit: {
132
+ slapiUrl: "https://slapi.dev.superlogic.com",
133
+ keyklockUrl: "https://auth.dev.join.bookit.com",
134
+ keyklockClientId: "oneof-next",
135
+ pointsConversionRatio: 100,
136
+ pointsTitle: "AIR SP"
137
+ },
138
+ moca: {
139
+ slapiUrl: "https://slapi.dev.air.shop",
140
+ keyklockUrl: "https://login.dev.air.shop",
141
+ keyklockClientId: "oneof-next",
142
+ pointsConversionRatio: 100,
143
+ pointsTitle: "AIR SP"
144
+ }
145
+ },
146
+ stg: {
147
+ bookit: {
148
+ slapiUrl: "https://slapi.stg.superlogic.com",
149
+ keyklockUrl: "https://auth.stg.join.bookit.com",
150
+ keyklockClientId: "oneof-next",
151
+ pointsConversionRatio: 100,
152
+ pointsTitle: "AIR SP"
153
+ },
154
+ moca: {
155
+ slapiUrl: "https://slapi.stg.air.shop",
156
+ keyklockUrl: "https://login.stg.air.shop",
157
+ keyklockClientId: "oneof-next",
158
+ pointsConversionRatio: 100,
159
+ pointsTitle: "AIR SP"
160
+ }
161
+ },
162
+ prod: {
163
+ bookit: {
164
+ slapiUrl: "https://slapi.superlogic.com",
165
+ keyklockUrl: "https://auth.join.bookit.com",
166
+ keyklockClientId: "oneof-next",
167
+ pointsConversionRatio: 100,
168
+ pointsTitle: "AIR SP"
169
+ },
170
+ moca: {
171
+ slapiUrl: "https://slapi.air.shop",
172
+ keyklockUrl: "https://login.air.shop",
173
+ keyklockClientId: "oneof-next",
174
+ pointsConversionRatio: 100,
175
+ pointsTitle: "AIR SP"
176
+ }
177
+ }
178
+ };
179
+ var StaticConfigContext = (0, import_react2.createContext)(null);
180
+ var StaticConfigProvider = ({ children, props }) => {
181
+ const { env } = useSpreePayEnv();
182
+ const [appProps, setAppProps] = (0, import_react2.useState)(props);
183
+ (0, import_react2.useEffect)(() => {
184
+ setAppProps(props);
185
+ }, [props]);
186
+ const staticConfig = (0, import_react2.useMemo)(() => {
187
+ return CONFIG[env.environment][env.tenantId];
188
+ }, [env.environment, env.tenantId]);
189
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(StaticConfigContext.Provider, { value: { staticConfig, appProps }, children });
190
+ };
191
+ var useStaticConfig = () => {
192
+ const ctx = (0, import_react2.useContext)(StaticConfigContext);
193
+ if (!ctx) throw new Error("useStaticConfig must be used within StaticConfigProvider");
194
+ return ctx;
195
+ };
196
+
197
+ // src/hooks/useSpreePayConfig.ts
198
+ var import_swr = __toESM(require("swr"), 1);
199
+ var useSpreePayConfig = () => {
200
+ const { data, isLoading } = (0, import_swr.default)("/v1/tenants/configs/spree-pay");
201
+ return { spreePayConfig: data, configIsLoading: isLoading };
202
+ };
203
+
126
204
  // src/lib/utils.ts
127
205
  var import_clsx = require("clsx");
128
206
  var import_tailwind_merge = require("tailwind-merge");
@@ -131,7 +209,7 @@ function cn(...inputs) {
131
209
  }
132
210
 
133
211
  // src/ui/spinner.tsx
134
- var import_jsx_runtime2 = require("react/jsx-runtime");
212
+ var import_jsx_runtime3 = require("react/jsx-runtime");
135
213
  var Spinner = (props) => {
136
214
  const { size = "md", className } = props;
137
215
  const sizeClasses = {
@@ -141,7 +219,7 @@ var Spinner = (props) => {
141
219
  lg: "size-12",
142
220
  xl: "size-16"
143
221
  };
144
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
222
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
145
223
  "svg",
146
224
  {
147
225
  className: cn(`${sizeClasses[size]} animate-spin text-gray-300`, className),
@@ -151,7 +229,7 @@ var Spinner = (props) => {
151
229
  width: "24",
152
230
  height: "24",
153
231
  children: [
154
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
232
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
155
233
  "path",
156
234
  {
157
235
  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",
@@ -161,7 +239,7 @@ var Spinner = (props) => {
161
239
  strokeLinejoin: "round"
162
240
  }
163
241
  ),
164
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
242
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
165
243
  "path",
166
244
  {
167
245
  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",
@@ -189,8 +267,9 @@ var formatUSD = (amount, currency = "USD") => {
189
267
  };
190
268
  var formatPoints = (amount, pointsTitle = "Pts") => {
191
269
  const formattedAmount = new Intl.NumberFormat("en-US", {
270
+ notation: "compact",
192
271
  style: "decimal",
193
- maximumFractionDigits: 5,
272
+ maximumFractionDigits: 1,
194
273
  minimumFractionDigits: 0
195
274
  }).format(amount);
196
275
  return `${formattedAmount} ${pointsTitle}`;
@@ -204,45 +283,85 @@ var formatCoin = (amount, currency = "USDC") => {
204
283
  return `${formattedAmount} ${currency}`;
205
284
  };
206
285
 
286
+ // src/utils/split.ts
287
+ var getSplitAmount = (amount, splitTokens, pointsConversionRatio) => {
288
+ if (!Number.isFinite(amount) || !Number.isFinite(splitTokens) || !Number.isFinite(pointsConversionRatio)) {
289
+ return amount;
290
+ }
291
+ if (pointsConversionRatio <= 0) return amount;
292
+ const usdCoveredByPoints = splitTokens / pointsConversionRatio;
293
+ const remaining = amount - usdCoveredByPoints;
294
+ return Math.max(0, parseFloat(remaining.toFixed(2)));
295
+ };
296
+
297
+ // src/utils/transactionFee.ts
298
+ var getTransactionFee = (amount = 0, transactionFeePercentage) => {
299
+ if (!Number.isFinite(amount) || amount <= 0) return 0;
300
+ if (!Number.isFinite(transactionFeePercentage) || !transactionFeePercentage || transactionFeePercentage <= 0) {
301
+ return 0;
302
+ }
303
+ const fee = amount * transactionFeePercentage;
304
+ return Math.round((fee + Number.EPSILON) * 100) / 100;
305
+ };
306
+
207
307
  // src/components/CheckoutButton.tsx
208
- var import_jsx_runtime3 = require("react/jsx-runtime");
209
- var CheckoutButton = ({ isLoggedIn, isProcessing, amount, onCheckout }) => {
308
+ var import_jsx_runtime4 = require("react/jsx-runtime");
309
+ var CheckoutButton = ({ isLoggedIn }) => {
310
+ const { staticConfig, appProps } = useStaticConfig();
311
+ const { amount, onProcess, isProcessing, transactionFeePercentage } = appProps;
312
+ const { spreePayConfig } = useSpreePayConfig();
313
+ const { pointsTitle, pointsConversionRatio } = staticConfig;
210
314
  const { selectedPaymentMethod, isInternalProcessing } = useSpreePaymentMethod();
211
- const isDisabled = !amount || !selectedPaymentMethod.method || !!isProcessing || isInternalProcessing || !isLoggedIn;
212
- const isUSD = selectedPaymentMethod.type === "CREDIT_CARD" /* CREDIT_CARD */;
213
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex w-full flex-col overflow-hidden rounded-3xl border border-black/25 bg-white text-xs font-medium", children: [
214
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "px-5 py-5 md:px-7 md:py-6", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "text-black/50", children: [
315
+ const { splitAmount, type, method } = selectedPaymentMethod;
316
+ const isDisabled = !amount || !method || !!isProcessing || isInternalProcessing || !isLoggedIn;
317
+ const isCC = type === "CREDIT_CARD" /* CREDIT_CARD */;
318
+ const isCrypto = type === "CRYPTO" /* CRYPTO */;
319
+ const getCheckoutContent = () => {
320
+ if (!!isProcessing || isInternalProcessing) {
321
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Spinner, { className: "inline", size: "sm" });
322
+ }
323
+ if (isCC && amount) {
324
+ const usdAmount = getSplitAmount(amount, splitAmount ?? 0, pointsConversionRatio);
325
+ if (splitAmount && usdAmount) {
326
+ return `Pay ${formatUSD(usdAmount + getTransactionFee(usdAmount, transactionFeePercentage))} + ${formatPoints(splitAmount, pointsTitle)}`;
327
+ }
328
+ if (usdAmount) {
329
+ return `Pay ${formatUSD(usdAmount + getTransactionFee(usdAmount, transactionFeePercentage))}`;
330
+ }
331
+ if (splitAmount) {
332
+ return `Pay ${formatPoints(splitAmount, pointsTitle)}`;
333
+ }
334
+ return "Checkout";
335
+ }
336
+ if (isCrypto && amount) {
337
+ return `Pay ${formatCoin(amount)}`;
338
+ }
339
+ return "Checkout";
340
+ };
341
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex w-full flex-col overflow-hidden rounded-3xl border border-black/25 bg-white text-xs font-medium", children: [
342
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "px-5 py-5 md:px-7 md:py-6", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "text-black/50", children: [
215
343
  "By clicking on the button below I acknowledge that I have read and accepted the",
216
344
  " ",
217
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
218
- "a",
219
- {
220
- className: "underline",
221
- href: "https://uat.travel.air.shop/terms?locale=en-US&currency=USD",
222
- target: "_blank",
223
- rel: "noreferrer",
224
- children: "Terms and Conditions"
225
- }
226
- ),
345
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("a", { className: "underline", href: spreePayConfig?.termsConditionsUrl, target: "_blank", rel: "noreferrer", children: "Terms and Conditions" }),
227
346
  "."
228
347
  ] }) }),
229
- onCheckout && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
348
+ onProcess && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
230
349
  "button",
231
350
  {
232
351
  disabled: isDisabled,
233
- onClick: onCheckout,
352
+ onClick: onProcess,
234
353
  className: "bg-primary h-[60px] w-full cursor-pointer text-xl font-semibold text-white disabled:cursor-not-allowed disabled:opacity-50",
235
- children: !!isProcessing || isInternalProcessing ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Spinner, { className: "inline", size: "sm" }) : amount ? `Pay ${isUSD ? formatUSD(amount) : formatCoin(amount)}` : "Checkout"
354
+ children: getCheckoutContent()
236
355
  }
237
356
  )
238
357
  ] });
239
358
  };
240
359
 
241
360
  // src/components/SpreeLegal.tsx
242
- var import_jsx_runtime4 = require("react/jsx-runtime");
361
+ var import_jsx_runtime5 = require("react/jsx-runtime");
243
362
  var SpreeLegal = () => {
244
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mt-4 flex items-center gap-4", children: [
245
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "flex-shrink-0", xmlns: "http://www.w3.org/2000/svg", width: "66", height: "30", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
363
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mt-4 flex items-center gap-4", children: [
364
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "flex-shrink-0", xmlns: "http://www.w3.org/2000/svg", width: "66", height: "30", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
246
365
  "path",
247
366
  {
248
367
  fill: "#000",
@@ -250,10 +369,10 @@ var SpreeLegal = () => {
250
369
  d: "M57.79 25.48a4.82 4.82 0 0 1-1.55-.25l.55-1.86c.34.1.65.15.92.15s.51-.1.72-.26c.21-.16.39-.43.53-.81l.2-.55-3.65-10.3h2.52l2.32 7.62h.1l2.34-7.62h2.53l-4.04 11.31c-.19.54-.44 1-.75 1.38-.31.38-.7.68-1.14.88-.45.2-.98.3-1.6.3ZM48.95 21.9a4.2 4.2 0 0 1-1.73-.35c-.5-.23-.9-.57-1.2-1.02a3 3 0 0 1-.44-1.67 2.44 2.44 0 0 1 1.18-2.3c.35-.23.76-.4 1.22-.5.46-.13.93-.21 1.42-.27l1.44-.16c.37-.05.64-.13.8-.24.18-.1.26-.27.26-.5v-.04c0-.5-.15-.88-.44-1.15-.3-.27-.72-.4-1.27-.4-.58 0-1.04.12-1.38.37-.34.26-.57.56-.69.9l-2.22-.31a3.54 3.54 0 0 1 2.35-2.47 6.29 6.29 0 0 1 3.38-.14c.48.1.92.3 1.32.56.4.26.72.6.96 1.06.25.44.37 1 .37 1.67v6.75h-2.29v-1.38h-.08a2.9 2.9 0 0 1-1.59 1.37c-.39.14-.84.22-1.37.22Zm.62-1.75c.48 0 .89-.1 1.24-.28.35-.2.62-.45.8-.77.2-.31.3-.65.3-1.03V16.9c-.08.06-.2.11-.38.17a18.34 18.34 0 0 1-1.8.32c-.36.05-.68.12-.96.23-.28.11-.5.27-.66.46-.16.2-.24.45-.24.75 0 .44.16.77.48 1 .32.22.72.33 1.22.33ZM34.43 21.7V8.23h5.05c1.03 0 1.9.2 2.6.58.7.38 1.23.91 1.6 1.59.36.67.54 1.43.54 2.28 0 .87-.18 1.63-.55 2.3a3.9 3.9 0 0 1-1.6 1.59c-.72.38-1.59.57-2.63.57H36.1v-2h3.01c.6 0 1.1-.11 1.49-.32.38-.21.67-.5.85-.87.2-.37.29-.79.29-1.27 0-.47-.1-.9-.29-1.26a1.92 1.92 0 0 0-.86-.84c-.38-.2-.88-.31-1.49-.31h-2.23v11.41h-2.44ZM14.54.46a14.54 14.54 0 1 1 0 29.08 14.54 14.54 0 0 1 0-29.08ZM5.59 18.12l-.84 3.35h.83l.84-3.35h-.83Zm1.66 0-.83 3.35h1.66l.84-3.35H7.25Zm3.35-9.58c-1.03 0-2.08.84-2.34 1.87l-1.1 4.4c-.26 1.03.37 1.87 1.4 1.87h9.64l-.34 1.44h-8.1l-.85 3.35h9.6c1.04 0 2.1-.85 2.35-1.89l1.05-4.4c.25-1.03-.38-1.85-1.4-1.85h-9.63l.36-1.44h8.13l.84-3.35H10.6Zm10.44 0-.84 3.35h1.67l.83-3.35h-1.66Zm2.5 0-.84 3.35h.83l.84-3.35h-.83Z"
251
370
  }
252
371
  ) }),
253
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "text-xs text-black/50", children: [
372
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "text-xs text-black/50", children: [
254
373
  "Spree enables seamless crypto payments for real-world goods, travel, and experiences. Enjoy secure, fast transactions and earn rewards.",
255
374
  " ",
256
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("a", { className: "underline", href: "https://www.spree.finance/", target: "_blank", rel: "noreferrer", children: "Learn more" }),
375
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("a", { className: "underline", href: "https://www.spree.finance/", target: "_blank", rel: "noreferrer", children: "Learn more" }),
257
376
  " ",
258
377
  "about Spree."
259
378
  ] })
@@ -261,31 +380,13 @@ var SpreeLegal = () => {
261
380
  };
262
381
 
263
382
  // src/components/CreditCardTab/CreditCardTab.tsx
264
- var import_react7 = require("react");
265
-
266
- // src/hooks/useCards.ts
267
- var import_swr = __toESM(require("swr"), 1);
268
- var useCards = () => {
269
- const { data, isLoading, mutate } = (0, import_swr.default)(`/v1/payments/cards`);
270
- return {
271
- cards: data?.data.filter((c) => c.active) || [],
272
- cardsIsLoading: isLoading,
273
- mutateCards: mutate
274
- };
275
- };
276
-
277
- // src/hooks/useSlapiBalance.ts
278
- var import_swr2 = __toESM(require("swr"), 1);
279
- var useSlapiBalance = () => {
280
- const { data, isLoading, mutate } = (0, import_swr2.default)(`/v1/loyalty/accounts`);
281
- return { balance: data?.detail, isBalanceLoading: isLoading, mutateBalance: mutate };
282
- };
383
+ var import_react13 = require("react");
283
384
 
284
- // src/services/cardPayment.ts
385
+ // src/hooks/useCardPayment.ts
285
386
  var import_nice_modal_react2 = __toESM(require("@ebay/nice-modal-react"), 1);
286
387
 
287
388
  // src/modals/Iframe3ds.tsx
288
- var import_react3 = require("react");
389
+ var import_react4 = require("react");
289
390
  var import_nice_modal_react = __toESM(require("@ebay/nice-modal-react"), 1);
290
391
 
291
392
  // src/services/eventBus.ts
@@ -307,30 +408,30 @@ var DialogPrimitive = __toESM(require("@radix-ui/react-dialog"), 1);
307
408
  var import_lucide_react = require("lucide-react");
308
409
 
309
410
  // src/ui/portal.ts
310
- var import_react2 = __toESM(require("react"), 1);
311
- var PortalContainerContext = import_react2.default.createContext({ container: null });
411
+ var import_react3 = __toESM(require("react"), 1);
412
+ var PortalContainerContext = import_react3.default.createContext({ container: null });
312
413
  function PortalContainerProvider({
313
414
  container,
314
415
  children
315
416
  }) {
316
- return import_react2.default.createElement(PortalContainerContext.Provider, { value: { container } }, children);
417
+ return import_react3.default.createElement(PortalContainerContext.Provider, { value: { container } }, children);
317
418
  }
318
419
  function usePortalContainer() {
319
- return import_react2.default.useContext(PortalContainerContext).container;
420
+ return import_react3.default.useContext(PortalContainerContext).container;
320
421
  }
321
422
 
322
423
  // src/ui/dialog.tsx
323
- var import_jsx_runtime5 = require("react/jsx-runtime");
424
+ var import_jsx_runtime6 = require("react/jsx-runtime");
324
425
  function Dialog({ ...props }) {
325
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
426
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
326
427
  }
327
428
  function DialogPortal({ ...props }) {
328
429
  const container = usePortalContainer();
329
430
  const safeContainer = container && document.body.contains(container) ? container : void 0;
330
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DialogPrimitive.Portal, { container: safeContainer, "data-slot": "dialog-portal", ...props });
431
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DialogPrimitive.Portal, { container: safeContainer, "data-slot": "dialog-portal", ...props });
331
432
  }
332
433
  function DialogOverlay({ className, ...props }) {
333
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
434
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
334
435
  DialogPrimitive.Overlay,
335
436
  {
336
437
  "data-slot": "dialog-overlay",
@@ -348,9 +449,9 @@ function DialogContent({
348
449
  showCloseButton = true,
349
450
  ...props
350
451
  }) {
351
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(DialogPortal, { "data-slot": "dialog-portal", children: [
352
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DialogOverlay, {}),
353
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
452
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(DialogPortal, { "data-slot": "dialog-portal", children: [
453
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DialogOverlay, {}),
454
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
354
455
  DialogPrimitive.Content,
355
456
  {
356
457
  "data-slot": "dialog-content",
@@ -361,14 +462,14 @@ function DialogContent({
361
462
  ...props,
362
463
  children: [
363
464
  children,
364
- showCloseButton && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
465
+ showCloseButton && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
365
466
  DialogPrimitive.Close,
366
467
  {
367
468
  "data-slot": "dialog-close",
368
469
  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",
369
470
  children: [
370
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react.XIcon, {}),
371
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "sr-only", children: "Close" })
471
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react.XIcon, {}),
472
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "sr-only", children: "Close" })
372
473
  ]
373
474
  }
374
475
  )
@@ -378,7 +479,7 @@ function DialogContent({
378
479
  ] });
379
480
  }
380
481
  function DialogTitle({ className, ...props }) {
381
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
482
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
382
483
  DialogPrimitive.Title,
383
484
  {
384
485
  "data-slot": "dialog-title",
@@ -388,7 +489,7 @@ function DialogTitle({ className, ...props }) {
388
489
  );
389
490
  }
390
491
  function DialogDescription({ className, ...props }) {
391
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
492
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
392
493
  DialogPrimitive.Description,
393
494
  {
394
495
  "data-slot": "dialog-description",
@@ -399,10 +500,10 @@ function DialogDescription({ className, ...props }) {
399
500
  }
400
501
 
401
502
  // src/modals/Iframe3ds.tsx
402
- var import_jsx_runtime6 = require("react/jsx-runtime");
503
+ var import_jsx_runtime7 = require("react/jsx-runtime");
403
504
  var Iframe3ds = import_nice_modal_react.default.create(({ url }) => {
404
505
  const modal = (0, import_nice_modal_react.useModal)();
405
- (0, import_react3.useEffect)(() => {
506
+ (0, import_react4.useEffect)(() => {
406
507
  return bus.on("paymentIntent", (data) => {
407
508
  modal.resolve(data.paymentIntent);
408
509
  modal.remove();
@@ -412,9 +513,9 @@ var Iframe3ds = import_nice_modal_react.default.create(({ url }) => {
412
513
  modal.reject();
413
514
  modal.remove();
414
515
  };
415
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Dialog, { open: modal.visible, onOpenChange: handleClose, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(DialogContent, { className: "max-h-[600px] w-full max-w-[680px] p-0", children: [
416
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DialogTitle, { className: "hidden", children: "3D Secure Verification" }),
417
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("iframe", { src: url, id: "3ds-iframe", title: "3D Secure Checkout", className: "h-[500px] w-full rounded-lg border-0" })
516
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Dialog, { open: modal.visible, onOpenChange: handleClose, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(DialogContent, { className: "max-h-[600px] w-full max-w-[680px] p-0", children: [
517
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(DialogTitle, { className: "hidden", children: "3D Secure Verification" }),
518
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("iframe", { src: url, id: "3ds-iframe", title: "3D Secure Checkout", className: "h-[500px] w-full rounded-lg border-0" })
418
519
  ] }) });
419
520
  });
420
521
  Iframe3ds.displayName = "Iframe3ds";
@@ -516,32 +617,13 @@ var registerApi = (config2) => {
516
617
 
517
618
  // src/services/slapi.ts
518
619
  var SlapiPaymentService = {
519
- // checkBallance: async ({ coin, amount, slippage }: CheckBallanceParams) => {
520
- // // if no ballance known, return true and check by wallet
521
- // if (!coin.balance) return true;
522
- // const isUSDC = coin.symbol === COIN.USDC;
523
- // if (isUSDC) return coin.balance > amount;
524
- // const inputDecimals = cryptoAssets[COIN.USDC].decimals; // Decimals for USDC
525
- // const outputDecimals = coin.decimals; // Decimals for the input asset (e.g., SOL, BONK)
526
- // const params = {
527
- // inputMint: env.NEXT_PUBLIC_USDC_MAINNET_MINT_ADDRESS, // should be main net
528
- // outputMint: coin.address,
529
- // amount: Math.floor(amount * Math.pow(10, inputDecimals)), // Convert amount to smallest units
530
- // slippage,
531
- // };
532
- // // eslint-disable-next-line @typescript-eslint/no-explicit-any
533
- // const { data } = await jupiterApi.get<any>(`/quote?${qs.stringify(params)}`);
534
- // // Convert back to human-readable form
535
- // const outAmountNumber = data?.outAmount ? Number(data.outAmount) / Math.pow(10, outputDecimals) : null;
536
- // // if no ballance known, return true and check by wallet
537
- // if (!outAmountNumber) return true;
538
- // return coin.balance > outAmountNumber;
539
- // },
540
620
  createPayment: (params) => {
541
621
  const { type, hash, metadata, capture = false } = params;
542
622
  let reqParams;
543
623
  if (type === "CRYPTO" /* CRYPTO */) {
544
624
  reqParams = { type, hash, crypto: params.crypto };
625
+ } else if (type === "CREDIT_CARD" /* CREDIT_CARD */ && params.points && params.points.amount > 0) {
626
+ reqParams = { type: "SPLIT" /* SPLIT */, hash, card: params.card, points: params.points };
545
627
  } else {
546
628
  reqParams = { type, hash, card: params.card };
547
629
  }
@@ -550,132 +632,271 @@ var SlapiPaymentService = {
550
632
  baseVerify: ({ id, txHash }) => {
551
633
  return slapiApi.post(`/v1/base-transactions/transactions/${id}/verify`, { txHash });
552
634
  },
553
- // signEncodedTransaction: async (signTransaction: SignTransaction, encodedTX: string): Promise<string> => {
554
- // const swapTransactionBuf = Buffer.from(encodedTX, 'base64');
555
- // const transaction = VersionedTransaction.deserialize(swapTransactionBuf);
556
- // // Sign and send the transaction
557
- // const signedTransaction = await signTransaction(transaction);
558
- // return Buffer.from(signedTransaction.serialize()).toString('base64');
559
- // },
560
- // executeSolana: (params: { txId: string; signedTx: string }) => {
561
- // const { txId, signedTx } = params;
562
- // return slapiApi.post<string>(`/solana-transactions/transactions/${txId}/execute`, { signedTx });
563
- // },
564
- addCard: (params) => {
565
- const { source, hash } = params;
635
+ addCard: ({ source, hash }) => {
566
636
  return slapiApi.post("/v1/payments/cards", { hash, source }).then((data) => ({ data }));
567
637
  },
568
- validate3DS: (params) => {
569
- const { paymentId } = params;
570
- return slapiApi.post("/v1/payments/validate", { paymentId, type: "CREDIT_CARD" }).then((data) => ({ data }));
638
+ validate3DS: ({ paymentId }) => {
639
+ return slapiApi.post("/v1/payments/validate", { paymentId, type: "CREDIT_CARD" /* CREDIT_CARD */ }).then((data) => ({ data }));
640
+ },
641
+ validatePoints: ({ paymentId, txHash }) => {
642
+ return slapiApi.post("/v1/payments/validate", { txHash, paymentId, type: "SPLIT" /* SPLIT */ }).then((data) => ({ data }));
643
+ },
644
+ getStatus: (paymentId) => {
645
+ return slapiApi.get(`/v1/payments/${paymentId}/status`);
571
646
  }
572
647
  };
573
648
 
574
- // src/services/cardPayment.ts
575
- var cardPayment = async (params) => {
576
- const { card, redirect3dsURI, hash, capture, metadata, transactionFee } = params;
577
- let cardId = card.id;
578
- if ("token" in card) {
579
- const { data: cardResData } = await SlapiPaymentService.addCard({ hash, source: card.token });
580
- cardId = cardResData.id;
581
- }
582
- const { data: paymentResData } = await SlapiPaymentService.createPayment({
583
- hash,
584
- capture,
585
- metadata,
586
- type: "CREDIT_CARD" /* CREDIT_CARD */,
587
- card: {
588
- cardId,
589
- transactionFee,
590
- returnUrl: `${window.location.origin}${redirect3dsURI}`
649
+ // src/hooks/useCardPayment.ts
650
+ var useCardPayment = () => {
651
+ const { selectedPaymentMethod } = useSpreePaymentMethod();
652
+ const { env } = useSpreePayEnv();
653
+ const { appProps } = useStaticConfig();
654
+ const cardPayment = async (params) => {
655
+ if (selectedPaymentMethod.type !== "CREDIT_CARD" /* CREDIT_CARD */ || !selectedPaymentMethod.method) {
656
+ throw new Error("Unsupported payment method");
591
657
  }
592
- });
593
- if (paymentResData.redirectUrl) {
594
- const paymentIntent = await import_nice_modal_react2.default.show(Iframe3ds, { url: paymentResData.redirectUrl });
595
- if (paymentIntent) {
596
- const { data: validateData } = await SlapiPaymentService.validate3DS({ paymentId: paymentResData.id });
597
- return {
598
- paymentType: "CREDIT_CARD" /* CREDIT_CARD */,
599
- status: validateData.status,
600
- paymentId: paymentResData.id,
601
- txId: paymentResData.txId,
602
- txHash: null
603
- };
658
+ const { hash, capture, metadata } = params;
659
+ const card = selectedPaymentMethod.method;
660
+ let cardId;
661
+ if ("token" in card) {
662
+ const { data: cardResData } = await SlapiPaymentService.addCard({ hash, source: card.token });
663
+ cardId = cardResData.id;
664
+ } else {
665
+ cardId = card.id;
604
666
  }
605
- }
667
+ const transactionFee = getTransactionFee(appProps.amount, appProps.transactionFeePercentage);
668
+ const { data: paymentResData } = await SlapiPaymentService.createPayment({
669
+ hash,
670
+ capture,
671
+ metadata,
672
+ type: "CREDIT_CARD" /* CREDIT_CARD */,
673
+ card: {
674
+ cardId,
675
+ transactionFee,
676
+ returnUrl: `${typeof window !== "undefined" ? window.location.origin : ""}${env.redirect3dsURI}`
677
+ }
678
+ });
679
+ let { status } = paymentResData;
680
+ if (paymentResData.redirectUrl) {
681
+ const paymentIntent = await import_nice_modal_react2.default.show(Iframe3ds, { url: paymentResData.redirectUrl });
682
+ if (paymentIntent) {
683
+ const { data: validateData } = await SlapiPaymentService.validate3DS({ paymentId: paymentResData.id });
684
+ ({ status } = validateData);
685
+ }
686
+ }
687
+ return {
688
+ status,
689
+ paymentType: "CREDIT_CARD" /* CREDIT_CARD */,
690
+ paymentId: paymentResData.id,
691
+ txId: paymentResData.txId,
692
+ txHash: null
693
+ };
694
+ };
695
+ return { cardPayment };
696
+ };
697
+
698
+ // src/hooks/useCards.ts
699
+ var import_swr2 = __toESM(require("swr"), 1);
700
+ var useCards = () => {
701
+ const { data, isLoading, mutate } = (0, import_swr2.default)(`/v1/payments/cards`);
606
702
  return {
607
- paymentType: "CREDIT_CARD" /* CREDIT_CARD */,
608
- status: paymentResData.status,
609
- paymentId: paymentResData.id,
610
- txId: paymentResData.txId,
611
- txHash: null
703
+ cards: data?.data.filter((c) => c.active) || [],
704
+ cardsIsLoading: isLoading,
705
+ mutateCards: mutate
612
706
  };
613
707
  };
614
708
 
615
- // src/components/common/PointsSwitch.tsx
616
- var import_react4 = require("react");
709
+ // src/hooks/useSplitCardPayments.ts
710
+ var import_nice_modal_react3 = __toESM(require("@ebay/nice-modal-react"), 1);
617
711
 
618
- // src/ui/label.tsx
619
- var LabelPrimitive = __toESM(require("@radix-ui/react-label"), 1);
620
- var import_jsx_runtime7 = require("react/jsx-runtime");
621
- function Label({ className, ...props }) {
622
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
623
- LabelPrimitive.Root,
624
- {
625
- "data-slot": "label",
626
- className: cn(
627
- "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",
628
- className
629
- ),
630
- ...props
712
+ // src/services/AirWalletService.ts
713
+ var import_airkit = require("@mocanetwork/airkit");
714
+ var import_viem = require("viem");
715
+ var singletonState = null;
716
+ var initPromise = null;
717
+ var cachedKey = null;
718
+ function optionsKey(opts) {
719
+ return `${opts.partnerId}|${opts.mocaChain?.id ?? "unknown"}`;
720
+ }
721
+ async function createAndInit(opts) {
722
+ const air = new import_airkit.AirService({ partnerId: opts.partnerId });
723
+ try {
724
+ await air.init({
725
+ buildEnv: opts.buildEnv ?? import_airkit.BUILD_ENV.SANDBOX,
726
+ enableLogging: opts.enableLogging ?? true,
727
+ skipRehydration: opts.skipRehydration ?? false
728
+ });
729
+ air.preloadWallet().catch(() => {
730
+ });
731
+ const loginRes = await air.login();
732
+ const address = loginRes?.abstractAccountAddress || null;
733
+ const walletClient = address ? (0, import_viem.createWalletClient)({
734
+ transport: (0, import_viem.custom)(air.provider),
735
+ chain: opts.mocaChain,
736
+ account: address
737
+ }) : null;
738
+ return { walletReady: true, address, walletClient, air, chain: opts.mocaChain };
739
+ } catch (e) {
740
+ const msg = e instanceof Error ? e.message : "Unknown error during AirWallet initialization";
741
+ return { walletReady: false, address: null, walletClient: null, air: null, chain: null, error: msg };
742
+ }
743
+ }
744
+ async function getAirWallet(options) {
745
+ const key = optionsKey(options);
746
+ if (singletonState && cachedKey === key) return singletonState;
747
+ if (initPromise && cachedKey === key) return initPromise;
748
+ cachedKey = key;
749
+ initPromise = createAndInit(options).then((state) => {
750
+ singletonState = state;
751
+ return state;
752
+ });
753
+ return initPromise;
754
+ }
755
+ function peekAirWallet() {
756
+ return singletonState;
757
+ }
758
+ async function handleSendErc20(params) {
759
+ const state = singletonState;
760
+ if (!state?.walletClient) {
761
+ console.error("Air wallet is not initialized");
762
+ throw new Error("Air wallet is not initialized");
763
+ }
764
+ if (!params?.recipient) {
765
+ console.error("Recipient address is not set");
766
+ throw new Error("Recipient address is not set");
767
+ }
768
+ if (!params?.token?.address || !params?.token?.decimals) {
769
+ console.error("Token address or decimals not set");
770
+ throw new Error("Token address or decimals not set");
771
+ }
772
+ try {
773
+ const { walletClient } = state;
774
+ const addresses = await walletClient.getAddresses();
775
+ const value = (0, import_viem.parseUnits)(String(params.amount), params.token.decimals);
776
+ const data = (0, import_viem.encodeFunctionData)({
777
+ abi: import_viem.erc20Abi,
778
+ functionName: "transfer",
779
+ args: [params.recipient, value]
780
+ });
781
+ const hash = await walletClient.sendTransaction({
782
+ account: addresses[0],
783
+ to: params.token.address,
784
+ data,
785
+ value: 0n,
786
+ chain: state.chain ?? void 0
787
+ });
788
+ return { txHash: hash };
789
+ } catch (error) {
790
+ if (typeof error === "object" && error !== null && "shortMessage" in error) {
791
+ console.error(error.shortMessage);
792
+ } else {
793
+ console.error("Your wallet balances are insufficient to complete this transaction.");
631
794
  }
632
- );
795
+ }
633
796
  }
634
797
 
635
- // src/ui/switch.tsx
636
- var SwitchPrimitive = __toESM(require("@radix-ui/react-switch"), 1);
637
- var import_jsx_runtime8 = require("react/jsx-runtime");
638
- function Switch({ className, ...props }) {
639
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
640
- SwitchPrimitive.Root,
641
- {
642
- "data-slot": "switch",
643
- className: cn(
644
- "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",
645
- className
646
- ),
647
- ...props,
648
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
649
- SwitchPrimitive.Thumb,
650
- {
651
- "data-slot": "switch-thumb",
652
- 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"
653
- }
654
- )
798
+ // src/hooks/useSplitCardPayments.ts
799
+ var REFRESH_INTERVAL = 3 * 1e3;
800
+ var MAX_RETRIES = 10;
801
+ async function longPollPoints(paymentId) {
802
+ let retries = 0;
803
+ while (retries < MAX_RETRIES) {
804
+ const { detail } = await SlapiPaymentService.getStatus(paymentId);
805
+ if (detail.status === "FAILED" /* FAILED */) {
806
+ throw new Error("Something went wrong with the payment");
655
807
  }
656
- );
808
+ if (["AUTHORIZED" /* AUTHORIZED */, "CAPTURED" /* CAPTURED */].includes(detail.status)) {
809
+ return detail.status;
810
+ }
811
+ await new Promise((res) => setTimeout(res, REFRESH_INTERVAL));
812
+ retries++;
813
+ }
814
+ throw new Error("Points Payment polling timed out");
657
815
  }
658
-
659
- // src/components/common/PointsSwitch.tsx
660
- var import_jsx_runtime9 = require("react/jsx-runtime");
661
- var PointsSwitch = (props) => {
662
- const { pointsConversionRatio, disabled = false, value, onChange, pointsTitle } = props;
663
- const { balance } = useSlapiBalance();
664
- const id = (0, import_react4.useId)();
665
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center justify-between gap-3", children: [
666
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-3", children: [
667
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Switch, { checked: value, onCheckedChange: onChange, disabled, id }),
668
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Label, { className: "text-md items-baseline leading-[1.3] font-semibold text-black md:text-xl", htmlFor: id, children: [
669
- "Use Points ",
670
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-xs font-medium", children: "Optional" })
671
- ] })
672
- ] }),
673
- balance?.availablePoints ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("p", { className: "flex-1 text-right text-sm font-medium text-black", children: [
674
- formatPoints(balance.availablePoints, pointsTitle),
675
- " ",
676
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-black/50", children: formatUSD(balance.availablePoints / pointsConversionRatio) })
677
- ] }) : null
678
- ] });
816
+ async function longPollCardStatus(paymentId) {
817
+ let retries = 0;
818
+ let shown3ds = false;
819
+ while (retries < MAX_RETRIES) {
820
+ const { detail } = await SlapiPaymentService.getStatus(paymentId);
821
+ if (detail.status === "FAILED" /* FAILED */) {
822
+ throw new Error(`Something went wrong with the ${detail.validationType} payment`);
823
+ }
824
+ if (detail.validationType === "POINTS") {
825
+ return detail.status;
826
+ }
827
+ if (!shown3ds && detail.card?.redirectUrl) {
828
+ const paymentIntent = await import_nice_modal_react3.default.show(Iframe3ds, { url: detail.card?.redirectUrl });
829
+ shown3ds = true;
830
+ if (paymentIntent) {
831
+ await SlapiPaymentService.validate3DS({ paymentId });
832
+ }
833
+ }
834
+ await new Promise((res) => setTimeout(res, REFRESH_INTERVAL));
835
+ retries++;
836
+ }
837
+ throw new Error("Payment polling timed out");
838
+ }
839
+ var useSplitCardPayments = () => {
840
+ const { selectedPaymentMethod } = useSpreePaymentMethod();
841
+ const { env } = useSpreePayEnv();
842
+ const { appProps, staticConfig } = useStaticConfig();
843
+ const { spreePayConfig } = useSpreePayConfig();
844
+ const splitPayment = async (params) => {
845
+ if (selectedPaymentMethod.type !== "CREDIT_CARD" /* CREDIT_CARD */ || !selectedPaymentMethod.method || !params.points) {
846
+ throw new Error("Unsupported payment method");
847
+ }
848
+ const { hash, capture, metadata, points } = params;
849
+ const card = selectedPaymentMethod.method;
850
+ let cardId;
851
+ if ("token" in card) {
852
+ const { data: cardResData } = await SlapiPaymentService.addCard({ hash, source: card.token });
853
+ cardId = cardResData.id;
854
+ } else {
855
+ cardId = card.id;
856
+ }
857
+ const usdAmount = getSplitAmount(appProps.amount ?? 0, points, staticConfig.pointsConversionRatio);
858
+ const transactionFee = getTransactionFee(usdAmount, appProps.transactionFeePercentage);
859
+ const { data: paymentResData } = await SlapiPaymentService.createPayment({
860
+ hash,
861
+ capture,
862
+ metadata,
863
+ type: "CREDIT_CARD" /* CREDIT_CARD */,
864
+ card: {
865
+ cardId,
866
+ transactionFee,
867
+ returnUrl: `${typeof window !== "undefined" ? window.location.origin : ""}${env.redirect3dsURI}`
868
+ },
869
+ points: {
870
+ amount: points
871
+ }
872
+ });
873
+ await longPollCardStatus(paymentResData.id);
874
+ const wallet = peekAirWallet();
875
+ if (!wallet || !spreePayConfig?.pointsChain) {
876
+ throw new Error("AirWallet not found");
877
+ }
878
+ const transaction = await handleSendErc20({
879
+ amount: params.points,
880
+ token: spreePayConfig.pointsChain.pointsCoin,
881
+ recipient: spreePayConfig.pointsChain.recipientAddress
882
+ });
883
+ if (!transaction) {
884
+ throw new Error("Points transaction failed");
885
+ }
886
+ await SlapiPaymentService.validatePoints({
887
+ paymentId: paymentResData.id,
888
+ txHash: transaction.txHash
889
+ });
890
+ const pointsStatus = await longPollPoints(paymentResData.id);
891
+ return {
892
+ paymentType: "SPLIT" /* SPLIT */,
893
+ status: pointsStatus,
894
+ paymentId: paymentResData.id,
895
+ txId: paymentResData.txId,
896
+ txHash: transaction.txHash
897
+ };
898
+ };
899
+ return { splitPayment };
679
900
  };
680
901
 
681
902
  // src/components/CreditCardTab/CreditCard/CreditCard.tsx
@@ -683,15 +904,8 @@ var import_react6 = require("react");
683
904
  var import_react_stripe_js2 = require("@stripe/react-stripe-js");
684
905
  var import_stripe_js = require("@stripe/stripe-js");
685
906
 
686
- // src/hooks/useConfig.ts
687
- var import_swr3 = __toESM(require("swr"), 1);
688
- var useConfig = () => {
689
- const { data, isLoading } = (0, import_swr3.default)("/v1/tenants/configs/spree-pay");
690
- return { config: data, configIsLoading: isLoading };
691
- };
692
-
693
907
  // src/components/CreditCardTab/CreditCard/CardsList.tsx
694
- var import_jsx_runtime10 = require("react/jsx-runtime");
908
+ var import_jsx_runtime8 = require("react/jsx-runtime");
695
909
  var isRemoveDisabled = true;
696
910
  var CardListItem = ({ card, isSelected, onSelect }) => {
697
911
  const handleSelect = () => {
@@ -701,17 +915,17 @@ var CardListItem = ({ card, isSelected, onSelect }) => {
701
915
  e.stopPropagation();
702
916
  if (isSelected || isRemoveDisabled) return;
703
917
  };
704
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { type: "button", onClick: handleSelect, className: "bg-primary/8 flex h-11 w-full overflow-hidden rounded-md", children: [
705
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
918
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("button", { type: "button", onClick: handleSelect, className: "bg-primary/8 flex h-11 w-full overflow-hidden rounded-md", children: [
919
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
706
920
  "div",
707
921
  {
708
922
  className: cn("flex h-full w-11 items-center justify-center bg-black/10", {
709
923
  "bg-primary": isSelected
710
924
  }),
711
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-white", children: isSelected && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "bg-primary h-2.5 w-2.5 rounded-full" }) })
925
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-white", children: isSelected && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "bg-primary h-2.5 w-2.5 rounded-full" }) })
712
926
  }
713
927
  ),
714
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
928
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
715
929
  "div",
716
930
  {
717
931
  className: cn(
@@ -721,13 +935,13 @@ var CardListItem = ({ card, isSelected, onSelect }) => {
721
935
  }
722
936
  ),
723
937
  children: [
724
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-sm font-medium text-black", children: card.schema }) }),
725
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-2", children: [
726
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("p", { className: "text-sm font-medium text-black/50", children: [
938
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-sm font-medium text-black", children: card.schema }) }),
939
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center gap-2", children: [
940
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("p", { className: "text-sm font-medium text-black/50", children: [
727
941
  "Ending in ",
728
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-black", children: card.lastFourNumbers })
942
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-black", children: card.lastFourNumbers })
729
943
  ] }),
730
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
944
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
731
945
  "div",
732
946
  {
733
947
  onClick: handleRemoveCard,
@@ -735,9 +949,9 @@ var CardListItem = ({ card, isSelected, onSelect }) => {
735
949
  "cursor-not-allowed opacity-50": isSelected || isRemoveDisabled
736
950
  // 'cursor-pointer': !isSelected || !isRemoveDisabled,
737
951
  }),
738
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", fill: "none", children: [
739
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("mask", { id: "mask0_188_5407", width: "20", height: "21", x: "0", y: "-1", maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { fill: "#D9D9D9", d: "M0-.5h20v20H0z" }) }),
740
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("g", { mask: "url(#mask0_188_5407)", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
952
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", fill: "none", children: [
953
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("mask", { id: "mask0_188_5407", width: "20", height: "21", x: "0", y: "-1", maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { fill: "#D9D9D9", d: "M0-.5h20v20H0z" }) }),
954
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("g", { mask: "url(#mask0_188_5407)", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
741
955
  "path",
742
956
  {
743
957
  fill: "#000",
@@ -757,13 +971,13 @@ var CardListItem = ({ card, isSelected, onSelect }) => {
757
971
  var CardsList = ({ selectedCard, setCard }) => {
758
972
  const { cards, cardsIsLoading } = useCards();
759
973
  if (cardsIsLoading) {
760
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex w-full flex-col gap-1", children: [
761
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "bg-primary/8 h-11 animate-pulse rounded-md" }),
762
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "bg-primary/8 h-11 animate-pulse rounded-md" })
974
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex w-full flex-col gap-1", children: [
975
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "bg-primary/8 h-11 animate-pulse rounded-md" }),
976
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "bg-primary/8 h-11 animate-pulse rounded-md" })
763
977
  ] });
764
978
  }
765
979
  if (cards.length === 0) return null;
766
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex w-full flex-col gap-1", children: cards.map((card) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CardListItem, { isSelected: selectedCard?.id === card.id, onSelect: setCard, card }, card.id)) });
980
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex w-full flex-col gap-1", children: cards.map((card) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CardListItem, { isSelected: selectedCard?.id === card.id, onSelect: setCard, card }, card.id)) });
767
981
  };
768
982
 
769
983
  // src/components/CreditCardTab/CreditCard/CreditCardForm.tsx
@@ -773,7 +987,7 @@ var import_react_stripe_js = require("@stripe/react-stripe-js");
773
987
  // src/ui/button.tsx
774
988
  var import_react_slot = require("@radix-ui/react-slot");
775
989
  var import_class_variance_authority = require("class-variance-authority");
776
- var import_jsx_runtime11 = require("react/jsx-runtime");
990
+ var import_jsx_runtime9 = require("react/jsx-runtime");
777
991
  var buttonVariants = (0, import_class_variance_authority.cva)(
778
992
  "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",
779
993
  {
@@ -808,15 +1022,15 @@ function Button({
808
1022
  ...props
809
1023
  }) {
810
1024
  const Comp = asChild ? import_react_slot.Slot : "button";
811
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Comp, { "data-slot": "button", className: cn(buttonVariants({ variant, size, className })), ...props });
1025
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Comp, { "data-slot": "button", className: cn(buttonVariants({ variant, size, className })), ...props });
812
1026
  }
813
1027
 
814
1028
  // src/ui/checkbox.tsx
815
1029
  var CheckboxPrimitive = __toESM(require("@radix-ui/react-checkbox"), 1);
816
1030
  var import_lucide_react2 = require("lucide-react");
817
- var import_jsx_runtime12 = require("react/jsx-runtime");
1031
+ var import_jsx_runtime10 = require("react/jsx-runtime");
818
1032
  function Checkbox({ className, ...props }) {
819
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1033
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
820
1034
  CheckboxPrimitive.Root,
821
1035
  {
822
1036
  "data-slot": "checkbox",
@@ -825,20 +1039,37 @@ function Checkbox({ className, ...props }) {
825
1039
  className
826
1040
  ),
827
1041
  ...props,
828
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1042
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
829
1043
  CheckboxPrimitive.Indicator,
830
1044
  {
831
1045
  "data-slot": "checkbox-indicator",
832
1046
  className: "flex items-center justify-center text-current transition-none",
833
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react2.CheckIcon, { className: "size-3.5 text-white" })
1047
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react2.CheckIcon, { className: "size-3.5 text-white" })
834
1048
  }
835
1049
  )
836
1050
  }
837
1051
  );
838
1052
  }
839
1053
 
1054
+ // src/ui/label.tsx
1055
+ var LabelPrimitive = __toESM(require("@radix-ui/react-label"), 1);
1056
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1057
+ function Label({ className, ...props }) {
1058
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1059
+ LabelPrimitive.Root,
1060
+ {
1061
+ "data-slot": "label",
1062
+ className: cn(
1063
+ "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",
1064
+ className
1065
+ ),
1066
+ ...props
1067
+ }
1068
+ );
1069
+ }
1070
+
840
1071
  // src/components/CreditCardTab/CreditCard/CreditCardForm.tsx
841
- var import_jsx_runtime13 = require("react/jsx-runtime");
1072
+ var import_jsx_runtime12 = require("react/jsx-runtime");
842
1073
  var style = {
843
1074
  base: {
844
1075
  fontSize: "16px",
@@ -896,9 +1127,9 @@ var CreditCardForm = ({ cancel, saveCard }) => {
896
1127
  setCardError("An error occurred while processing your card. Please try again.");
897
1128
  }
898
1129
  };
899
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
900
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex w-full flex-col gap-1", children: [
901
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1130
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1131
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex w-full flex-col gap-1", children: [
1132
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
902
1133
  import_react_stripe_js.CardNumberElement,
903
1134
  {
904
1135
  options: {
@@ -908,8 +1139,8 @@ var CreditCardForm = ({ cancel, saveCard }) => {
908
1139
  }
909
1140
  }
910
1141
  ),
911
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex w-full gap-1", children: [
912
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1142
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex w-full gap-1", children: [
1143
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
913
1144
  import_react_stripe_js.CardExpiryElement,
914
1145
  {
915
1146
  options: {
@@ -919,7 +1150,7 @@ var CreditCardForm = ({ cancel, saveCard }) => {
919
1150
  }
920
1151
  }
921
1152
  ),
922
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1153
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
923
1154
  import_react_stripe_js.CardCvcElement,
924
1155
  {
925
1156
  options: {
@@ -930,32 +1161,32 @@ var CreditCardForm = ({ cancel, saveCard }) => {
930
1161
  }
931
1162
  )
932
1163
  ] }),
933
- cardError && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-destructive mt-1 text-sm", children: cardError })
1164
+ cardError && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-destructive mt-1 text-sm", children: cardError })
934
1165
  ] }),
935
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-2", children: [
936
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Checkbox, { disabled: true, checked: true, id: "saveCard" }),
937
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Label, { className: "text-sm font-medium", htmlFor: "saveCard", children: "Save card for future purchases" })
1166
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center gap-2", children: [
1167
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Checkbox, { disabled: true, checked: true, id: "saveCard" }),
1168
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Label, { className: "text-sm font-medium", htmlFor: "saveCard", children: "Save card for future purchases" })
938
1169
  ] }),
939
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex w-full justify-end gap-2", children: [
940
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Button, { variant: "secondary", onClick: cancel, children: "Cancel" }),
941
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Button, { onClick: handleSaveCard, children: "Add Card" })
1170
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex w-full justify-end gap-2", children: [
1171
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button, { variant: "secondary", onClick: cancel, children: "Cancel" }),
1172
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button, { onClick: handleSaveCard, children: "Add Card" })
942
1173
  ] })
943
1174
  ] });
944
1175
  };
945
1176
 
946
1177
  // src/components/CreditCardTab/CreditCard/CreditCard.tsx
947
- var import_jsx_runtime14 = require("react/jsx-runtime");
948
- var SripeWrapper = (props) => {
1178
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1179
+ var StripeWrapper = (props) => {
949
1180
  const stripePromise = (0, import_react6.useMemo)(() => (0, import_stripe_js.loadStripe)(props.publicKey), [props.publicKey]);
950
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_stripe_js2.Elements, { stripe: stripePromise, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CreditCardForm, { cancel: props.onCancel, saveCard: props.saveNewCard }) });
1181
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_stripe_js2.Elements, { stripe: stripePromise, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CreditCardForm, { cancel: props.onCancel, saveCard: props.saveNewCard }) });
951
1182
  };
952
1183
  var CreditCard = () => {
953
1184
  const [showForm, setShowForm] = (0, import_react6.useState)(false);
954
1185
  const { selectedPaymentMethod, setSelectedPaymentMethod } = useSpreePaymentMethod();
955
1186
  const { mutateCards } = useCards();
956
- const { config: config2 } = useConfig();
1187
+ const { spreePayConfig } = useSpreePayConfig();
957
1188
  const setCard = (card) => {
958
- setSelectedPaymentMethod({ type: "CREDIT_CARD" /* CREDIT_CARD */, method: card });
1189
+ setSelectedPaymentMethod({ ...selectedPaymentMethod, type: "CREDIT_CARD" /* CREDIT_CARD */, method: card });
959
1190
  };
960
1191
  const saveNewCard = (newCard) => {
961
1192
  mutateCards((data) => ({ ...data, data: [...data?.data ?? [], newCard] }), { revalidate: false });
@@ -965,70 +1196,1221 @@ var CreditCard = () => {
965
1196
  const handleCancel = () => {
966
1197
  setShowForm(false);
967
1198
  };
968
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col items-baseline gap-4", children: [
969
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { className: "text-primary text-xl leading-[34px] font-semibold", children: "Your Credit Cards" }),
970
- !showForm && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
971
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1199
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col items-baseline gap-4", children: [
1200
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h3", { className: "text-primary text-xl leading-[34px] font-semibold", children: "Your Credit Cards" }),
1201
+ !showForm && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
1202
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
972
1203
  CardsList,
973
1204
  {
974
1205
  selectedCard: selectedPaymentMethod?.type === "CREDIT_CARD" /* CREDIT_CARD */ ? selectedPaymentMethod.method : null,
975
1206
  setCard
976
1207
  }
977
1208
  ),
978
- config2?.stripePublicKey && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { onClick: () => setShowForm(true), className: "text-sm font-medium text-black hover:underline", children: "Add new card" })
1209
+ spreePayConfig?.stripePublicKey && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { onClick: () => setShowForm(true), className: "text-sm font-medium text-black hover:underline", children: "Add new card" })
979
1210
  ] }),
980
- config2?.stripePublicKey && showForm && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SripeWrapper, { onCancel: handleCancel, saveNewCard, publicKey: config2.stripePublicKey })
1211
+ spreePayConfig?.stripePublicKey && showForm && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StripeWrapper, { onCancel: handleCancel, saveNewCard, publicKey: spreePayConfig.stripePublicKey })
981
1212
  ] });
982
1213
  };
983
1214
 
984
- // src/components/CreditCardTab/CreditCardTab.tsx
1215
+ // src/components/CreditCardTab/Points/Points.tsx
1216
+ var import_react12 = require("react");
1217
+
1218
+ // src/components/common/PointsSwitch.tsx
1219
+ var import_react7 = require("react");
1220
+
1221
+ // src/hooks/useSlapiBalance.ts
1222
+ var import_swr3 = __toESM(require("swr"), 1);
1223
+ var useSlapiBalance = () => {
1224
+ const { data, isLoading, mutate } = (0, import_swr3.default)(`/v1/loyalty/accounts`);
1225
+ return { balance: data?.detail, isBalanceLoading: isLoading, mutateBalance: mutate };
1226
+ };
1227
+
1228
+ // src/ui/switch.tsx
1229
+ var SwitchPrimitive = __toESM(require("@radix-ui/react-switch"), 1);
1230
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1231
+ function Switch({ className, ...props }) {
1232
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1233
+ SwitchPrimitive.Root,
1234
+ {
1235
+ "data-slot": "switch",
1236
+ className: cn(
1237
+ "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",
1238
+ className
1239
+ ),
1240
+ ...props,
1241
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1242
+ SwitchPrimitive.Thumb,
1243
+ {
1244
+ "data-slot": "switch-thumb",
1245
+ 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"
1246
+ }
1247
+ )
1248
+ }
1249
+ );
1250
+ }
1251
+
1252
+ // src/components/common/PointsSwitch.tsx
985
1253
  var import_jsx_runtime15 = require("react/jsx-runtime");
986
- var PointsSelector = ({ isSelected, onSelect, children }) => {
987
- return (
988
- // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
989
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
990
- "div",
1254
+ var PointsSwitch = (props) => {
1255
+ const { disabled = false, value, onChange } = props;
1256
+ const { staticConfig } = useStaticConfig();
1257
+ const { pointsConversionRatio, pointsTitle } = staticConfig;
1258
+ const { balance } = useSlapiBalance();
1259
+ const id = (0, import_react7.useId)();
1260
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center justify-between gap-3", children: [
1261
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center gap-3", children: [
1262
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Switch, { checked: value, onCheckedChange: onChange, disabled, id }),
1263
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Label, { className: "text-md items-baseline leading-[1.3] font-semibold text-black md:text-xl", htmlFor: id, children: [
1264
+ "Use Points ",
1265
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-xs font-medium", children: "Optional" })
1266
+ ] })
1267
+ ] }),
1268
+ balance?.availablePoints ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("p", { className: "flex-1 text-right text-sm font-medium text-black", children: [
1269
+ formatPoints(balance.availablePoints, pointsTitle),
1270
+ " ",
1271
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-black/50", children: formatUSD(balance.availablePoints / pointsConversionRatio) })
1272
+ ] }) : null
1273
+ ] });
1274
+ };
1275
+
1276
+ // src/components/CreditCardTab/Points/SplitBlock.tsx
1277
+ var import_react11 = require("react");
1278
+
1279
+ // src/components/CreditCardTab/Points/PointsSelector.tsx
1280
+ var import_react10 = require("react");
1281
+
1282
+ // src/ui/input.tsx
1283
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1284
+ function Input({ className, type, ...props }) {
1285
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1286
+ "input",
1287
+ {
1288
+ type,
1289
+ "data-slot": "input",
1290
+ className: cn(
1291
+ "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",
1292
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
1293
+ "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
1294
+ className
1295
+ ),
1296
+ ...props
1297
+ }
1298
+ );
1299
+ }
1300
+
1301
+ // src/ui/slider.tsx
1302
+ var React12 = __toESM(require("react"), 1);
1303
+
1304
+ // ../../node_modules/@radix-ui/react-slider/dist/index.mjs
1305
+ var React11 = __toESM(require("react"), 1);
1306
+
1307
+ // ../../node_modules/@radix-ui/number/dist/index.mjs
1308
+ function clamp(value, [min, max]) {
1309
+ return Math.min(max, Math.max(min, value));
1310
+ }
1311
+
1312
+ // ../../node_modules/@radix-ui/react-slider/node_modules/@radix-ui/primitive/dist/index.mjs
1313
+ var canUseDOM = !!(typeof window !== "undefined" && window.document && window.document.createElement);
1314
+ function composeEventHandlers(originalEventHandler, ourEventHandler, { checkForDefaultPrevented = true } = {}) {
1315
+ return function handleEvent(event) {
1316
+ originalEventHandler?.(event);
1317
+ if (checkForDefaultPrevented === false || !event.defaultPrevented) {
1318
+ return ourEventHandler?.(event);
1319
+ }
1320
+ };
1321
+ }
1322
+
1323
+ // ../../node_modules/@radix-ui/react-compose-refs/dist/index.mjs
1324
+ var React2 = __toESM(require("react"), 1);
1325
+ function setRef(ref, value) {
1326
+ if (typeof ref === "function") {
1327
+ return ref(value);
1328
+ } else if (ref !== null && ref !== void 0) {
1329
+ ref.current = value;
1330
+ }
1331
+ }
1332
+ function composeRefs(...refs) {
1333
+ return (node) => {
1334
+ let hasCleanup = false;
1335
+ const cleanups = refs.map((ref) => {
1336
+ const cleanup = setRef(ref, node);
1337
+ if (!hasCleanup && typeof cleanup == "function") {
1338
+ hasCleanup = true;
1339
+ }
1340
+ return cleanup;
1341
+ });
1342
+ if (hasCleanup) {
1343
+ return () => {
1344
+ for (let i = 0; i < cleanups.length; i++) {
1345
+ const cleanup = cleanups[i];
1346
+ if (typeof cleanup == "function") {
1347
+ cleanup();
1348
+ } else {
1349
+ setRef(refs[i], null);
1350
+ }
1351
+ }
1352
+ };
1353
+ }
1354
+ };
1355
+ }
1356
+ function useComposedRefs(...refs) {
1357
+ return React2.useCallback(composeRefs(...refs), refs);
1358
+ }
1359
+
1360
+ // ../../node_modules/@radix-ui/react-context/dist/index.mjs
1361
+ var React3 = __toESM(require("react"), 1);
1362
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1363
+ function createContextScope(scopeName, createContextScopeDeps = []) {
1364
+ let defaultContexts = [];
1365
+ function createContext32(rootComponentName, defaultContext) {
1366
+ const BaseContext = React3.createContext(defaultContext);
1367
+ const index = defaultContexts.length;
1368
+ defaultContexts = [...defaultContexts, defaultContext];
1369
+ const Provider = (props) => {
1370
+ const { scope, children, ...context } = props;
1371
+ const Context = scope?.[scopeName]?.[index] || BaseContext;
1372
+ const value = React3.useMemo(() => context, Object.values(context));
1373
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Context.Provider, { value, children });
1374
+ };
1375
+ Provider.displayName = rootComponentName + "Provider";
1376
+ function useContext22(consumerName, scope) {
1377
+ const Context = scope?.[scopeName]?.[index] || BaseContext;
1378
+ const context = React3.useContext(Context);
1379
+ if (context) return context;
1380
+ if (defaultContext !== void 0) return defaultContext;
1381
+ throw new Error(`\`${consumerName}\` must be used within \`${rootComponentName}\``);
1382
+ }
1383
+ return [Provider, useContext22];
1384
+ }
1385
+ const createScope = () => {
1386
+ const scopeContexts = defaultContexts.map((defaultContext) => {
1387
+ return React3.createContext(defaultContext);
1388
+ });
1389
+ return function useScope(scope) {
1390
+ const contexts = scope?.[scopeName] || scopeContexts;
1391
+ return React3.useMemo(
1392
+ () => ({ [`__scope${scopeName}`]: { ...scope, [scopeName]: contexts } }),
1393
+ [scope, contexts]
1394
+ );
1395
+ };
1396
+ };
1397
+ createScope.scopeName = scopeName;
1398
+ return [createContext32, composeContextScopes(createScope, ...createContextScopeDeps)];
1399
+ }
1400
+ function composeContextScopes(...scopes) {
1401
+ const baseScope = scopes[0];
1402
+ if (scopes.length === 1) return baseScope;
1403
+ const createScope = () => {
1404
+ const scopeHooks = scopes.map((createScope2) => ({
1405
+ useScope: createScope2(),
1406
+ scopeName: createScope2.scopeName
1407
+ }));
1408
+ return function useComposedScopes(overrideScopes) {
1409
+ const nextScopes = scopeHooks.reduce((nextScopes2, { useScope, scopeName }) => {
1410
+ const scopeProps = useScope(overrideScopes);
1411
+ const currentScope = scopeProps[`__scope${scopeName}`];
1412
+ return { ...nextScopes2, ...currentScope };
1413
+ }, {});
1414
+ return React3.useMemo(() => ({ [`__scope${baseScope.scopeName}`]: nextScopes }), [nextScopes]);
1415
+ };
1416
+ };
1417
+ createScope.scopeName = baseScope.scopeName;
1418
+ return createScope;
1419
+ }
1420
+
1421
+ // ../../node_modules/@radix-ui/react-use-controllable-state/dist/index.mjs
1422
+ var React5 = __toESM(require("react"), 1);
1423
+
1424
+ // ../../node_modules/@radix-ui/react-use-layout-effect/dist/index.mjs
1425
+ var React4 = __toESM(require("react"), 1);
1426
+ var useLayoutEffect2 = globalThis?.document ? React4.useLayoutEffect : () => {
1427
+ };
1428
+
1429
+ // ../../node_modules/@radix-ui/react-use-controllable-state/dist/index.mjs
1430
+ var React22 = __toESM(require("react"), 1);
1431
+ var useInsertionEffect = React5[" useInsertionEffect ".trim().toString()] || useLayoutEffect2;
1432
+ function useControllableState({
1433
+ prop,
1434
+ defaultProp,
1435
+ onChange = () => {
1436
+ },
1437
+ caller
1438
+ }) {
1439
+ const [uncontrolledProp, setUncontrolledProp, onChangeRef] = useUncontrolledState({
1440
+ defaultProp,
1441
+ onChange
1442
+ });
1443
+ const isControlled = prop !== void 0;
1444
+ const value = isControlled ? prop : uncontrolledProp;
1445
+ if (true) {
1446
+ const isControlledRef = React5.useRef(prop !== void 0);
1447
+ React5.useEffect(() => {
1448
+ const wasControlled = isControlledRef.current;
1449
+ if (wasControlled !== isControlled) {
1450
+ const from = wasControlled ? "controlled" : "uncontrolled";
1451
+ const to = isControlled ? "controlled" : "uncontrolled";
1452
+ console.warn(
1453
+ `${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.`
1454
+ );
1455
+ }
1456
+ isControlledRef.current = isControlled;
1457
+ }, [isControlled, caller]);
1458
+ }
1459
+ const setValue = React5.useCallback(
1460
+ (nextValue) => {
1461
+ if (isControlled) {
1462
+ const value2 = isFunction(nextValue) ? nextValue(prop) : nextValue;
1463
+ if (value2 !== prop) {
1464
+ onChangeRef.current?.(value2);
1465
+ }
1466
+ } else {
1467
+ setUncontrolledProp(nextValue);
1468
+ }
1469
+ },
1470
+ [isControlled, prop, setUncontrolledProp, onChangeRef]
1471
+ );
1472
+ return [value, setValue];
1473
+ }
1474
+ function useUncontrolledState({
1475
+ defaultProp,
1476
+ onChange
1477
+ }) {
1478
+ const [value, setValue] = React5.useState(defaultProp);
1479
+ const prevValueRef = React5.useRef(value);
1480
+ const onChangeRef = React5.useRef(onChange);
1481
+ useInsertionEffect(() => {
1482
+ onChangeRef.current = onChange;
1483
+ }, [onChange]);
1484
+ React5.useEffect(() => {
1485
+ if (prevValueRef.current !== value) {
1486
+ onChangeRef.current?.(value);
1487
+ prevValueRef.current = value;
1488
+ }
1489
+ }, [value, prevValueRef]);
1490
+ return [value, setValue, onChangeRef];
1491
+ }
1492
+ function isFunction(value) {
1493
+ return typeof value === "function";
1494
+ }
1495
+ var SYNC_STATE = Symbol("RADIX:SYNC_STATE");
1496
+
1497
+ // ../../node_modules/@radix-ui/react-direction/dist/index.mjs
1498
+ var React6 = __toESM(require("react"), 1);
1499
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1500
+ var DirectionContext = React6.createContext(void 0);
1501
+ function useDirection(localDir) {
1502
+ const globalDir = React6.useContext(DirectionContext);
1503
+ return localDir || globalDir || "ltr";
1504
+ }
1505
+
1506
+ // ../../node_modules/@radix-ui/react-use-previous/dist/index.mjs
1507
+ var React7 = __toESM(require("react"), 1);
1508
+ function usePrevious(value) {
1509
+ const ref = React7.useRef({ value, previous: value });
1510
+ return React7.useMemo(() => {
1511
+ if (ref.current.value !== value) {
1512
+ ref.current.previous = ref.current.value;
1513
+ ref.current.value = value;
1514
+ }
1515
+ return ref.current.previous;
1516
+ }, [value]);
1517
+ }
1518
+
1519
+ // ../../node_modules/@radix-ui/react-use-size/dist/index.mjs
1520
+ var React8 = __toESM(require("react"), 1);
1521
+ function useSize(element) {
1522
+ const [size, setSize] = React8.useState(void 0);
1523
+ useLayoutEffect2(() => {
1524
+ if (element) {
1525
+ setSize({ width: element.offsetWidth, height: element.offsetHeight });
1526
+ const resizeObserver = new ResizeObserver((entries) => {
1527
+ if (!Array.isArray(entries)) {
1528
+ return;
1529
+ }
1530
+ if (!entries.length) {
1531
+ return;
1532
+ }
1533
+ const entry = entries[0];
1534
+ let width;
1535
+ let height;
1536
+ if ("borderBoxSize" in entry) {
1537
+ const borderSizeEntry = entry["borderBoxSize"];
1538
+ const borderSize = Array.isArray(borderSizeEntry) ? borderSizeEntry[0] : borderSizeEntry;
1539
+ width = borderSize["inlineSize"];
1540
+ height = borderSize["blockSize"];
1541
+ } else {
1542
+ width = element.offsetWidth;
1543
+ height = element.offsetHeight;
1544
+ }
1545
+ setSize({ width, height });
1546
+ });
1547
+ resizeObserver.observe(element, { box: "border-box" });
1548
+ return () => resizeObserver.unobserve(element);
1549
+ } else {
1550
+ setSize(void 0);
1551
+ }
1552
+ }, [element]);
1553
+ return size;
1554
+ }
1555
+
1556
+ // ../../node_modules/@radix-ui/react-primitive/dist/index.mjs
1557
+ var React9 = __toESM(require("react"), 1);
1558
+ var ReactDOM = __toESM(require("react-dom"), 1);
1559
+ var import_react_slot2 = require("@radix-ui/react-slot");
1560
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1561
+ var NODES = [
1562
+ "a",
1563
+ "button",
1564
+ "div",
1565
+ "form",
1566
+ "h2",
1567
+ "h3",
1568
+ "img",
1569
+ "input",
1570
+ "label",
1571
+ "li",
1572
+ "nav",
1573
+ "ol",
1574
+ "p",
1575
+ "select",
1576
+ "span",
1577
+ "svg",
1578
+ "ul"
1579
+ ];
1580
+ var Primitive = NODES.reduce((primitive, node) => {
1581
+ const Slot2 = (0, import_react_slot2.createSlot)(`Primitive.${node}`);
1582
+ const Node2 = React9.forwardRef((props, forwardedRef) => {
1583
+ const { asChild, ...primitiveProps } = props;
1584
+ const Comp = asChild ? Slot2 : node;
1585
+ if (typeof window !== "undefined") {
1586
+ window[Symbol.for("radix-ui")] = true;
1587
+ }
1588
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Comp, { ...primitiveProps, ref: forwardedRef });
1589
+ });
1590
+ Node2.displayName = `Primitive.${node}`;
1591
+ return { ...primitive, [node]: Node2 };
1592
+ }, {});
1593
+
1594
+ // ../../node_modules/@radix-ui/react-collection/dist/index.mjs
1595
+ var import_react8 = __toESM(require("react"), 1);
1596
+ var import_react_slot3 = require("@radix-ui/react-slot");
1597
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1598
+ var import_react9 = __toESM(require("react"), 1);
1599
+ var import_react_slot4 = require("@radix-ui/react-slot");
1600
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1601
+ function createCollection(name) {
1602
+ const PROVIDER_NAME = name + "CollectionProvider";
1603
+ const [createCollectionContext, createCollectionScope2] = createContextScope(PROVIDER_NAME);
1604
+ const [CollectionProviderImpl, useCollectionContext] = createCollectionContext(
1605
+ PROVIDER_NAME,
1606
+ { collectionRef: { current: null }, itemMap: /* @__PURE__ */ new Map() }
1607
+ );
1608
+ const CollectionProvider = (props) => {
1609
+ const { scope, children } = props;
1610
+ const ref = import_react8.default.useRef(null);
1611
+ const itemMap = import_react8.default.useRef(/* @__PURE__ */ new Map()).current;
1612
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CollectionProviderImpl, { scope, itemMap, collectionRef: ref, children });
1613
+ };
1614
+ CollectionProvider.displayName = PROVIDER_NAME;
1615
+ const COLLECTION_SLOT_NAME = name + "CollectionSlot";
1616
+ const CollectionSlotImpl = (0, import_react_slot3.createSlot)(COLLECTION_SLOT_NAME);
1617
+ const CollectionSlot = import_react8.default.forwardRef(
1618
+ (props, forwardedRef) => {
1619
+ const { scope, children } = props;
1620
+ const context = useCollectionContext(COLLECTION_SLOT_NAME, scope);
1621
+ const composedRefs = useComposedRefs(forwardedRef, context.collectionRef);
1622
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CollectionSlotImpl, { ref: composedRefs, children });
1623
+ }
1624
+ );
1625
+ CollectionSlot.displayName = COLLECTION_SLOT_NAME;
1626
+ const ITEM_SLOT_NAME = name + "CollectionItemSlot";
1627
+ const ITEM_DATA_ATTR = "data-radix-collection-item";
1628
+ const CollectionItemSlotImpl = (0, import_react_slot3.createSlot)(ITEM_SLOT_NAME);
1629
+ const CollectionItemSlot = import_react8.default.forwardRef(
1630
+ (props, forwardedRef) => {
1631
+ const { scope, children, ...itemData } = props;
1632
+ const ref = import_react8.default.useRef(null);
1633
+ const composedRefs = useComposedRefs(forwardedRef, ref);
1634
+ const context = useCollectionContext(ITEM_SLOT_NAME, scope);
1635
+ import_react8.default.useEffect(() => {
1636
+ context.itemMap.set(ref, { ref, ...itemData });
1637
+ return () => void context.itemMap.delete(ref);
1638
+ });
1639
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CollectionItemSlotImpl, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
1640
+ }
1641
+ );
1642
+ CollectionItemSlot.displayName = ITEM_SLOT_NAME;
1643
+ function useCollection2(scope) {
1644
+ const context = useCollectionContext(name + "CollectionConsumer", scope);
1645
+ const getItems = import_react8.default.useCallback(() => {
1646
+ const collectionNode = context.collectionRef.current;
1647
+ if (!collectionNode) return [];
1648
+ const orderedNodes = Array.from(collectionNode.querySelectorAll(`[${ITEM_DATA_ATTR}]`));
1649
+ const items = Array.from(context.itemMap.values());
1650
+ const orderedItems = items.sort(
1651
+ (a, b) => orderedNodes.indexOf(a.ref.current) - orderedNodes.indexOf(b.ref.current)
1652
+ );
1653
+ return orderedItems;
1654
+ }, [context.collectionRef, context.itemMap]);
1655
+ return getItems;
1656
+ }
1657
+ return [
1658
+ { Provider: CollectionProvider, Slot: CollectionSlot, ItemSlot: CollectionItemSlot },
1659
+ useCollection2,
1660
+ createCollectionScope2
1661
+ ];
1662
+ }
1663
+
1664
+ // ../../node_modules/@radix-ui/react-slider/dist/index.mjs
1665
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1666
+ var PAGE_KEYS = ["PageUp", "PageDown"];
1667
+ var ARROW_KEYS = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"];
1668
+ var BACK_KEYS = {
1669
+ "from-left": ["Home", "PageDown", "ArrowDown", "ArrowLeft"],
1670
+ "from-right": ["Home", "PageDown", "ArrowDown", "ArrowRight"],
1671
+ "from-bottom": ["Home", "PageDown", "ArrowDown", "ArrowLeft"],
1672
+ "from-top": ["Home", "PageDown", "ArrowUp", "ArrowLeft"]
1673
+ };
1674
+ var SLIDER_NAME = "Slider";
1675
+ var [Collection, useCollection, createCollectionScope] = createCollection(SLIDER_NAME);
1676
+ var [createSliderContext, createSliderScope] = createContextScope(SLIDER_NAME, [
1677
+ createCollectionScope
1678
+ ]);
1679
+ var [SliderProvider, useSliderContext] = createSliderContext(SLIDER_NAME);
1680
+ var Slider = React11.forwardRef(
1681
+ (props, forwardedRef) => {
1682
+ const {
1683
+ name,
1684
+ min = 0,
1685
+ max = 100,
1686
+ step = 1,
1687
+ orientation = "horizontal",
1688
+ disabled = false,
1689
+ minStepsBetweenThumbs = 0,
1690
+ defaultValue = [min],
1691
+ value,
1692
+ onValueChange = () => {
1693
+ },
1694
+ onValueCommit = () => {
1695
+ },
1696
+ inverted = false,
1697
+ form,
1698
+ ...sliderProps
1699
+ } = props;
1700
+ const thumbRefs = React11.useRef(/* @__PURE__ */ new Set());
1701
+ const valueIndexToChangeRef = React11.useRef(0);
1702
+ const isHorizontal = orientation === "horizontal";
1703
+ const SliderOrientation = isHorizontal ? SliderHorizontal : SliderVertical;
1704
+ const [values = [], setValues] = useControllableState({
1705
+ prop: value,
1706
+ defaultProp: defaultValue,
1707
+ onChange: (value2) => {
1708
+ const thumbs = [...thumbRefs.current];
1709
+ thumbs[valueIndexToChangeRef.current]?.focus();
1710
+ onValueChange(value2);
1711
+ }
1712
+ });
1713
+ const valuesBeforeSlideStartRef = React11.useRef(values);
1714
+ function handleSlideStart(value2) {
1715
+ const closestIndex = getClosestValueIndex(values, value2);
1716
+ updateValues(value2, closestIndex);
1717
+ }
1718
+ function handleSlideMove(value2) {
1719
+ updateValues(value2, valueIndexToChangeRef.current);
1720
+ }
1721
+ function handleSlideEnd() {
1722
+ const prevValue = valuesBeforeSlideStartRef.current[valueIndexToChangeRef.current];
1723
+ const nextValue = values[valueIndexToChangeRef.current];
1724
+ const hasChanged = nextValue !== prevValue;
1725
+ if (hasChanged) onValueCommit(values);
1726
+ }
1727
+ function updateValues(value2, atIndex, { commit } = { commit: false }) {
1728
+ const decimalCount = getDecimalCount(step);
1729
+ const snapToStep = roundValue(Math.round((value2 - min) / step) * step + min, decimalCount);
1730
+ const nextValue = clamp(snapToStep, [min, max]);
1731
+ setValues((prevValues = []) => {
1732
+ const nextValues = getNextSortedValues(prevValues, nextValue, atIndex);
1733
+ if (hasMinStepsBetweenValues(nextValues, minStepsBetweenThumbs * step)) {
1734
+ valueIndexToChangeRef.current = nextValues.indexOf(nextValue);
1735
+ const hasChanged = String(nextValues) !== String(prevValues);
1736
+ if (hasChanged && commit) onValueCommit(nextValues);
1737
+ return hasChanged ? nextValues : prevValues;
1738
+ } else {
1739
+ return prevValues;
1740
+ }
1741
+ });
1742
+ }
1743
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1744
+ SliderProvider,
1745
+ {
1746
+ scope: props.__scopeSlider,
1747
+ name,
1748
+ disabled,
1749
+ min,
1750
+ max,
1751
+ valueIndexToChangeRef,
1752
+ thumbs: thumbRefs.current,
1753
+ values,
1754
+ orientation,
1755
+ form,
1756
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Collection.Provider, { scope: props.__scopeSlider, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Collection.Slot, { scope: props.__scopeSlider, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1757
+ SliderOrientation,
1758
+ {
1759
+ "aria-disabled": disabled,
1760
+ "data-disabled": disabled ? "" : void 0,
1761
+ ...sliderProps,
1762
+ ref: forwardedRef,
1763
+ onPointerDown: composeEventHandlers(sliderProps.onPointerDown, () => {
1764
+ if (!disabled) valuesBeforeSlideStartRef.current = values;
1765
+ }),
1766
+ min,
1767
+ max,
1768
+ inverted,
1769
+ onSlideStart: disabled ? void 0 : handleSlideStart,
1770
+ onSlideMove: disabled ? void 0 : handleSlideMove,
1771
+ onSlideEnd: disabled ? void 0 : handleSlideEnd,
1772
+ onHomeKeyDown: () => !disabled && updateValues(min, 0, { commit: true }),
1773
+ onEndKeyDown: () => !disabled && updateValues(max, values.length - 1, { commit: true }),
1774
+ onStepKeyDown: ({ event, direction: stepDirection }) => {
1775
+ if (!disabled) {
1776
+ const isPageKey = PAGE_KEYS.includes(event.key);
1777
+ const isSkipKey = isPageKey || event.shiftKey && ARROW_KEYS.includes(event.key);
1778
+ const multiplier = isSkipKey ? 10 : 1;
1779
+ const atIndex = valueIndexToChangeRef.current;
1780
+ const value2 = values[atIndex];
1781
+ const stepInDirection = step * multiplier * stepDirection;
1782
+ updateValues(value2 + stepInDirection, atIndex, { commit: true });
1783
+ }
1784
+ }
1785
+ }
1786
+ ) }) })
1787
+ }
1788
+ );
1789
+ }
1790
+ );
1791
+ Slider.displayName = SLIDER_NAME;
1792
+ var [SliderOrientationProvider, useSliderOrientationContext] = createSliderContext(SLIDER_NAME, {
1793
+ startEdge: "left",
1794
+ endEdge: "right",
1795
+ size: "width",
1796
+ direction: 1
1797
+ });
1798
+ var SliderHorizontal = React11.forwardRef(
1799
+ (props, forwardedRef) => {
1800
+ const {
1801
+ min,
1802
+ max,
1803
+ dir,
1804
+ inverted,
1805
+ onSlideStart,
1806
+ onSlideMove,
1807
+ onSlideEnd,
1808
+ onStepKeyDown,
1809
+ ...sliderProps
1810
+ } = props;
1811
+ const [slider, setSlider] = React11.useState(null);
1812
+ const composedRefs = useComposedRefs(forwardedRef, (node) => setSlider(node));
1813
+ const rectRef = React11.useRef(void 0);
1814
+ const direction = useDirection(dir);
1815
+ const isDirectionLTR = direction === "ltr";
1816
+ const isSlidingFromLeft = isDirectionLTR && !inverted || !isDirectionLTR && inverted;
1817
+ function getValueFromPointer(pointerPosition) {
1818
+ const rect = rectRef.current || slider.getBoundingClientRect();
1819
+ const input = [0, rect.width];
1820
+ const output = isSlidingFromLeft ? [min, max] : [max, min];
1821
+ const value = linearScale(input, output);
1822
+ rectRef.current = rect;
1823
+ return value(pointerPosition - rect.left);
1824
+ }
1825
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1826
+ SliderOrientationProvider,
991
1827
  {
992
- onClick: onSelect,
993
- className: cn("bg-primary/8 cursor-pointer overflow-hidden rounded-md border-1 border-transparent", {
994
- "border-primary": isSelected
1828
+ scope: props.__scopeSlider,
1829
+ startEdge: isSlidingFromLeft ? "left" : "right",
1830
+ endEdge: isSlidingFromLeft ? "right" : "left",
1831
+ direction: isSlidingFromLeft ? 1 : -1,
1832
+ size: "width",
1833
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1834
+ SliderImpl,
1835
+ {
1836
+ dir: direction,
1837
+ "data-orientation": "horizontal",
1838
+ ...sliderProps,
1839
+ ref: composedRefs,
1840
+ style: {
1841
+ ...sliderProps.style,
1842
+ ["--radix-slider-thumb-transform"]: "translateX(-50%)"
1843
+ },
1844
+ onSlideStart: (event) => {
1845
+ const value = getValueFromPointer(event.clientX);
1846
+ onSlideStart?.(value);
1847
+ },
1848
+ onSlideMove: (event) => {
1849
+ const value = getValueFromPointer(event.clientX);
1850
+ onSlideMove?.(value);
1851
+ },
1852
+ onSlideEnd: () => {
1853
+ rectRef.current = void 0;
1854
+ onSlideEnd?.();
1855
+ },
1856
+ onStepKeyDown: (event) => {
1857
+ const slideDirection = isSlidingFromLeft ? "from-left" : "from-right";
1858
+ const isBackKey = BACK_KEYS[slideDirection].includes(event.key);
1859
+ onStepKeyDown?.({ event, direction: isBackKey ? -1 : 1 });
1860
+ }
1861
+ }
1862
+ )
1863
+ }
1864
+ );
1865
+ }
1866
+ );
1867
+ var SliderVertical = React11.forwardRef(
1868
+ (props, forwardedRef) => {
1869
+ const {
1870
+ min,
1871
+ max,
1872
+ inverted,
1873
+ onSlideStart,
1874
+ onSlideMove,
1875
+ onSlideEnd,
1876
+ onStepKeyDown,
1877
+ ...sliderProps
1878
+ } = props;
1879
+ const sliderRef = React11.useRef(null);
1880
+ const ref = useComposedRefs(forwardedRef, sliderRef);
1881
+ const rectRef = React11.useRef(void 0);
1882
+ const isSlidingFromBottom = !inverted;
1883
+ function getValueFromPointer(pointerPosition) {
1884
+ const rect = rectRef.current || sliderRef.current.getBoundingClientRect();
1885
+ const input = [0, rect.height];
1886
+ const output = isSlidingFromBottom ? [max, min] : [min, max];
1887
+ const value = linearScale(input, output);
1888
+ rectRef.current = rect;
1889
+ return value(pointerPosition - rect.top);
1890
+ }
1891
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1892
+ SliderOrientationProvider,
1893
+ {
1894
+ scope: props.__scopeSlider,
1895
+ startEdge: isSlidingFromBottom ? "bottom" : "top",
1896
+ endEdge: isSlidingFromBottom ? "top" : "bottom",
1897
+ size: "height",
1898
+ direction: isSlidingFromBottom ? 1 : -1,
1899
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1900
+ SliderImpl,
1901
+ {
1902
+ "data-orientation": "vertical",
1903
+ ...sliderProps,
1904
+ ref,
1905
+ style: {
1906
+ ...sliderProps.style,
1907
+ ["--radix-slider-thumb-transform"]: "translateY(50%)"
1908
+ },
1909
+ onSlideStart: (event) => {
1910
+ const value = getValueFromPointer(event.clientY);
1911
+ onSlideStart?.(value);
1912
+ },
1913
+ onSlideMove: (event) => {
1914
+ const value = getValueFromPointer(event.clientY);
1915
+ onSlideMove?.(value);
1916
+ },
1917
+ onSlideEnd: () => {
1918
+ rectRef.current = void 0;
1919
+ onSlideEnd?.();
1920
+ },
1921
+ onStepKeyDown: (event) => {
1922
+ const slideDirection = isSlidingFromBottom ? "from-bottom" : "from-top";
1923
+ const isBackKey = BACK_KEYS[slideDirection].includes(event.key);
1924
+ onStepKeyDown?.({ event, direction: isBackKey ? -1 : 1 });
1925
+ }
1926
+ }
1927
+ )
1928
+ }
1929
+ );
1930
+ }
1931
+ );
1932
+ var SliderImpl = React11.forwardRef(
1933
+ (props, forwardedRef) => {
1934
+ const {
1935
+ __scopeSlider,
1936
+ onSlideStart,
1937
+ onSlideMove,
1938
+ onSlideEnd,
1939
+ onHomeKeyDown,
1940
+ onEndKeyDown,
1941
+ onStepKeyDown,
1942
+ ...sliderProps
1943
+ } = props;
1944
+ const context = useSliderContext(SLIDER_NAME, __scopeSlider);
1945
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1946
+ Primitive.span,
1947
+ {
1948
+ ...sliderProps,
1949
+ ref: forwardedRef,
1950
+ onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
1951
+ if (event.key === "Home") {
1952
+ onHomeKeyDown(event);
1953
+ event.preventDefault();
1954
+ } else if (event.key === "End") {
1955
+ onEndKeyDown(event);
1956
+ event.preventDefault();
1957
+ } else if (PAGE_KEYS.concat(ARROW_KEYS).includes(event.key)) {
1958
+ onStepKeyDown(event);
1959
+ event.preventDefault();
1960
+ }
995
1961
  }),
1962
+ onPointerDown: composeEventHandlers(props.onPointerDown, (event) => {
1963
+ const target = event.target;
1964
+ target.setPointerCapture(event.pointerId);
1965
+ event.preventDefault();
1966
+ if (context.thumbs.has(target)) {
1967
+ target.focus();
1968
+ } else {
1969
+ onSlideStart(event);
1970
+ }
1971
+ }),
1972
+ onPointerMove: composeEventHandlers(props.onPointerMove, (event) => {
1973
+ const target = event.target;
1974
+ if (target.hasPointerCapture(event.pointerId)) onSlideMove(event);
1975
+ }),
1976
+ onPointerUp: composeEventHandlers(props.onPointerUp, (event) => {
1977
+ const target = event.target;
1978
+ if (target.hasPointerCapture(event.pointerId)) {
1979
+ target.releasePointerCapture(event.pointerId);
1980
+ onSlideEnd(event);
1981
+ }
1982
+ })
1983
+ }
1984
+ );
1985
+ }
1986
+ );
1987
+ var TRACK_NAME = "SliderTrack";
1988
+ var SliderTrack = React11.forwardRef(
1989
+ (props, forwardedRef) => {
1990
+ const { __scopeSlider, ...trackProps } = props;
1991
+ const context = useSliderContext(TRACK_NAME, __scopeSlider);
1992
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1993
+ Primitive.span,
1994
+ {
1995
+ "data-disabled": context.disabled ? "" : void 0,
1996
+ "data-orientation": context.orientation,
1997
+ ...trackProps,
1998
+ ref: forwardedRef
1999
+ }
2000
+ );
2001
+ }
2002
+ );
2003
+ SliderTrack.displayName = TRACK_NAME;
2004
+ var RANGE_NAME = "SliderRange";
2005
+ var SliderRange = React11.forwardRef(
2006
+ (props, forwardedRef) => {
2007
+ const { __scopeSlider, ...rangeProps } = props;
2008
+ const context = useSliderContext(RANGE_NAME, __scopeSlider);
2009
+ const orientation = useSliderOrientationContext(RANGE_NAME, __scopeSlider);
2010
+ const ref = React11.useRef(null);
2011
+ const composedRefs = useComposedRefs(forwardedRef, ref);
2012
+ const valuesCount = context.values.length;
2013
+ const percentages = context.values.map(
2014
+ (value) => convertValueToPercentage(value, context.min, context.max)
2015
+ );
2016
+ const offsetStart = valuesCount > 1 ? Math.min(...percentages) : 0;
2017
+ const offsetEnd = 100 - Math.max(...percentages);
2018
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2019
+ Primitive.span,
2020
+ {
2021
+ "data-orientation": context.orientation,
2022
+ "data-disabled": context.disabled ? "" : void 0,
2023
+ ...rangeProps,
2024
+ ref: composedRefs,
2025
+ style: {
2026
+ ...props.style,
2027
+ [orientation.startEdge]: offsetStart + "%",
2028
+ [orientation.endEdge]: offsetEnd + "%"
2029
+ }
2030
+ }
2031
+ );
2032
+ }
2033
+ );
2034
+ SliderRange.displayName = RANGE_NAME;
2035
+ var THUMB_NAME = "SliderThumb";
2036
+ var SliderThumb = React11.forwardRef(
2037
+ (props, forwardedRef) => {
2038
+ const getItems = useCollection(props.__scopeSlider);
2039
+ const [thumb, setThumb] = React11.useState(null);
2040
+ const composedRefs = useComposedRefs(forwardedRef, (node) => setThumb(node));
2041
+ const index = React11.useMemo(
2042
+ () => thumb ? getItems().findIndex((item) => item.ref.current === thumb) : -1,
2043
+ [getItems, thumb]
2044
+ );
2045
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SliderThumbImpl, { ...props, ref: composedRefs, index });
2046
+ }
2047
+ );
2048
+ var SliderThumbImpl = React11.forwardRef(
2049
+ (props, forwardedRef) => {
2050
+ const { __scopeSlider, index, name, ...thumbProps } = props;
2051
+ const context = useSliderContext(THUMB_NAME, __scopeSlider);
2052
+ const orientation = useSliderOrientationContext(THUMB_NAME, __scopeSlider);
2053
+ const [thumb, setThumb] = React11.useState(null);
2054
+ const composedRefs = useComposedRefs(forwardedRef, (node) => setThumb(node));
2055
+ const isFormControl = thumb ? context.form || !!thumb.closest("form") : true;
2056
+ const size = useSize(thumb);
2057
+ const value = context.values[index];
2058
+ const percent = value === void 0 ? 0 : convertValueToPercentage(value, context.min, context.max);
2059
+ const label = getLabel(index, context.values.length);
2060
+ const orientationSize = size?.[orientation.size];
2061
+ const thumbInBoundsOffset = orientationSize ? getThumbInBoundsOffset(orientationSize, percent, orientation.direction) : 0;
2062
+ React11.useEffect(() => {
2063
+ if (thumb) {
2064
+ context.thumbs.add(thumb);
2065
+ return () => {
2066
+ context.thumbs.delete(thumb);
2067
+ };
2068
+ }
2069
+ }, [thumb, context.thumbs]);
2070
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2071
+ "span",
2072
+ {
2073
+ style: {
2074
+ transform: "var(--radix-slider-thumb-transform)",
2075
+ position: "absolute",
2076
+ [orientation.startEdge]: `calc(${percent}% + ${thumbInBoundsOffset}px)`
2077
+ },
996
2078
  children: [
997
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: cn("flex h-11 w-full", { "bg-black/4": isSelected }), children: [
998
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
999
- "div",
2079
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Collection.ItemSlot, { scope: props.__scopeSlider, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2080
+ Primitive.span,
2081
+ {
2082
+ role: "slider",
2083
+ "aria-label": props["aria-label"] || label,
2084
+ "aria-valuemin": context.min,
2085
+ "aria-valuenow": value,
2086
+ "aria-valuemax": context.max,
2087
+ "aria-orientation": context.orientation,
2088
+ "data-orientation": context.orientation,
2089
+ "data-disabled": context.disabled ? "" : void 0,
2090
+ tabIndex: context.disabled ? void 0 : 0,
2091
+ ...thumbProps,
2092
+ ref: composedRefs,
2093
+ style: value === void 0 ? { display: "none" } : props.style,
2094
+ onFocus: composeEventHandlers(props.onFocus, () => {
2095
+ context.valueIndexToChangeRef.current = index;
2096
+ })
2097
+ }
2098
+ ) }),
2099
+ isFormControl && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2100
+ SliderBubbleInput,
2101
+ {
2102
+ name: name ?? (context.name ? context.name + (context.values.length > 1 ? "[]" : "") : void 0),
2103
+ form: context.form,
2104
+ value
2105
+ },
2106
+ index
2107
+ )
2108
+ ]
2109
+ }
2110
+ );
2111
+ }
2112
+ );
2113
+ SliderThumb.displayName = THUMB_NAME;
2114
+ var BUBBLE_INPUT_NAME = "RadioBubbleInput";
2115
+ var SliderBubbleInput = React11.forwardRef(
2116
+ ({ __scopeSlider, value, ...props }, forwardedRef) => {
2117
+ const ref = React11.useRef(null);
2118
+ const composedRefs = useComposedRefs(ref, forwardedRef);
2119
+ const prevValue = usePrevious(value);
2120
+ React11.useEffect(() => {
2121
+ const input = ref.current;
2122
+ if (!input) return;
2123
+ const inputProto = window.HTMLInputElement.prototype;
2124
+ const descriptor = Object.getOwnPropertyDescriptor(inputProto, "value");
2125
+ const setValue = descriptor.set;
2126
+ if (prevValue !== value && setValue) {
2127
+ const event = new Event("input", { bubbles: true });
2128
+ setValue.call(input, value);
2129
+ input.dispatchEvent(event);
2130
+ }
2131
+ }, [prevValue, value]);
2132
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2133
+ Primitive.input,
2134
+ {
2135
+ style: { display: "none" },
2136
+ ...props,
2137
+ ref: composedRefs,
2138
+ defaultValue: value
2139
+ }
2140
+ );
2141
+ }
2142
+ );
2143
+ SliderBubbleInput.displayName = BUBBLE_INPUT_NAME;
2144
+ function getNextSortedValues(prevValues = [], nextValue, atIndex) {
2145
+ const nextValues = [...prevValues];
2146
+ nextValues[atIndex] = nextValue;
2147
+ return nextValues.sort((a, b) => a - b);
2148
+ }
2149
+ function convertValueToPercentage(value, min, max) {
2150
+ const maxSteps = max - min;
2151
+ const percentPerStep = 100 / maxSteps;
2152
+ const percentage = percentPerStep * (value - min);
2153
+ return clamp(percentage, [0, 100]);
2154
+ }
2155
+ function getLabel(index, totalValues) {
2156
+ if (totalValues > 2) {
2157
+ return `Value ${index + 1} of ${totalValues}`;
2158
+ } else if (totalValues === 2) {
2159
+ return ["Minimum", "Maximum"][index];
2160
+ } else {
2161
+ return void 0;
2162
+ }
2163
+ }
2164
+ function getClosestValueIndex(values, nextValue) {
2165
+ if (values.length === 1) return 0;
2166
+ const distances = values.map((value) => Math.abs(value - nextValue));
2167
+ const closestDistance = Math.min(...distances);
2168
+ return distances.indexOf(closestDistance);
2169
+ }
2170
+ function getThumbInBoundsOffset(width, left, direction) {
2171
+ const halfWidth = width / 2;
2172
+ const halfPercent = 50;
2173
+ const offset = linearScale([0, halfPercent], [0, halfWidth]);
2174
+ return (halfWidth - offset(left) * direction) * direction;
2175
+ }
2176
+ function getStepsBetweenValues(values) {
2177
+ return values.slice(0, -1).map((value, index) => values[index + 1] - value);
2178
+ }
2179
+ function hasMinStepsBetweenValues(values, minStepsBetweenValues) {
2180
+ if (minStepsBetweenValues > 0) {
2181
+ const stepsBetweenValues = getStepsBetweenValues(values);
2182
+ const actualMinStepsBetweenValues = Math.min(...stepsBetweenValues);
2183
+ return actualMinStepsBetweenValues >= minStepsBetweenValues;
2184
+ }
2185
+ return true;
2186
+ }
2187
+ function linearScale(input, output) {
2188
+ return (value) => {
2189
+ if (input[0] === input[1] || output[0] === output[1]) return output[0];
2190
+ const ratio = (output[1] - output[0]) / (input[1] - input[0]);
2191
+ return output[0] + ratio * (value - input[0]);
2192
+ };
2193
+ }
2194
+ function getDecimalCount(value) {
2195
+ return (String(value).split(".")[1] || "").length;
2196
+ }
2197
+ function roundValue(value, decimalCount) {
2198
+ const rounder = Math.pow(10, decimalCount);
2199
+ return Math.round(value * rounder) / rounder;
2200
+ }
2201
+ var Root5 = Slider;
2202
+ var Track = SliderTrack;
2203
+ var Range = SliderRange;
2204
+ var Thumb2 = SliderThumb;
2205
+
2206
+ // ../ui/src/lib/utils.ts
2207
+ var import_clsx2 = require("clsx");
2208
+ var import_tailwind_merge2 = require("tailwind-merge");
2209
+ function cn2(...inputs) {
2210
+ return (0, import_tailwind_merge2.twMerge)((0, import_clsx2.clsx)(inputs));
2211
+ }
2212
+
2213
+ // src/ui/slider.tsx
2214
+ var import_jsx_runtime23 = require("react/jsx-runtime");
2215
+ function Slider2({
2216
+ className,
2217
+ defaultValue,
2218
+ value,
2219
+ min = 0,
2220
+ max = 100,
2221
+ ...props
2222
+ }) {
2223
+ const _values = React12.useMemo(
2224
+ () => Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min, max],
2225
+ [value, defaultValue, min, max]
2226
+ );
2227
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
2228
+ Root5,
2229
+ {
2230
+ "data-slot": "slider",
2231
+ defaultValue,
2232
+ value,
2233
+ min,
2234
+ max,
2235
+ className: cn2(
2236
+ "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",
2237
+ className
2238
+ ),
2239
+ ...props,
2240
+ children: [
2241
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2242
+ Track,
2243
+ {
2244
+ "data-slot": "slider-track",
2245
+ className: cn2(
2246
+ "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"
2247
+ ),
2248
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2249
+ Range,
1000
2250
  {
1001
- className: cn("flex h-full w-11 items-center justify-center bg-black/10", {
1002
- "bg-primary": isSelected
1003
- }),
1004
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-white", children: isSelected && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "bg-primary h-2.5 w-2.5 rounded-full" }) })
2251
+ "data-slot": "slider-range",
2252
+ className: cn2("bg-primary absolute data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full")
1005
2253
  }
1006
- ),
1007
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex h-full w-full items-center justify-between gap-4 px-3", children })
2254
+ )
2255
+ }
2256
+ ),
2257
+ Array.from({ length: _values.length }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2258
+ Thumb2,
2259
+ {
2260
+ "data-slot": "slider-thumb",
2261
+ 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"
2262
+ },
2263
+ index
2264
+ ))
2265
+ ]
2266
+ }
2267
+ );
2268
+ }
2269
+
2270
+ // src/components/CreditCardTab/Points/PointsSelector.tsx
2271
+ var import_jsx_runtime24 = require("react/jsx-runtime");
2272
+ var PointsSelector = (props) => {
2273
+ const { isSelected, onSelect, children } = props;
2274
+ const { balance } = useSlapiBalance();
2275
+ const { selectedPaymentMethod, setSelectedPaymentMethod } = useSpreePaymentMethod();
2276
+ const { appProps, staticConfig } = useStaticConfig();
2277
+ const min = 0;
2278
+ const max = Math.min((appProps.amount ?? 0) * staticConfig.pointsConversionRatio, balance?.availablePoints ?? 0);
2279
+ const step = 10;
2280
+ const [splitTokens, setSplitTokens] = (0, import_react10.useState)(0);
2281
+ const splitAmount = getSplitAmount(appProps.amount ?? 0, splitTokens, staticConfig.pointsConversionRatio);
2282
+ const handleCommit = (value) => {
2283
+ setSelectedPaymentMethod({ ...selectedPaymentMethod, splitAmount: value });
2284
+ };
2285
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
2286
+ "button",
2287
+ {
2288
+ onClick: onSelect,
2289
+ className: cn("bg-primary/8 cursor-pointer overflow-hidden rounded-md border-1 border-transparent", {
2290
+ "border-primary": isSelected
2291
+ }),
2292
+ children: [
2293
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: cn("flex h-11 w-full", { "bg-black/4": isSelected }), children: [
2294
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2295
+ "div",
2296
+ {
2297
+ className: cn("flex h-full w-11 items-center justify-center bg-black/10", {
2298
+ "bg-primary": isSelected
2299
+ }),
2300
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-white", children: isSelected && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "bg-primary h-2.5 w-2.5 rounded-full" }) })
2301
+ }
2302
+ ),
2303
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex h-full w-full items-center justify-between gap-3 px-3", children })
2304
+ ] }),
2305
+ isSelected && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "px-3 pt-6 pb-2 md:px-4", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex justify-between gap-3", children: [
2306
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex max-w-[100px] flex-col gap-1", children: [
2307
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Input, { readOnly: true, value: splitTokens, className: "bg-white text-center font-medium" }),
2308
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-left text-xs leading-[20px] text-black/45", children: "Points" })
1008
2309
  ] }),
1009
- isSelected && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "px-4 pt-6 pb-2", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { children: "Card" }) })
1010
- ]
1011
- }
1012
- )
2310
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex w-full items-center pb-6", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2311
+ Slider2,
2312
+ {
2313
+ value: [splitTokens],
2314
+ onValueCommit: ([v]) => handleCommit(v),
2315
+ onValueChange: ([v]) => setSplitTokens(v),
2316
+ min,
2317
+ max,
2318
+ step
2319
+ }
2320
+ ) }),
2321
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex max-w-[100px] flex-col gap-1", children: [
2322
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2323
+ Input,
2324
+ {
2325
+ readOnly: true,
2326
+ value: formatUSD(splitAmount + getTransactionFee(splitAmount, appProps.transactionFeePercentage)),
2327
+ className: "bg-white text-center font-medium"
2328
+ }
2329
+ ),
2330
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-left text-xs leading-[20px] text-black/45", children: "Card" })
2331
+ ] })
2332
+ ] }) })
2333
+ ]
2334
+ }
1013
2335
  );
1014
2336
  };
1015
- var CreditCardTab = ({ pointsTitle, pointsConversionRatio }) => {
1016
- const [usePoints, setUsePoints] = (0, import_react7.useState)(false);
1017
- const [selectedPointsType, setSelectedPointsType] = (0, import_react7.useState)(null);
2337
+
2338
+ // src/components/CreditCardTab/Points/SplitBlock.tsx
2339
+ var import_jsx_runtime25 = require("react/jsx-runtime");
2340
+ var SplitBlock = (props) => {
2341
+ const { isSelected, onSelect } = props;
1018
2342
  const { balance, isBalanceLoading } = useSlapiBalance();
2343
+ const { spreePayConfig } = useSpreePayConfig();
2344
+ const [address, setAddress] = (0, import_react11.useState)(null);
2345
+ const { staticConfig } = useStaticConfig();
2346
+ const { pointsConversionRatio, pointsTitle } = staticConfig;
2347
+ const initWallet = (0, import_react11.useCallback)(async (pointsChain) => {
2348
+ if (!pointsChain) {
2349
+ return;
2350
+ }
2351
+ try {
2352
+ const res = await getAirWallet({
2353
+ mocaChain: pointsChain.mocaChain,
2354
+ partnerId: pointsChain.partnerId
2355
+ });
2356
+ setAddress(res.address ?? null);
2357
+ } catch (e) {
2358
+ console.error("Air Wallet init failed:", e);
2359
+ }
2360
+ }, []);
2361
+ (0, import_react11.useEffect)(() => {
2362
+ initWallet(spreePayConfig?.pointsChain);
2363
+ }, [spreePayConfig, initWallet]);
2364
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex flex-col gap-1", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(PointsSelector, { onSelect: () => onSelect("air"), isSelected, children: [
2365
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex items-center gap-2", children: balance?.availablePoints ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("p", { className: "text-sm font-medium text-black", children: [
2366
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-black/50", children: "Available" }),
2367
+ " ",
2368
+ formatPoints(balance.availablePoints, pointsTitle),
2369
+ " ",
2370
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-black/50", children: formatUSD(balance.availablePoints / pointsConversionRatio) })
2371
+ ] }) : null }),
2372
+ isBalanceLoading ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "h-4 w-6 animate-pulse bg-gray-200" }) : !balance?.availablePoints && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-sm font-medium text-black", children: "No points available" }),
2373
+ address && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "text-sm font-medium text-black", children: address.length > 8 ? `${address.slice(0, 4)}...${address.slice(-4)}` : address })
2374
+ ] }) });
2375
+ };
2376
+
2377
+ // src/components/CreditCardTab/Points/Points.tsx
2378
+ var import_jsx_runtime26 = require("react/jsx-runtime");
2379
+ var Points = () => {
2380
+ const [usePoints, setUsePoints] = (0, import_react12.useState)(false);
2381
+ const [selectedPointsType, setSelectedPointsType] = (0, import_react12.useState)(null);
2382
+ const { setSelectedPaymentMethod, selectedPaymentMethod } = useSpreePaymentMethod();
2383
+ const handleTogglePoints = (enabled) => {
2384
+ setUsePoints(enabled);
2385
+ if (!enabled) {
2386
+ setSelectedPointsType(null);
2387
+ setSelectedPaymentMethod({ ...selectedPaymentMethod, splitAmount: void 0 });
2388
+ }
2389
+ };
2390
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
2391
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PointsSwitch, { value: usePoints, onChange: handleTogglePoints }),
2392
+ usePoints && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SplitBlock, { isSelected: selectedPointsType === "air", onSelect: setSelectedPointsType })
2393
+ ] });
2394
+ };
2395
+
2396
+ // src/components/CreditCardTab/CreditCardTab.tsx
2397
+ var import_jsx_runtime27 = require("react/jsx-runtime");
2398
+ var CreditCardTab = () => {
1019
2399
  const { selectedPaymentMethod, setSelectedPaymentMethod } = useSpreePaymentMethod();
1020
2400
  const { register } = useSpreePayRegister();
1021
2401
  const { mutateCards } = useCards();
1022
- const { env } = useSpreePayEnv();
1023
- const handlePay = (0, import_react7.useCallback)(
2402
+ const { cardPayment } = useCardPayment();
2403
+ const { splitPayment } = useSplitCardPayments();
2404
+ const handlePay = (0, import_react13.useCallback)(
1024
2405
  async (data) => {
1025
2406
  try {
1026
2407
  if (selectedPaymentMethod.type === "CREDIT_CARD" /* CREDIT_CARD */ && selectedPaymentMethod.method) {
1027
- const res = await cardPayment({
1028
- ...data,
1029
- card: selectedPaymentMethod.method,
1030
- redirect3dsURI: env.redirect3dsURI
1031
- });
2408
+ let res = null;
2409
+ if (selectedPaymentMethod.splitAmount && selectedPaymentMethod.splitAmount > 0) {
2410
+ res = await splitPayment({ ...data, points: selectedPaymentMethod.splitAmount });
2411
+ } else {
2412
+ res = await cardPayment(data);
2413
+ }
1032
2414
  if (["AUTHORIZED" /* AUTHORIZED */, "CAPTURED" /* CAPTURED */].includes(res.status)) {
1033
2415
  return Promise.resolve(res);
1034
2416
  }
@@ -1038,57 +2420,24 @@ var CreditCardTab = ({ pointsTitle, pointsConversionRatio }) => {
1038
2420
  } catch (_) {
1039
2421
  return Promise.reject(new PaymentError("Payment failed", "FAILED" /* FAILED */));
1040
2422
  } finally {
1041
- setSelectedPaymentMethod({ type: "CREDIT_CARD" /* CREDIT_CARD */, method: null });
2423
+ setSelectedPaymentMethod({ ...selectedPaymentMethod, type: "CREDIT_CARD" /* CREDIT_CARD */, method: null });
1042
2424
  mutateCards();
1043
2425
  }
1044
2426
  },
1045
- [setSelectedPaymentMethod, mutateCards, env.redirect3dsURI, selectedPaymentMethod]
2427
+ [mutateCards, selectedPaymentMethod, setSelectedPaymentMethod, cardPayment, splitPayment]
1046
2428
  );
1047
- (0, import_react7.useEffect)(() => {
2429
+ (0, import_react13.useEffect)(() => {
1048
2430
  register(handlePay);
1049
2431
  }, [register, handlePay]);
1050
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { children: [
1051
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "border-b-1 border-black/7 px-5 py-5 md:px-7 md:py-6", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CreditCard, {}) }),
1052
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-col gap-6 px-5 py-5 md:px-7 md:py-6", children: [
1053
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1054
- PointsSwitch,
1055
- {
1056
- disabled: true,
1057
- value: usePoints,
1058
- onChange: setUsePoints,
1059
- pointsTitle,
1060
- pointsConversionRatio
1061
- }
1062
- ),
1063
- usePoints && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-col gap-1", children: [
1064
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(PointsSelector, { onSelect: () => setSelectedPointsType("slapi"), isSelected: selectedPointsType === "slapi", children: [
1065
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-sm font-medium text-black", children: "from [Brand] Balance" }) }),
1066
- isBalanceLoading ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "h-4 w-6 animate-pulse bg-gray-200" }) : !balance?.availablePoints && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-sm font-medium text-black", children: "No points available" }),
1067
- balance?.availablePoints ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("p", { className: "text-sm font-medium text-black", children: [
1068
- formatPoints(balance.availablePoints, pointsTitle),
1069
- " ",
1070
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-black/50", children: formatUSD(balance.availablePoints / pointsConversionRatio) })
1071
- ] }) : null
1072
- ] }),
1073
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1074
- PointsSelector,
1075
- {
1076
- onSelect: () => setSelectedPointsType("wallet"),
1077
- isSelected: selectedPointsType === "wallet",
1078
- children: [
1079
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-sm font-medium text-black", children: "from Crypto Wallet" }) }),
1080
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("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" })
1081
- ]
1082
- }
1083
- )
1084
- ] })
1085
- ] })
2432
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { children: [
2433
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "border-b-1 border-black/7 px-5 py-5 md:px-7 md:py-6", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(CreditCard, {}) }),
2434
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "flex flex-col gap-6 px-5 pt-5 pb-5 md:px-7 md:pt-6 md:pb-7", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Points, {}) })
1086
2435
  ] });
1087
2436
  };
1088
2437
 
1089
2438
  // src/components/CryptoTab/Crypto/CryptoWrapper.tsx
1090
2439
  var import_react_query = require("@tanstack/react-query");
1091
- var import_nice_modal_react5 = __toESM(require("@ebay/nice-modal-react"), 1);
2440
+ var import_nice_modal_react6 = __toESM(require("@ebay/nice-modal-react"), 1);
1092
2441
  var import_rainbowkit2 = require("@rainbow-me/rainbowkit");
1093
2442
  var import_styles = require("@rainbow-me/rainbowkit/styles.css");
1094
2443
  var import_wallets = require("@rainbow-me/rainbowkit/wallets");
@@ -1096,7 +2445,7 @@ var import_wagmi5 = require("wagmi");
1096
2445
  var import_chains = require("wagmi/chains");
1097
2446
 
1098
2447
  // src/components/CryptoTab/Crypto/Crypto.tsx
1099
- var import_react8 = require("react");
2448
+ var import_react14 = require("react");
1100
2449
  var import_wagmi4 = require("wagmi");
1101
2450
 
1102
2451
  // ../../node_modules/@wagmi/core/dist/esm/utils/getAction.js
@@ -1120,7 +2469,7 @@ function readContract(config2, parameters) {
1120
2469
  }
1121
2470
 
1122
2471
  // ../../node_modules/@wagmi/core/dist/esm/actions/waitForTransactionReceipt.js
1123
- var import_viem = require("viem");
2472
+ var import_viem2 = require("viem");
1124
2473
  var import_actions2 = require("viem/actions");
1125
2474
  async function waitForTransactionReceipt(config2, parameters) {
1126
2475
  const { chainId, timeout = 0, ...rest } = parameters;
@@ -1138,7 +2487,7 @@ async function waitForTransactionReceipt(config2, parameters) {
1138
2487
  maxFeePerGas: txn.type === "eip1559" ? txn.maxFeePerGas : void 0,
1139
2488
  maxPriorityFeePerGas: txn.type === "eip1559" ? txn.maxPriorityFeePerGas : void 0
1140
2489
  });
1141
- const reason = code?.data ? (0, import_viem.hexToString)(`0x${code.data.substring(138)}`) : "unknown reason";
2490
+ const reason = code?.data ? (0, import_viem2.hexToString)(`0x${code.data.substring(138)}`) : "unknown reason";
1142
2491
  throw new Error(reason);
1143
2492
  }
1144
2493
  return {
@@ -1148,10 +2497,10 @@ async function waitForTransactionReceipt(config2, parameters) {
1148
2497
  }
1149
2498
 
1150
2499
  // ../../node_modules/@wagmi/core/dist/esm/exports/index.js
1151
- var import_viem2 = require("viem");
2500
+ var import_viem3 = require("viem");
1152
2501
 
1153
2502
  // src/hooks/useCryptoPayment.ts
1154
- var import_viem3 = require("viem");
2503
+ var import_viem4 = require("viem");
1155
2504
  var import_wagmi = require("wagmi");
1156
2505
 
1157
2506
  // src/config/baseTokens.ts
@@ -1214,14 +2563,14 @@ var useCryptoPayment = () => {
1214
2563
  }
1215
2564
  const allowance = await readContract(config2, {
1216
2565
  address: tokenAddress,
1217
- abi: import_viem3.erc20Abi,
2566
+ abi: import_viem4.erc20Abi,
1218
2567
  functionName: "allowance",
1219
2568
  args: [walletClient.account.address, ONE_INCH_AGGREGATION_ROUTER_V6]
1220
2569
  });
1221
2570
  if (allowance <= 0n) {
1222
2571
  const result = await walletClient.writeContract({
1223
2572
  address: tokenAddress,
1224
- abi: import_viem3.erc20Abi,
2573
+ abi: import_viem4.erc20Abi,
1225
2574
  functionName: "approve",
1226
2575
  args: [ONE_INCH_AGGREGATION_ROUTER_V6, MAX_UINT256]
1227
2576
  });
@@ -1265,13 +2614,13 @@ var useCryptoPayment = () => {
1265
2614
 
1266
2615
  // src/components/CryptoTab/Crypto/ConnectButton.tsx
1267
2616
  var import_rainbowkit = require("@rainbow-me/rainbowkit");
1268
- var import_jsx_runtime16 = require("react/jsx-runtime");
2617
+ var import_jsx_runtime28 = require("react/jsx-runtime");
1269
2618
  var ConnectButton = () => {
1270
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_rainbowkit.ConnectButton.Custom, { children: ({ mounted, chain, account, openAccountModal, openChainModal, openConnectModal }) => {
2619
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_rainbowkit.ConnectButton.Custom, { children: ({ mounted, chain, account, openAccountModal, openChainModal, openConnectModal }) => {
1271
2620
  if (!mounted) return null;
1272
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children: (() => {
2621
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_jsx_runtime28.Fragment, { children: (() => {
1273
2622
  if (!mounted || !account || !chain) {
1274
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2623
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1275
2624
  "button",
1276
2625
  {
1277
2626
  className: "h-[34px] rounded-md border-1 border-black px-3 text-sm font-medium text-black",
@@ -1281,7 +2630,7 @@ var ConnectButton = () => {
1281
2630
  );
1282
2631
  }
1283
2632
  if (chain.unsupported) {
1284
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2633
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1285
2634
  "button",
1286
2635
  {
1287
2636
  className: "h-[34px] rounded-md border-1 border-black px-3 text-sm font-medium text-red-500",
@@ -1290,13 +2639,13 @@ var ConnectButton = () => {
1290
2639
  }
1291
2640
  );
1292
2641
  }
1293
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2642
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
1294
2643
  "button",
1295
2644
  {
1296
2645
  className: "flex h-[34px] items-center gap-2 rounded-md border-1 border-black px-1.5 text-sm font-medium text-black",
1297
2646
  onClick: openAccountModal,
1298
2647
  children: [
1299
- chain.hasIcon && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "h-6 w-6 overflow-hidden rounded-full", style: { background: chain.iconBackground }, children: chain.iconUrl && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("img", { alt: chain.name ?? "Chain icon", src: chain.iconUrl }) }),
2648
+ chain.hasIcon && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "h-6 w-6 overflow-hidden rounded-full", style: { background: chain.iconBackground }, children: chain.iconUrl && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("img", { alt: chain.name ?? "Chain icon", src: chain.iconUrl }) }),
1300
2649
  account.displayName
1301
2650
  ]
1302
2651
  }
@@ -1306,29 +2655,29 @@ var ConnectButton = () => {
1306
2655
  };
1307
2656
 
1308
2657
  // src/config/symbolLogos.tsx
1309
- var import_jsx_runtime17 = require("react/jsx-runtime");
1310
- var MOCA_SVG = /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "28", height: "28", fill: "none", children: [
1311
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "14", cy: "14", r: "13.5", fill: "#C15F97" }),
1312
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2658
+ var import_jsx_runtime29 = require("react/jsx-runtime");
2659
+ var MOCA_SVG = /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "28", height: "28", fill: "none", children: [
2660
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("circle", { cx: "14", cy: "14", r: "13.5", fill: "#C15F97" }),
2661
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1313
2662
  "path",
1314
2663
  {
1315
2664
  fill: "#fff",
1316
2665
  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"
1317
2666
  }
1318
2667
  ),
1319
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "16", cy: "14", r: "1.5", fill: "#fff" })
2668
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("circle", { cx: "16", cy: "14", r: "1.5", fill: "#fff" })
1320
2669
  ] });
1321
- var USDC_SVG = /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "28", height: "28", fill: "none", children: [
1322
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("g", { clipPath: "url(#clip0_528_9163)", children: [
1323
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("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" }),
1324
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2670
+ var USDC_SVG = /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "28", height: "28", fill: "none", children: [
2671
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("g", { clipPath: "url(#clip0_528_9163)", children: [
2672
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("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" }),
2673
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1325
2674
  "path",
1326
2675
  {
1327
2676
  fill: "#fff",
1328
2677
  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"
1329
2678
  }
1330
2679
  ),
1331
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2680
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1332
2681
  "path",
1333
2682
  {
1334
2683
  fill: "#fff",
@@ -1336,11 +2685,11 @@ var USDC_SVG = /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("svg", { xmlns: "h
1336
2685
  }
1337
2686
  )
1338
2687
  ] }),
1339
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("clipPath", { id: "clip0_528_9163", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { fill: "#fff", d: "M0 0h28v28H0z" }) }) })
2688
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("clipPath", { id: "clip0_528_9163", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("path", { fill: "#fff", d: "M0 0h28v28H0z" }) }) })
1340
2689
  ] });
1341
- var USDT_SVG = /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "28", height: "28", fill: "none", children: [
1342
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { fill: "#26A17B", d: "M14 28a14 14 0 1 0 0-28 14 14 0 0 0 0 28Z" }),
1343
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2690
+ var USDT_SVG = /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "28", height: "28", fill: "none", children: [
2691
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("path", { fill: "#26A17B", d: "M14 28a14 14 0 1 0 0-28 14 14 0 0 0 0 28Z" }),
2692
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1344
2693
  "path",
1345
2694
  {
1346
2695
  fill: "#fff",
@@ -1348,23 +2697,23 @@ var USDT_SVG = /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("svg", { xmlns: "h
1348
2697
  }
1349
2698
  )
1350
2699
  ] });
1351
- var WETH_SVG = /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", width: "28", height: "28", viewBox: "0 0 24 24", children: [
1352
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("g", { clipPath: "url(#clip0_528_9173)", children: [
1353
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2700
+ var WETH_SVG = /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", width: "28", height: "28", viewBox: "0 0 24 24", children: [
2701
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("g", { clipPath: "url(#clip0_528_9173)", children: [
2702
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1354
2703
  "path",
1355
2704
  {
1356
2705
  fill: "#000",
1357
2706
  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"
1358
2707
  }
1359
2708
  ),
1360
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2709
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1361
2710
  "path",
1362
2711
  {
1363
2712
  fill: "#F61F7D",
1364
2713
  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"
1365
2714
  }
1366
2715
  ),
1367
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2716
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1368
2717
  "path",
1369
2718
  {
1370
2719
  fill: "#000",
@@ -1373,8 +2722,8 @@ var WETH_SVG = /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("svg", { xmlns: "h
1373
2722
  clipRule: "evenodd"
1374
2723
  }
1375
2724
  ),
1376
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("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" }),
1377
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2725
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("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" }),
2726
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1378
2727
  "path",
1379
2728
  {
1380
2729
  fill: "#000",
@@ -1383,8 +2732,8 @@ var WETH_SVG = /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("svg", { xmlns: "h
1383
2732
  clipRule: "evenodd"
1384
2733
  }
1385
2734
  ),
1386
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { fill: "#000", fillRule: "evenodd", d: "M3.02 10.63.7 8.75l.74-.86 2.34 1.87-.75.87Z", clipRule: "evenodd" }),
1387
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2735
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("path", { fill: "#000", fillRule: "evenodd", d: "M3.02 10.63.7 8.75l.74-.86 2.34 1.87-.75.87Z", clipRule: "evenodd" }),
2736
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1388
2737
  "path",
1389
2738
  {
1390
2739
  fill: "#000",
@@ -1392,7 +2741,7 @@ var WETH_SVG = /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("svg", { xmlns: "h
1392
2741
  }
1393
2742
  )
1394
2743
  ] }),
1395
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("clipPath", { id: "clip0_528_9173", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { fill: "#fff", d: "M0 0h24v24H0z" }) }) })
2744
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("clipPath", { id: "clip0_528_9173", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("path", { fill: "#fff", d: "M0 0h24v24H0z" }) }) })
1396
2745
  ] });
1397
2746
  var symbolLogos = {
1398
2747
  MOCA: MOCA_SVG,
@@ -1405,34 +2754,34 @@ function getSymbolLogo(symbol) {
1405
2754
  }
1406
2755
 
1407
2756
  // src/components/CryptoTab/Crypto/Logos.tsx
1408
- var import_jsx_runtime18 = require("react/jsx-runtime");
2757
+ var import_jsx_runtime30 = require("react/jsx-runtime");
1409
2758
  var Logos = () => {
1410
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex", children: [
1411
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "rounded-full border border-[#F5F7FA]", children: getSymbolLogo("MOCA") }),
1412
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "-ml-2.5 rounded-full border border-[#F5F7FA]", children: getSymbolLogo("USDC") }),
1413
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "-ml-2.5 rounded-full border border-[#F5F7FA]", children: getSymbolLogo("USDT") }),
1414
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "-ml-2.5 rounded-full border border-[#F5F7FA] bg-[#F5F7FA]", children: getSymbolLogo("WETH") })
2759
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex", children: [
2760
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "rounded-full border border-[#F5F7FA]", children: getSymbolLogo("MOCA") }),
2761
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "-ml-2.5 rounded-full border border-[#F5F7FA]", children: getSymbolLogo("USDC") }),
2762
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "-ml-2.5 rounded-full border border-[#F5F7FA]", children: getSymbolLogo("USDT") }),
2763
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "-ml-2.5 rounded-full border border-[#F5F7FA] bg-[#F5F7FA]", children: getSymbolLogo("WETH") })
1415
2764
  ] });
1416
2765
  };
1417
2766
 
1418
2767
  // src/components/CryptoTab/Crypto/SelectCoinButton.tsx
1419
- var import_nice_modal_react4 = __toESM(require("@ebay/nice-modal-react"), 1);
2768
+ var import_nice_modal_react5 = __toESM(require("@ebay/nice-modal-react"), 1);
1420
2769
 
1421
2770
  // src/modals/CryptoSelectModal.tsx
1422
- var import_nice_modal_react3 = __toESM(require("@ebay/nice-modal-react"), 1);
2771
+ var import_nice_modal_react4 = __toESM(require("@ebay/nice-modal-react"), 1);
1423
2772
 
1424
2773
  // src/hooks/useBaseERC20Token.ts
1425
- var React2 = __toESM(require("react"), 1);
1426
- var import_viem4 = require("viem");
2774
+ var React13 = __toESM(require("react"), 1);
2775
+ var import_viem5 = require("viem");
1427
2776
  var import_wagmi2 = require("wagmi");
1428
2777
  function useBaseERC20Token() {
1429
2778
  const { address } = (0, import_wagmi2.useAccount)();
1430
2779
  const baseClient = (0, import_wagmi2.usePublicClient)({ chainId: BASE_CHAIN_ID });
1431
2780
  const defaultClient = (0, import_wagmi2.usePublicClient)();
1432
- const [rows, setRows] = React2.useState([]);
1433
- const [isLoading, setLoading] = React2.useState(false);
1434
- const [error, setError] = React2.useState(null);
1435
- React2.useEffect(() => {
2781
+ const [rows, setRows] = React13.useState([]);
2782
+ const [isLoading, setLoading] = React13.useState(false);
2783
+ const [error, setError] = React13.useState(null);
2784
+ React13.useEffect(() => {
1436
2785
  let cancelled = false;
1437
2786
  async function run() {
1438
2787
  const client = baseClient ?? defaultClient;
@@ -1445,7 +2794,7 @@ function useBaseERC20Token() {
1445
2794
  const normalizedTokens = [];
1446
2795
  for (const t of BASE_TOKENS) {
1447
2796
  try {
1448
- const addr = (0, import_viem4.getAddress)(t.address);
2797
+ const addr = (0, import_viem5.getAddress)(t.address);
1449
2798
  normalizedTokens.push({ ...t, address: addr });
1450
2799
  } catch {
1451
2800
  }
@@ -1454,7 +2803,7 @@ function useBaseERC20Token() {
1454
2803
  allowFailure: true,
1455
2804
  contracts: normalizedTokens.map((t) => ({
1456
2805
  address: t.address,
1457
- abi: import_viem4.erc20Abi,
2806
+ abi: import_viem5.erc20Abi,
1458
2807
  functionName: "balanceOf",
1459
2808
  args: [address]
1460
2809
  }))
@@ -1465,7 +2814,7 @@ function useBaseERC20Token() {
1465
2814
  const t = normalizedTokens[idx];
1466
2815
  if (r.status === "success") {
1467
2816
  const raw = r.result;
1468
- if (raw > 0n) acc.push({ ...t, raw, formatted: (0, import_viem4.formatUnits)(raw, t.decimals) });
2817
+ if (raw > 0n) acc.push({ ...t, raw, formatted: (0, import_viem5.formatUnits)(raw, t.decimals) });
1469
2818
  }
1470
2819
  }
1471
2820
  if (!cancelled) setRows(acc);
@@ -1506,9 +2855,9 @@ function useBaseNativeToken() {
1506
2855
  }
1507
2856
 
1508
2857
  // src/modals/CryptoSelectModal.tsx
1509
- var import_jsx_runtime19 = require("react/jsx-runtime");
1510
- var CryptoSelectModal = import_nice_modal_react3.default.create(() => {
1511
- const modal = (0, import_nice_modal_react3.useModal)();
2858
+ var import_jsx_runtime31 = require("react/jsx-runtime");
2859
+ var CryptoSelectModal = import_nice_modal_react4.default.create(() => {
2860
+ const modal = (0, import_nice_modal_react4.useModal)();
1512
2861
  const { isLoading, error, erc20Balances } = useBaseERC20Token();
1513
2862
  const { isLoadingNative, nativeError, nativeBalance } = useBaseNativeToken();
1514
2863
  const { setSelectedPaymentMethod } = useSpreePaymentMethod();
@@ -1516,13 +2865,13 @@ var CryptoSelectModal = import_nice_modal_react3.default.create(() => {
1516
2865
  modal.remove();
1517
2866
  setSelectedPaymentMethod({ type: "CRYPTO" /* CRYPTO */, method: coin });
1518
2867
  };
1519
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Dialog, { open: modal.visible, onOpenChange: modal.remove, children: [
1520
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DialogDescription, { className: "hidden", children: "Crypto Select Modal" }),
1521
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(DialogContent, { showCloseButton: false, className: "gap-0 p-0", children: [
1522
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex flex-col gap-6 px-5 py-5 md:px-7 md:py-6", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center justify-between gap-4", children: [
1523
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { className: "rounded-md hover:bg-gray-100", onClick: modal.remove, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "25", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("path", { stroke: "#000", d: "m15 6.5-6 6 6 6" }) }) }),
1524
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DialogTitle, { className: "text-primary text-2xl font-semibold", children: "Select a token" }),
1525
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { className: "rounded-md p-1 hover:bg-gray-100", onClick: modal.remove, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "17", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2868
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(Dialog, { open: modal.visible, onOpenChange: modal.remove, children: [
2869
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(DialogDescription, { className: "hidden", children: "Crypto Select Modal" }),
2870
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(DialogContent, { showCloseButton: false, className: "gap-0 p-0", children: [
2871
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "flex flex-col gap-6 px-5 py-5 md:px-7 md:py-6", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex items-center justify-between gap-4", children: [
2872
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("button", { className: "rounded-md hover:bg-gray-100", onClick: modal.remove, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "25", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("path", { stroke: "#000", d: "m15 6.5-6 6 6 6" }) }) }),
2873
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(DialogTitle, { className: "text-primary text-2xl font-semibold", children: "Select a token" }),
2874
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("button", { className: "rounded-md p-1 hover:bg-gray-100", onClick: modal.remove, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "17", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1526
2875
  "path",
1527
2876
  {
1528
2877
  fill: "#000",
@@ -1530,19 +2879,19 @@ var CryptoSelectModal = import_nice_modal_react3.default.create(() => {
1530
2879
  }
1531
2880
  ) }) })
1532
2881
  ] }) }),
1533
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-4 px-5 py-5 md:px-7 md:py-6", children: [
1534
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h3", { className: "text-primary text-xl font-semibold", children: "Tokens with wallet balance" }),
1535
- (error || nativeError) && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-center text-sm text-red-500", children: "Something wrong" }),
1536
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex w-full flex-col gap-1", children: [
1537
- isLoadingNative && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "h-11 animate-pulse rounded-md bg-gray-100" }),
1538
- nativeBalance && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2882
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex flex-col gap-4 px-5 py-5 md:px-7 md:py-6", children: [
2883
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("h3", { className: "text-primary text-xl font-semibold", children: "Tokens with wallet balance" }),
2884
+ (error || nativeError) && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { className: "text-center text-sm text-red-500", children: "Something wrong" }),
2885
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex w-full flex-col gap-1", children: [
2886
+ isLoadingNative && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "h-11 animate-pulse rounded-md bg-gray-100" }),
2887
+ nativeBalance && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
1539
2888
  "button",
1540
2889
  {
1541
2890
  className: "flex h-11 w-full items-center justify-between gap-4 rounded-sm px-1.5 text-black hover:bg-gray-100",
1542
2891
  onClick: () => handleSelect(nativeBalance),
1543
2892
  children: [
1544
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-2", children: [
1545
- nativeBalance.logoURI && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2893
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex items-center gap-2", children: [
2894
+ nativeBalance.logoURI && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1546
2895
  "img",
1547
2896
  {
1548
2897
  className: "h-8 w-8 shrink-0",
@@ -1550,31 +2899,31 @@ var CryptoSelectModal = import_nice_modal_react3.default.create(() => {
1550
2899
  alt: `${nativeBalance.symbol} logo`
1551
2900
  }
1552
2901
  ),
1553
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-sm font-medium", children: nativeBalance.symbol })
2902
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { className: "text-sm font-medium", children: nativeBalance.symbol })
1554
2903
  ] }),
1555
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-sm font-medium", children: nativeBalance.formatted })
2904
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { className: "text-sm font-medium", children: nativeBalance.formatted })
1556
2905
  ]
1557
2906
  },
1558
2907
  nativeBalance.symbol
1559
2908
  ),
1560
- isLoading && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
1561
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "h-11 animate-pulse rounded-md bg-gray-100" }),
1562
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "h-11 animate-pulse rounded-md bg-gray-100" }),
1563
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "h-11 animate-pulse rounded-md bg-gray-100" })
2909
+ isLoading && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_jsx_runtime31.Fragment, { children: [
2910
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "h-11 animate-pulse rounded-md bg-gray-100" }),
2911
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "h-11 animate-pulse rounded-md bg-gray-100" }),
2912
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "h-11 animate-pulse rounded-md bg-gray-100" })
1564
2913
  ] }),
1565
2914
  erc20Balances.map((coin) => {
1566
2915
  const Icon = getSymbolLogo(coin.symbol);
1567
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2916
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
1568
2917
  "button",
1569
2918
  {
1570
2919
  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",
1571
2920
  onClick: () => handleSelect(coin),
1572
2921
  children: [
1573
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-2", children: [
2922
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex items-center gap-2", children: [
1574
2923
  Boolean(Icon) && Icon,
1575
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-sm font-medium", children: coin.symbol })
2924
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { className: "text-sm font-medium", children: coin.symbol })
1576
2925
  ] }),
1577
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-sm font-medium", children: coin.formatted })
2926
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { className: "text-sm font-medium", children: coin.formatted })
1578
2927
  ]
1579
2928
  },
1580
2929
  coin.symbol
@@ -1588,51 +2937,51 @@ var CryptoSelectModal = import_nice_modal_react3.default.create(() => {
1588
2937
  CryptoSelectModal.displayName = "CryptoSelectModal";
1589
2938
 
1590
2939
  // src/components/CryptoTab/Crypto/SelectCoinButton.tsx
1591
- var import_jsx_runtime20 = require("react/jsx-runtime");
2940
+ var import_jsx_runtime32 = require("react/jsx-runtime");
1592
2941
  var SelectCoinButton = () => {
1593
2942
  const openModal = () => {
1594
- import_nice_modal_react4.default.show(CryptoSelectModal);
2943
+ import_nice_modal_react5.default.show(CryptoSelectModal);
1595
2944
  };
1596
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("button", { onClick: openModal, type: "button", className: "bg-primary/8 flex h-11 w-full overflow-hidden rounded-md", children: [
1597
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "bg-primary flex h-full w-11 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-white" }) }),
1598
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex h-full w-full items-center justify-between px-3", children: [
1599
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "font-medium text-black/50", children: "Select a token" }) }),
1600
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("path", { stroke: "#000", strokeLinecap: "round", d: "m6 12.43 4-4-4-4" }) })
2945
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("button", { onClick: openModal, type: "button", className: "bg-primary/8 flex h-11 w-full overflow-hidden rounded-md", children: [
2946
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "bg-primary flex h-full w-11 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-white" }) }),
2947
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex h-full w-full items-center justify-between px-3", children: [
2948
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { className: "font-medium text-black/50", children: "Select a token" }) }),
2949
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("path", { stroke: "#000", strokeLinecap: "round", d: "m6 12.43 4-4-4-4" }) })
1601
2950
  ] })
1602
2951
  ] });
1603
2952
  };
1604
2953
 
1605
2954
  // src/components/CryptoTab/Crypto/SelectedCoin.tsx
1606
- var import_jsx_runtime21 = require("react/jsx-runtime");
2955
+ var import_jsx_runtime33 = require("react/jsx-runtime");
1607
2956
  var SelectedCoin = (props) => {
1608
2957
  const { coin, balance, logoURI } = props;
1609
2958
  const Icon = getSymbolLogo(coin);
1610
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "bg-primary/8 flex h-11 w-full overflow-hidden rounded-md", children: [
1611
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "bg-primary flex h-full w-11 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-white", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "bg-primary h-2.5 w-2.5 rounded-full" }) }) }),
1612
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "border-primary flex h-full w-full items-center justify-between rounded-r-md border-1 !border-l-0 px-3", children: [
1613
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-1", children: [
2959
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "bg-primary/8 flex h-11 w-full overflow-hidden rounded-md", children: [
2960
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "bg-primary flex h-full w-11 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-white", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "bg-primary h-2.5 w-2.5 rounded-full" }) }) }),
2961
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "border-primary flex h-full w-full items-center justify-between rounded-r-md border-1 !border-l-0 px-3", children: [
2962
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex items-center gap-1", children: [
1614
2963
  Icon,
1615
- !Icon && logoURI && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("img", { className: "mr-1 h-8 w-8 shrink-0", src: logoURI, alt: `${coin} logo` }),
1616
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "font-semibold text-black", children: coin }),
1617
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("path", { d: "M6 12.4341L10 8.43408L6 4.43408", stroke: "black", strokeLinecap: "round" }) })
2964
+ !Icon && logoURI && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("img", { className: "mr-1 h-8 w-8 shrink-0", src: logoURI, alt: `${coin} logo` }),
2965
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { className: "font-semibold text-black", children: coin }),
2966
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("path", { d: "M6 12.4341L10 8.43408L6 4.43408", stroke: "black", strokeLinecap: "round" }) })
1618
2967
  ] }),
1619
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("p", { className: "text-xs font-medium text-black/50", children: [
2968
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("p", { className: "text-xs font-medium text-black/50", children: [
1620
2969
  "Wallet balance ",
1621
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-black", children: balance })
2970
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-black", children: balance })
1622
2971
  ] })
1623
2972
  ] })
1624
2973
  ] });
1625
2974
  };
1626
2975
 
1627
2976
  // src/components/CryptoTab/Crypto/Crypto.tsx
1628
- var import_jsx_runtime22 = require("react/jsx-runtime");
2977
+ var import_jsx_runtime34 = require("react/jsx-runtime");
1629
2978
  var Crypto = () => {
1630
2979
  const { address } = (0, import_wagmi4.useAccount)();
1631
2980
  const { selectedPaymentMethod } = useSpreePaymentMethod();
1632
2981
  const { cryptoPayment } = useCryptoPayment();
1633
2982
  const isWalletConnected = Boolean(address);
1634
2983
  const { register } = useSpreePayRegister();
1635
- const handlePay = (0, import_react8.useCallback)(
2984
+ const handlePay = (0, import_react14.useCallback)(
1636
2985
  async (data) => {
1637
2986
  try {
1638
2987
  const res = await cryptoPayment(data);
@@ -1646,17 +2995,17 @@ var Crypto = () => {
1646
2995
  },
1647
2996
  [cryptoPayment]
1648
2997
  );
1649
- (0, import_react8.useEffect)(() => {
2998
+ (0, import_react14.useEffect)(() => {
1650
2999
  register(handlePay);
1651
3000
  }, [register, handlePay]);
1652
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex flex-col items-baseline gap-4", children: [
1653
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex w-full items-center justify-between gap-4", children: [
1654
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { className: "text-primary text-xl leading-[1.7] font-semibold", children: "Pay with Crypto" }),
1655
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ConnectButton, {})
3001
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex flex-col items-baseline gap-4", children: [
3002
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex w-full items-center justify-between gap-4", children: [
3003
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("h3", { className: "text-primary text-xl leading-[1.7] font-semibold", children: "Pay with Crypto" }),
3004
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ConnectButton, {})
1656
3005
  ] }),
1657
- !isWalletConnected && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Logos, {}),
1658
- isWalletConnected && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex w-full flex-col gap-1", children: [
1659
- selectedPaymentMethod.type === "CRYPTO" /* CRYPTO */ && selectedPaymentMethod.method && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3006
+ !isWalletConnected && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Logos, {}),
3007
+ isWalletConnected && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex w-full flex-col gap-1", children: [
3008
+ selectedPaymentMethod.type === "CRYPTO" /* CRYPTO */ && selectedPaymentMethod.method && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
1660
3009
  SelectedCoin,
1661
3010
  {
1662
3011
  coin: selectedPaymentMethod.method.symbol,
@@ -1664,13 +3013,13 @@ var Crypto = () => {
1664
3013
  logoURI: selectedPaymentMethod.method.logoURI
1665
3014
  }
1666
3015
  ),
1667
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SelectCoinButton, {})
3016
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(SelectCoinButton, {})
1668
3017
  ] })
1669
3018
  ] });
1670
3019
  };
1671
3020
 
1672
3021
  // src/components/CryptoTab/Crypto/CryptoWrapper.tsx
1673
- var import_jsx_runtime23 = require("react/jsx-runtime");
3022
+ var import_jsx_runtime35 = require("react/jsx-runtime");
1674
3023
  var queryClient = new import_react_query.QueryClient();
1675
3024
  var connectors = (0, import_rainbowkit2.connectorsForWallets)(
1676
3025
  [
@@ -1688,29 +3037,30 @@ var config = (0, import_wagmi5.createConfig)({
1688
3037
  ssr: true
1689
3038
  });
1690
3039
  var CryptoWrapper = () => {
1691
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_wagmi5.WagmiProvider, { config, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_query.QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_rainbowkit2.RainbowKitProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_nice_modal_react5.default.Provider, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Crypto, {}) }) }) }) });
3040
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_wagmi5.WagmiProvider, { config, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react_query.QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_rainbowkit2.RainbowKitProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_nice_modal_react6.default.Provider, { children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Crypto, {}) }) }) }) });
1692
3041
  };
1693
3042
 
1694
3043
  // src/components/CryptoTab/CryptoTab.tsx
1695
- var import_jsx_runtime24 = require("react/jsx-runtime");
1696
- var CryptoTab = (props) => {
1697
- const { pointsTitle, pointsConversionRatio } = props;
1698
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { children: [
1699
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "border-b-1 border-black/7 px-5 py-5 md:px-7 md:py-5", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CryptoWrapper, {}) }),
1700
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "px-5 py-5 md:px-7 md:py-6", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PointsSwitch, { disabled: true, pointsTitle, pointsConversionRatio }) })
3044
+ var import_jsx_runtime36 = require("react/jsx-runtime");
3045
+ var CryptoTab = () => {
3046
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { children: [
3047
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "border-b-1 border-black/7 px-5 py-5 md:px-7 md:py-5", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(CryptoWrapper, {}) }),
3048
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "px-5 py-5 md:px-7 md:py-6", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(PointsSwitch, { disabled: true }) })
1701
3049
  ] });
1702
3050
  };
1703
3051
 
1704
3052
  // src/components/TabButtons.tsx
1705
- var import_jsx_runtime25 = require("react/jsx-runtime");
1706
- var TabButton = ({ isActive, children, onClick }) => {
1707
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3053
+ var import_jsx_runtime37 = require("react/jsx-runtime");
3054
+ var TabButton = ({ isDisabled = true, isActive, children, onClick }) => {
3055
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
1708
3056
  "button",
1709
3057
  {
3058
+ disabled: isDisabled,
1710
3059
  onClick,
1711
3060
  className: cn(
1712
3061
  "flex w-[132px] flex-col items-baseline rounded-sm border-1 border-black/50 px-2.5 py-1.5 text-sm text-black",
1713
- { "opacity-50": !isActive },
3062
+ { "opacity-50": !isActive || isDisabled },
3063
+ { "cursor-not-allowed": isDisabled },
1714
3064
  { "bg-primary/7 border-primary text-primary": isActive }
1715
3065
  ),
1716
3066
  children
@@ -1719,84 +3069,99 @@ var TabButton = ({ isActive, children, onClick }) => {
1719
3069
  };
1720
3070
  var TabButtons = (props) => {
1721
3071
  const { value, onChange } = props;
3072
+ const { spreePayConfig } = useSpreePayConfig();
1722
3073
  const handleChange = (type) => () => {
1723
3074
  if (value !== type) {
1724
3075
  onChange({ type, method: null });
1725
3076
  }
1726
3077
  };
1727
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex gap-2", children: [
1728
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(TabButton, { onClick: handleChange("CREDIT_CARD" /* CREDIT_CARD */), isActive: value === "CREDIT_CARD" /* CREDIT_CARD */, children: [
1729
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1730
- "path",
1731
- {
1732
- fill: "currentColor",
1733
- 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"
1734
- }
1735
- ) }),
1736
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-sm font-medium", children: "Card" })
1737
- ] }),
1738
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(TabButton, { onClick: handleChange("CRYPTO" /* CRYPTO */), isActive: value === "CRYPTO" /* CRYPTO */, children: [
1739
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("svg", { className: "my-1", xmlns: "http://www.w3.org/2000/svg", width: "30", height: "16", fill: "none", children: [
1740
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1741
- "path",
1742
- {
1743
- fill: "currentColor",
1744
- 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"
1745
- }
1746
- ),
1747
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1748
- "path",
1749
- {
1750
- fill: "currentColor",
1751
- 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"
1752
- }
1753
- ),
1754
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("circle", { cx: "8", cy: "8", r: "7", stroke: "currentColor", strokeWidth: "2" })
1755
- ] }),
1756
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-sm font-medium", children: "Crypto" })
1757
- ] })
3078
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex gap-2", children: [
3079
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
3080
+ TabButton,
3081
+ {
3082
+ isDisabled: !spreePayConfig?.creditCard.enabled,
3083
+ onClick: handleChange("CREDIT_CARD" /* CREDIT_CARD */),
3084
+ isActive: value === "CREDIT_CARD" /* CREDIT_CARD */,
3085
+ children: [
3086
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
3087
+ "path",
3088
+ {
3089
+ fill: "currentColor",
3090
+ 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"
3091
+ }
3092
+ ) }),
3093
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: "text-sm font-medium", children: "Card" })
3094
+ ]
3095
+ }
3096
+ ),
3097
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
3098
+ TabButton,
3099
+ {
3100
+ isDisabled: !spreePayConfig?.creditCard.enabled,
3101
+ onClick: handleChange("CRYPTO" /* CRYPTO */),
3102
+ isActive: value === "CRYPTO" /* CRYPTO */,
3103
+ children: [
3104
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("svg", { className: "my-1", xmlns: "http://www.w3.org/2000/svg", width: "30", height: "16", fill: "none", children: [
3105
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
3106
+ "path",
3107
+ {
3108
+ fill: "currentColor",
3109
+ 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"
3110
+ }
3111
+ ),
3112
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
3113
+ "path",
3114
+ {
3115
+ fill: "currentColor",
3116
+ 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"
3117
+ }
3118
+ ),
3119
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("circle", { cx: "8", cy: "8", r: "7", stroke: "currentColor", strokeWidth: "2" })
3120
+ ] }),
3121
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: "text-sm font-medium", children: "Crypto" })
3122
+ ]
3123
+ }
3124
+ )
1758
3125
  ] });
1759
3126
  };
1760
3127
 
1761
3128
  // src/components/Tabs.tsx
1762
- var import_jsx_runtime26 = require("react/jsx-runtime");
1763
- var Tabs = ({ config: config2 }) => {
3129
+ var import_jsx_runtime38 = require("react/jsx-runtime");
3130
+ var Tabs = () => {
1764
3131
  const { selectedPaymentMethod, setSelectedPaymentMethod } = useSpreePaymentMethod();
1765
- const { pointsConversionRatio, pointsTitle } = config2;
1766
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "mb-4 rounded-3xl border border-black/25 bg-white", children: [
1767
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("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: [
1768
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h2", { className: "text-primary text-2xl font-semibold", children: "Choose a Payment Method" }),
1769
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(TabButtons, { value: selectedPaymentMethod.type, onChange: setSelectedPaymentMethod })
3132
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "mb-4 rounded-3xl border border-black/25 bg-white", children: [
3133
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("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: [
3134
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("h2", { className: "text-primary text-2xl font-semibold", children: "Choose a Payment Method" }),
3135
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(TabButtons, { value: selectedPaymentMethod.type, onChange: setSelectedPaymentMethod })
1770
3136
  ] }),
1771
- selectedPaymentMethod.type === "CREDIT_CARD" /* CREDIT_CARD */ && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(CreditCardTab, { pointsTitle, pointsConversionRatio }),
1772
- selectedPaymentMethod.type === "CRYPTO" /* CRYPTO */ && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(CryptoTab, { pointsTitle, pointsConversionRatio })
3137
+ selectedPaymentMethod.type === "CREDIT_CARD" /* CREDIT_CARD */ && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(CreditCardTab, {}),
3138
+ selectedPaymentMethod.type === "CRYPTO" /* CRYPTO */ && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(CryptoTab, {})
1773
3139
  ] });
1774
3140
  };
1775
3141
 
1776
3142
  // src/SpreePayContent.tsx
1777
- var import_jsx_runtime27 = require("react/jsx-runtime");
1778
- var SpreePayContent = (props) => {
1779
- const { isLoggedIn, config: config2, amount, onProcess, isProcessing } = props;
1780
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "w-full", children: [
1781
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Tabs, { config: config2 }),
1782
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(CheckoutButton, { isLoggedIn, isProcessing, onCheckout: onProcess, amount }),
1783
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(SpreeLegal, {})
3143
+ var import_jsx_runtime39 = require("react/jsx-runtime");
3144
+ var SpreePayContent = ({ isLoggedIn }) => {
3145
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "w-full", children: [
3146
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Tabs, {}),
3147
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(CheckoutButton, { isLoggedIn }),
3148
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(SpreeLegal, {})
1784
3149
  ] });
1785
3150
  };
1786
3151
 
1787
3152
  // src/hooks/useKeycloakSSO.ts
1788
- var import_react9 = require("react");
3153
+ var import_react15 = require("react");
1789
3154
  var import_keycloak_js = __toESM(require("keycloak-js"), 1);
1790
3155
  var refreshAheadSeconds = 60;
1791
3156
  function useKeycloakSSO(config2) {
1792
3157
  const { url, realm, clientId, ssoPageURI, enabled } = config2;
1793
- const initRef = (0, import_react9.useRef)(false);
1794
- const kcRef = (0, import_react9.useRef)(null);
1795
- const refreshTimerRef = (0, import_react9.useRef)(null);
1796
- const [error, setError] = (0, import_react9.useState)(null);
1797
- const [isChecking, setIsChecking] = (0, import_react9.useState)(enabled);
1798
- const [accessToken, setAccessToken] = (0, import_react9.useState)(null);
1799
- const scheduleRefresh = (0, import_react9.useCallback)(() => {
3158
+ const initRef = (0, import_react15.useRef)(false);
3159
+ const kcRef = (0, import_react15.useRef)(null);
3160
+ const refreshTimerRef = (0, import_react15.useRef)(null);
3161
+ const [error, setError] = (0, import_react15.useState)(null);
3162
+ const [isChecking, setIsChecking] = (0, import_react15.useState)(enabled);
3163
+ const [accessToken, setAccessToken] = (0, import_react15.useState)(null);
3164
+ const scheduleRefresh = (0, import_react15.useCallback)(() => {
1800
3165
  const kc = kcRef.current;
1801
3166
  if (!kc || !kc.tokenParsed || !kc.tokenParsed.exp) {
1802
3167
  return;
@@ -1817,7 +3182,7 @@ function useKeycloakSSO(config2) {
1817
3182
  });
1818
3183
  }, delayMs);
1819
3184
  }, []);
1820
- (0, import_react9.useEffect)(() => {
3185
+ (0, import_react15.useEffect)(() => {
1821
3186
  if (initRef.current || !enabled) return;
1822
3187
  initRef.current = true;
1823
3188
  setIsChecking(true);
@@ -1852,94 +3217,43 @@ function useKeycloakSSO(config2) {
1852
3217
  }
1853
3218
 
1854
3219
  // src/SpreePay.tsx
1855
- var import_jsx_runtime28 = require("react/jsx-runtime");
1856
- var CONFIG = {
1857
- dev: {
1858
- bookit: {
1859
- slapiUrl: "https://slapi.dev.superlogic.com",
1860
- keyklockUrl: "https://auth.dev.join.bookit.com",
1861
- keyklockClientId: "oneof-next",
1862
- pointsConversionRatio: 100,
1863
- pointsTitle: "AIR SP"
1864
- },
1865
- moca: {
1866
- slapiUrl: "https://slapi.dev.air.shop",
1867
- keyklockUrl: "https://login.dev.air.shop",
1868
- keyklockClientId: "oneof-next",
1869
- pointsConversionRatio: 100,
1870
- pointsTitle: "AIR SP"
1871
- }
1872
- },
1873
- stg: {
1874
- bookit: {
1875
- slapiUrl: "https://slapi.stg.superlogic.com",
1876
- keyklockUrl: "https://auth.stg.join.bookit.com",
1877
- keyklockClientId: "oneof-next",
1878
- pointsConversionRatio: 100,
1879
- pointsTitle: "AIR SP"
1880
- },
1881
- moca: {
1882
- slapiUrl: "https://slapi.stg.air.shop",
1883
- keyklockUrl: "https://login.stg.air.shop",
1884
- keyklockClientId: "oneof-next",
1885
- pointsConversionRatio: 100,
1886
- pointsTitle: "AIR SP"
1887
- }
1888
- },
1889
- prod: {
1890
- bookit: {
1891
- slapiUrl: "https://slapi.superlogic.com",
1892
- keyklockUrl: "https://auth.join.bookit.com",
1893
- keyklockClientId: "oneof-next",
1894
- pointsConversionRatio: 100,
1895
- pointsTitle: "AIR SP"
1896
- },
1897
- moca: {
1898
- slapiUrl: "https://slapi.air.shop",
1899
- keyklockUrl: "https://login.air.shop",
1900
- keyklockClientId: "oneof-next",
1901
- pointsConversionRatio: 100,
1902
- pointsTitle: "AIR SP"
1903
- }
1904
- }
1905
- };
1906
- var SpreePay = ({ className, ...rest }) => {
1907
- const rootRef = (0, import_react10.useRef)(null);
1908
- const [portalEl, setPortalEl] = (0, import_react10.useState)(null);
1909
- (0, import_react10.useLayoutEffect)(() => {
3220
+ var import_jsx_runtime40 = require("react/jsx-runtime");
3221
+ var SpreePayInner = () => {
3222
+ const rootRef = (0, import_react16.useRef)(null);
3223
+ const [portalEl, setPortalEl] = (0, import_react16.useState)(null);
3224
+ (0, import_react16.useLayoutEffect)(() => {
1910
3225
  if (!rootRef.current) return;
1911
3226
  const el = rootRef.current.querySelector(":scope > .sl-spreepay__portal");
1912
3227
  setPortalEl(el ?? null);
1913
3228
  }, []);
1914
3229
  const { env } = useSpreePayEnv();
1915
- const environment = env?.environment || "dev";
3230
+ const { staticConfig, appProps } = useStaticConfig();
1916
3231
  const tenantId = env?.tenantId || "bookit";
1917
- const config2 = CONFIG[environment]?.[tenantId];
1918
3232
  const { isChecking, accessToken } = useKeycloakSSO({
1919
3233
  realm: tenantId,
1920
- url: config2.keyklockUrl,
1921
- clientId: config2.keyklockClientId,
3234
+ url: staticConfig.keyklockUrl,
3235
+ clientId: staticConfig.keyklockClientId,
1922
3236
  ssoPageURI: env?.ssoPageURI,
1923
3237
  enabled: !env?.accessToken
1924
3238
  });
1925
- const slapiFetcher = (0, import_react10.useMemo)(() => {
3239
+ const slapiFetcher = (0, import_react16.useMemo)(() => {
1926
3240
  if (accessToken || env.accessToken) {
1927
3241
  return registerApi({
1928
3242
  accessToken: env.accessToken || accessToken,
1929
3243
  tenantId,
1930
- baseUrl: config2.slapiUrl
3244
+ baseUrl: staticConfig.slapiUrl
1931
3245
  });
1932
3246
  }
1933
- }, [env.accessToken, config2, tenantId, accessToken]);
3247
+ }, [env.accessToken, staticConfig, tenantId, accessToken]);
1934
3248
  const getContent = () => {
1935
3249
  if (isChecking) {
1936
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex w-full flex-col", children: [
1937
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "bg-primary/8 mb-4 h-[315px] animate-pulse rounded-3xl" }),
1938
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "bg-primary/8 h-[135px] animate-pulse rounded-3xl" }),
1939
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SpreeLegal, {})
3250
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex w-full flex-col", children: [
3251
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "bg-primary/8 mb-4 h-[315px] animate-pulse rounded-3xl" }),
3252
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "bg-primary/8 h-[135px] animate-pulse rounded-3xl" }),
3253
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(SpreeLegal, {})
1940
3254
  ] });
1941
3255
  }
1942
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3256
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
1943
3257
  import_swr4.SWRConfig,
1944
3258
  {
1945
3259
  value: {
@@ -1948,20 +3262,23 @@ var SpreePay = ({ className, ...rest }) => {
1948
3262
  revalidateOnFocus: false,
1949
3263
  revalidateIfStale: false
1950
3264
  },
1951
- children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(PortalContainerProvider, { container: portalEl, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_nice_modal_react6.default.Provider, { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SpreePayContent, { isLoggedIn: Boolean(accessToken || env.accessToken), config: config2, ...rest }) }) })
3265
+ children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(PortalContainerProvider, { container: portalEl, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_nice_modal_react7.default.Provider, { children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(SpreePayContent, { isLoggedIn: Boolean(accessToken || env.accessToken) }) }) })
1952
3266
  }
1953
3267
  );
1954
3268
  };
1955
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { ref: rootRef, className: cn("sl-spreepay", className), children: [
1956
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "sl-spreepay__portal" }),
3269
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { ref: rootRef, className: cn("sl-spreepay", appProps.className), children: [
3270
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "sl-spreepay__portal" }),
1957
3271
  getContent()
1958
3272
  ] });
1959
3273
  };
3274
+ var SpreePay = (props) => {
3275
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(StaticConfigProvider, { props, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(SpreePayInner, {}) });
3276
+ };
1960
3277
 
1961
3278
  // src/hooks/useCapture3DS.ts
1962
- var import_react11 = require("react");
3279
+ var import_react17 = require("react");
1963
3280
  var useCapture3DS = (searchParams) => {
1964
- (0, import_react11.useEffect)(() => {
3281
+ (0, import_react17.useEffect)(() => {
1965
3282
  if (window?.parent && searchParams?.paymentIntent) {
1966
3283
  window.parent.SP_EVENT_BUS?.emit("paymentIntent", { paymentIntent: searchParams.paymentIntent });
1967
3284
  }