@cimplify/sdk 0.8.6 → 0.8.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/advanced.d.mts +2 -2
- package/dist/advanced.d.ts +2 -2
- package/dist/{client-6MsOWo8f.d.mts → client-D1rHAIZY.d.mts} +1 -1
- package/dist/{client-CVJ0S99a.d.ts → client-Dklt51q-.d.ts} +1 -1
- package/dist/{index-mrKi_VbR.d.mts → index-DKLWJwJd.d.mts} +1 -1
- package/dist/{index-B_JHO-ER.d.ts → index-DQp1xkcl.d.ts} +1 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +54 -0
- package/dist/index.mjs +54 -1
- package/dist/{payment-CLIWNMaP.d.mts → payment-BKjX2fAs.d.mts} +2 -1
- package/dist/{payment-CLIWNMaP.d.ts → payment-BKjX2fAs.d.ts} +2 -1
- package/dist/react.d.mts +29 -3
- package/dist/react.d.ts +29 -3
- package/dist/react.js +859 -603
- package/dist/react.mjs +681 -426
- package/dist/utils.d.mts +2 -2
- package/dist/utils.d.ts +2 -2
- package/package.json +1 -1
package/dist/react.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var React3 = require('react');
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
|
|
6
6
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
7
|
|
|
8
|
-
var
|
|
8
|
+
var React3__default = /*#__PURE__*/_interopDefault(React3);
|
|
9
9
|
|
|
10
10
|
// src/react/index.tsx
|
|
11
11
|
|
|
@@ -201,7 +201,7 @@ function deriveAdsApiUrl() {
|
|
|
201
201
|
}
|
|
202
202
|
return "https://api.cimplify.io";
|
|
203
203
|
}
|
|
204
|
-
var AdContext =
|
|
204
|
+
var AdContext = React3.createContext({
|
|
205
205
|
siteId: null,
|
|
206
206
|
config: null,
|
|
207
207
|
isLoading: true,
|
|
@@ -209,7 +209,7 @@ var AdContext = React2.createContext({
|
|
|
209
209
|
apiBase: "https://api.cimplify.io"
|
|
210
210
|
});
|
|
211
211
|
function useAds() {
|
|
212
|
-
return
|
|
212
|
+
return React3.useContext(AdContext);
|
|
213
213
|
}
|
|
214
214
|
function AdProvider({
|
|
215
215
|
siteId,
|
|
@@ -218,10 +218,10 @@ function AdProvider({
|
|
|
218
218
|
children
|
|
219
219
|
}) {
|
|
220
220
|
const resolvedApiBase = apiBase || deriveAdsApiUrl();
|
|
221
|
-
const [config, setConfig] =
|
|
222
|
-
const [isLoading, setIsLoading] =
|
|
223
|
-
const [identity, setIdentity] =
|
|
224
|
-
|
|
221
|
+
const [config, setConfig] = React3.useState(null);
|
|
222
|
+
const [isLoading, setIsLoading] = React3.useState(true);
|
|
223
|
+
const [identity, setIdentity] = React3.useState(null);
|
|
224
|
+
React3.useEffect(() => {
|
|
225
225
|
const userIdentity = getUserIdentity(authenticatedAccountId);
|
|
226
226
|
setIdentity(userIdentity);
|
|
227
227
|
fetch(`${resolvedApiBase}/ads/config/${siteId}`).then((r) => r.json()).then((data) => {
|
|
@@ -244,11 +244,11 @@ function Ad({
|
|
|
244
244
|
onClick
|
|
245
245
|
}) {
|
|
246
246
|
const { siteId, config, isLoading, identity, apiBase } = useAds();
|
|
247
|
-
const [ad, setAd] =
|
|
248
|
-
const [error, setError] =
|
|
249
|
-
const impressionTracked =
|
|
250
|
-
const containerRef =
|
|
251
|
-
|
|
247
|
+
const [ad, setAd] = React3.useState(null);
|
|
248
|
+
const [error, setError] = React3.useState(false);
|
|
249
|
+
const impressionTracked = React3.useRef(false);
|
|
250
|
+
const containerRef = React3.useRef(null);
|
|
251
|
+
React3.useEffect(() => {
|
|
252
252
|
if (isLoading || !config?.enabled || !siteId || !identity) return;
|
|
253
253
|
const path = typeof window !== "undefined" ? window.location.pathname : "/";
|
|
254
254
|
const referrer = typeof document !== "undefined" ? document.referrer : "";
|
|
@@ -291,7 +291,7 @@ function Ad({
|
|
|
291
291
|
}
|
|
292
292
|
}).catch(() => setError(true));
|
|
293
293
|
}, [siteId, config, isLoading, slot, identity, apiBase]);
|
|
294
|
-
|
|
294
|
+
React3.useEffect(() => {
|
|
295
295
|
if (!ad || impressionTracked.current || typeof window === "undefined" || !identity) return;
|
|
296
296
|
const observer = new IntersectionObserver(
|
|
297
297
|
([entry]) => {
|
|
@@ -368,12 +368,13 @@ function getSelections(item) {
|
|
|
368
368
|
}
|
|
369
369
|
return void 0;
|
|
370
370
|
}
|
|
371
|
-
function mapItem(item) {
|
|
371
|
+
function mapItem(item, fx) {
|
|
372
|
+
const amt = (value) => fx ? String(fx.convertPrice(value)) : String(value);
|
|
372
373
|
const result = {
|
|
373
374
|
name: item.name,
|
|
374
375
|
quantity: item.quantity,
|
|
375
|
-
unit_price:
|
|
376
|
-
total_price:
|
|
376
|
+
unit_price: amt(item.base_price),
|
|
377
|
+
total_price: amt(item.total_price),
|
|
377
378
|
line_type: item.line_type
|
|
378
379
|
};
|
|
379
380
|
if (item.image_url) result.image_url = item.image_url;
|
|
@@ -386,7 +387,7 @@ function mapItem(item) {
|
|
|
386
387
|
if (item.add_on_options?.length) {
|
|
387
388
|
result.add_ons = item.add_on_options.map((opt) => ({
|
|
388
389
|
name: opt.name,
|
|
389
|
-
price:
|
|
390
|
+
price: amt(opt.price ?? "0")
|
|
390
391
|
}));
|
|
391
392
|
}
|
|
392
393
|
if (item.special_instructions) {
|
|
@@ -394,359 +395,18 @@ function mapItem(item) {
|
|
|
394
395
|
}
|
|
395
396
|
return result;
|
|
396
397
|
}
|
|
397
|
-
function transformToCheckoutCart(cart) {
|
|
398
|
+
function transformToCheckoutCart(cart, fx) {
|
|
399
|
+
const amt = (value) => fx ? String(fx.convertPrice(value)) : String(value);
|
|
398
400
|
return {
|
|
399
|
-
items: cart.items.map(mapItem),
|
|
400
|
-
subtotal:
|
|
401
|
-
tax_amount:
|
|
402
|
-
total_discounts:
|
|
403
|
-
service_charge:
|
|
404
|
-
total:
|
|
405
|
-
currency: cart.pricing.currency
|
|
401
|
+
items: cart.items.map((item) => mapItem(item, fx)),
|
|
402
|
+
subtotal: amt(cart.pricing.subtotal),
|
|
403
|
+
tax_amount: amt(cart.pricing.tax_amount),
|
|
404
|
+
total_discounts: amt(cart.pricing.total_discounts),
|
|
405
|
+
service_charge: amt(cart.pricing.service_charge),
|
|
406
|
+
total: amt(cart.pricing.total_price),
|
|
407
|
+
currency: fx?.displayCurrency ?? cart.pricing.currency
|
|
406
408
|
};
|
|
407
409
|
}
|
|
408
|
-
var SPACE = { sm: 8};
|
|
409
|
-
function shellColors(isDark, primaryColor) {
|
|
410
|
-
return {
|
|
411
|
-
text: isDark ? "#f4f4f5" : "#1a1a1a",
|
|
412
|
-
textSecondary: isDark ? "#a1a1aa" : "#52525b",
|
|
413
|
-
textMuted: isDark ? "#71717a" : "#a1a1aa",
|
|
414
|
-
border: isDark ? "#27272a" : "#e4e4e7",
|
|
415
|
-
surface: isDark ? "#18181b" : "#fafafa",
|
|
416
|
-
error: "#dc2626",
|
|
417
|
-
primary: primaryColor
|
|
418
|
-
};
|
|
419
|
-
}
|
|
420
|
-
function statusToLabel(status) {
|
|
421
|
-
if (!status) {
|
|
422
|
-
return "";
|
|
423
|
-
}
|
|
424
|
-
if (status === "preparing") {
|
|
425
|
-
return "Preparing checkout";
|
|
426
|
-
}
|
|
427
|
-
if (status === "recovering") {
|
|
428
|
-
return "Resuming payment";
|
|
429
|
-
}
|
|
430
|
-
if (status === "processing") {
|
|
431
|
-
return "Processing payment";
|
|
432
|
-
}
|
|
433
|
-
if (status === "awaiting_authorization") {
|
|
434
|
-
return "Waiting for authorization";
|
|
435
|
-
}
|
|
436
|
-
if (status === "polling") {
|
|
437
|
-
return "Confirming payment";
|
|
438
|
-
}
|
|
439
|
-
if (status === "finalizing") {
|
|
440
|
-
return "Finalizing order";
|
|
441
|
-
}
|
|
442
|
-
if (status === "success") {
|
|
443
|
-
return "Payment complete";
|
|
444
|
-
}
|
|
445
|
-
return "Payment failed";
|
|
446
|
-
}
|
|
447
|
-
function CimplifyCheckout({
|
|
448
|
-
client,
|
|
449
|
-
businessId,
|
|
450
|
-
cartId,
|
|
451
|
-
locationId,
|
|
452
|
-
linkUrl,
|
|
453
|
-
orderTypes,
|
|
454
|
-
enrollInLink = true,
|
|
455
|
-
onComplete,
|
|
456
|
-
onError,
|
|
457
|
-
onStatusChange,
|
|
458
|
-
appearance,
|
|
459
|
-
demoMode,
|
|
460
|
-
className
|
|
461
|
-
}) {
|
|
462
|
-
const resolvedOrderTypes = React2.useMemo(
|
|
463
|
-
() => orderTypes && orderTypes.length > 0 ? orderTypes : ["pickup", "delivery"],
|
|
464
|
-
[orderTypes]
|
|
465
|
-
);
|
|
466
|
-
const [orderType, setOrderType] = React2.useState(resolvedOrderTypes[0] || "pickup");
|
|
467
|
-
const [status, setStatus] = React2.useState(null);
|
|
468
|
-
const [statusText, setStatusText] = React2.useState("");
|
|
469
|
-
const [isSubmitting, setIsSubmitting] = React2.useState(false);
|
|
470
|
-
const [isInitializing, setIsInitializing] = React2.useState(false);
|
|
471
|
-
const [errorMessage, setErrorMessage] = React2.useState(null);
|
|
472
|
-
const [resolvedBusinessId, setResolvedBusinessId] = React2.useState(businessId ?? null);
|
|
473
|
-
const [resolvedCartId, setResolvedCartId] = React2.useState(cartId ?? null);
|
|
474
|
-
const [resolvedCart, setResolvedCart] = React2.useState(null);
|
|
475
|
-
const checkoutMountRef = React2.useRef(null);
|
|
476
|
-
const elementsRef = React2.useRef(null);
|
|
477
|
-
const activeCheckoutRef = React2.useRef(null);
|
|
478
|
-
const initialAppearanceRef = React2.useRef(appearance);
|
|
479
|
-
const hasWarnedInlineAppearanceRef = React2.useRef(false);
|
|
480
|
-
const isMountedRef = React2.useRef(true);
|
|
481
|
-
const demoRunRef = React2.useRef(0);
|
|
482
|
-
const isDemoCheckout = demoMode ?? client.getPublicKey().trim().length === 0;
|
|
483
|
-
const isTestMode = client.isTestMode();
|
|
484
|
-
const primaryColor = appearance?.variables?.primaryColor || "#0a2540";
|
|
485
|
-
const isDark = appearance?.theme === "dark";
|
|
486
|
-
const emitStatus = React2__default.default.useEffectEvent(
|
|
487
|
-
(nextStatus, context = {}) => {
|
|
488
|
-
setStatus(nextStatus);
|
|
489
|
-
setStatusText(context.display_text || "");
|
|
490
|
-
onStatusChange?.(nextStatus, context);
|
|
491
|
-
}
|
|
492
|
-
);
|
|
493
|
-
const fireError = React2__default.default.useEffectEvent(
|
|
494
|
-
(error) => {
|
|
495
|
-
onError?.(error);
|
|
496
|
-
}
|
|
497
|
-
);
|
|
498
|
-
React2.useEffect(() => {
|
|
499
|
-
if (!resolvedOrderTypes.includes(orderType)) {
|
|
500
|
-
setOrderType(resolvedOrderTypes[0] || "pickup");
|
|
501
|
-
}
|
|
502
|
-
}, [resolvedOrderTypes, orderType]);
|
|
503
|
-
React2.useEffect(() => {
|
|
504
|
-
if (appearance && appearance !== initialAppearanceRef.current && !hasWarnedInlineAppearanceRef.current) {
|
|
505
|
-
hasWarnedInlineAppearanceRef.current = true;
|
|
506
|
-
console.warn(
|
|
507
|
-
"[Cimplify] `appearance` prop reference changed after mount. Elements keep the initial appearance to avoid iframe remount. Memoize appearance with useMemo() to remove this warning."
|
|
508
|
-
);
|
|
509
|
-
}
|
|
510
|
-
}, [appearance]);
|
|
511
|
-
React2.useEffect(() => {
|
|
512
|
-
let cancelled = false;
|
|
513
|
-
async function bootstrap() {
|
|
514
|
-
if (isDemoCheckout) {
|
|
515
|
-
if (!cancelled) {
|
|
516
|
-
setResolvedBusinessId(businessId ?? null);
|
|
517
|
-
setResolvedCartId(cartId ?? "cart_demo");
|
|
518
|
-
setIsInitializing(false);
|
|
519
|
-
setErrorMessage(null);
|
|
520
|
-
}
|
|
521
|
-
return;
|
|
522
|
-
}
|
|
523
|
-
const needsBusinessResolve = !businessId;
|
|
524
|
-
const needsCartResolve = !cartId;
|
|
525
|
-
if (!needsBusinessResolve && !needsCartResolve) {
|
|
526
|
-
if (!cancelled) {
|
|
527
|
-
setResolvedBusinessId(businessId || null);
|
|
528
|
-
setResolvedCartId(cartId || null);
|
|
529
|
-
setIsInitializing(false);
|
|
530
|
-
setErrorMessage(null);
|
|
531
|
-
}
|
|
532
|
-
client.cart.get().then((cartResult) => {
|
|
533
|
-
if (!cancelled && cartResult.ok && cartResult.value) {
|
|
534
|
-
setResolvedCart(cartResult.value);
|
|
535
|
-
}
|
|
536
|
-
}).catch(() => {
|
|
537
|
-
});
|
|
538
|
-
return;
|
|
539
|
-
}
|
|
540
|
-
if (!cancelled) {
|
|
541
|
-
setIsInitializing(true);
|
|
542
|
-
setErrorMessage(null);
|
|
543
|
-
}
|
|
544
|
-
let nextBusinessId = businessId ?? null;
|
|
545
|
-
if (!nextBusinessId) {
|
|
546
|
-
try {
|
|
547
|
-
nextBusinessId = await client.resolveBusinessId();
|
|
548
|
-
} catch {
|
|
549
|
-
if (!cancelled) {
|
|
550
|
-
const message = "Unable to initialize checkout business context.";
|
|
551
|
-
setResolvedBusinessId(null);
|
|
552
|
-
setResolvedCartId(null);
|
|
553
|
-
setErrorMessage(message);
|
|
554
|
-
setIsInitializing(false);
|
|
555
|
-
fireError({ code: "BUSINESS_ID_REQUIRED", message });
|
|
556
|
-
}
|
|
557
|
-
return;
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
let nextCartId = cartId ?? null;
|
|
561
|
-
if (!nextCartId) {
|
|
562
|
-
const cartResult = await client.cart.get();
|
|
563
|
-
if (!cartResult.ok || !cartResult.value?.id || cartResult.value.items.length === 0) {
|
|
564
|
-
if (!cancelled) {
|
|
565
|
-
const message = "Your cart is empty. Add items before checkout.";
|
|
566
|
-
setResolvedBusinessId(nextBusinessId);
|
|
567
|
-
setResolvedCartId(null);
|
|
568
|
-
setErrorMessage(message);
|
|
569
|
-
setIsInitializing(false);
|
|
570
|
-
fireError({ code: "CART_EMPTY", message });
|
|
571
|
-
}
|
|
572
|
-
return;
|
|
573
|
-
}
|
|
574
|
-
nextCartId = cartResult.value.id;
|
|
575
|
-
if (!cancelled) {
|
|
576
|
-
setResolvedCart(cartResult.value);
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
if (!cancelled) {
|
|
580
|
-
setResolvedBusinessId(nextBusinessId);
|
|
581
|
-
setResolvedCartId(nextCartId);
|
|
582
|
-
setIsInitializing(false);
|
|
583
|
-
setErrorMessage(null);
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
void bootstrap();
|
|
587
|
-
return () => {
|
|
588
|
-
cancelled = true;
|
|
589
|
-
};
|
|
590
|
-
}, [businessId, cartId, client, isDemoCheckout]);
|
|
591
|
-
React2.useEffect(() => {
|
|
592
|
-
return () => {
|
|
593
|
-
isMountedRef.current = false;
|
|
594
|
-
demoRunRef.current += 1;
|
|
595
|
-
activeCheckoutRef.current?.abort();
|
|
596
|
-
activeCheckoutRef.current = null;
|
|
597
|
-
};
|
|
598
|
-
}, []);
|
|
599
|
-
const handleSubmit = React2__default.default.useEffectEvent(async () => {
|
|
600
|
-
if (isSubmitting || isInitializing || !resolvedCartId) {
|
|
601
|
-
if (!resolvedCartId && !isInitializing) {
|
|
602
|
-
const message = "Your cart is empty. Add items before checkout.";
|
|
603
|
-
setErrorMessage(message);
|
|
604
|
-
fireError({ code: "CART_EMPTY", message });
|
|
605
|
-
}
|
|
606
|
-
return;
|
|
607
|
-
}
|
|
608
|
-
setErrorMessage(null);
|
|
609
|
-
setIsSubmitting(true);
|
|
610
|
-
emitStatus("preparing", { display_text: statusToLabel("preparing") });
|
|
611
|
-
if (isDemoCheckout) {
|
|
612
|
-
const runId = demoRunRef.current + 1;
|
|
613
|
-
demoRunRef.current = runId;
|
|
614
|
-
const wait = async (ms) => {
|
|
615
|
-
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
616
|
-
return isMountedRef.current && runId === demoRunRef.current;
|
|
617
|
-
};
|
|
618
|
-
try {
|
|
619
|
-
if (!await wait(400)) return;
|
|
620
|
-
emitStatus("processing", { display_text: statusToLabel("processing") });
|
|
621
|
-
if (!await wait(900)) return;
|
|
622
|
-
emitStatus("polling", { display_text: statusToLabel("polling") });
|
|
623
|
-
if (!await wait(1200)) return;
|
|
624
|
-
const result = {
|
|
625
|
-
success: true,
|
|
626
|
-
order: {
|
|
627
|
-
id: `ord_demo_${Date.now()}`,
|
|
628
|
-
order_number: `DEMO-${Math.random().toString(36).slice(2, 8).toUpperCase()}`,
|
|
629
|
-
status: "confirmed",
|
|
630
|
-
total: "0.00",
|
|
631
|
-
currency: "USD"
|
|
632
|
-
}
|
|
633
|
-
};
|
|
634
|
-
emitStatus("success", {
|
|
635
|
-
order_id: result.order?.id,
|
|
636
|
-
order_number: result.order?.order_number,
|
|
637
|
-
display_text: statusToLabel("success")
|
|
638
|
-
});
|
|
639
|
-
onComplete(result);
|
|
640
|
-
} finally {
|
|
641
|
-
if (isMountedRef.current && runId === demoRunRef.current) {
|
|
642
|
-
setIsSubmitting(false);
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
return;
|
|
646
|
-
}
|
|
647
|
-
if (!elementsRef.current) {
|
|
648
|
-
const message = "Checkout is still initializing. Please try again.";
|
|
649
|
-
setErrorMessage(message);
|
|
650
|
-
fireError({ code: "CHECKOUT_NOT_READY", message });
|
|
651
|
-
setIsSubmitting(false);
|
|
652
|
-
return;
|
|
653
|
-
}
|
|
654
|
-
const checkout = elementsRef.current.processCheckout({
|
|
655
|
-
cart_id: resolvedCartId,
|
|
656
|
-
location_id: locationId ?? client.getLocationId() ?? void 0,
|
|
657
|
-
order_type: orderType,
|
|
658
|
-
enroll_in_link: enrollInLink,
|
|
659
|
-
on_status_change: emitStatus
|
|
660
|
-
});
|
|
661
|
-
activeCheckoutRef.current = checkout;
|
|
662
|
-
try {
|
|
663
|
-
const result = await checkout;
|
|
664
|
-
if (result.success) {
|
|
665
|
-
onComplete(result);
|
|
666
|
-
return;
|
|
667
|
-
}
|
|
668
|
-
const code = result.error?.code || "CHECKOUT_FAILED";
|
|
669
|
-
const message = result.error?.message || "Payment failed.";
|
|
670
|
-
setErrorMessage(message);
|
|
671
|
-
fireError({ code, message });
|
|
672
|
-
} finally {
|
|
673
|
-
if (isMountedRef.current) {
|
|
674
|
-
activeCheckoutRef.current = null;
|
|
675
|
-
setIsSubmitting(false);
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
});
|
|
679
|
-
React2.useEffect(() => {
|
|
680
|
-
if (isDemoCheckout || !resolvedBusinessId) {
|
|
681
|
-
elementsRef.current = null;
|
|
682
|
-
return;
|
|
683
|
-
}
|
|
684
|
-
const elements = client.elements(resolvedBusinessId, {
|
|
685
|
-
appearance: initialAppearanceRef.current,
|
|
686
|
-
linkUrl
|
|
687
|
-
});
|
|
688
|
-
elementsRef.current = elements;
|
|
689
|
-
const checkout = elements.create("checkout", {
|
|
690
|
-
orderTypes: resolvedOrderTypes,
|
|
691
|
-
defaultOrderType: resolvedOrderTypes[0]
|
|
692
|
-
});
|
|
693
|
-
if (checkoutMountRef.current) {
|
|
694
|
-
checkout.mount(checkoutMountRef.current);
|
|
695
|
-
}
|
|
696
|
-
checkout.on("ready", () => {
|
|
697
|
-
if (resolvedCart) {
|
|
698
|
-
checkout.setCart(transformToCheckoutCart(resolvedCart));
|
|
699
|
-
}
|
|
700
|
-
});
|
|
701
|
-
checkout.on("order_type_changed", (data) => {
|
|
702
|
-
const typed = data;
|
|
703
|
-
if (typed.orderType) {
|
|
704
|
-
setOrderType(typed.orderType);
|
|
705
|
-
}
|
|
706
|
-
});
|
|
707
|
-
checkout.on("request_submit", () => {
|
|
708
|
-
void handleSubmit();
|
|
709
|
-
});
|
|
710
|
-
return () => {
|
|
711
|
-
activeCheckoutRef.current?.abort();
|
|
712
|
-
activeCheckoutRef.current = null;
|
|
713
|
-
elements.destroy();
|
|
714
|
-
elementsRef.current = null;
|
|
715
|
-
};
|
|
716
|
-
}, [client, resolvedBusinessId, isDemoCheckout]);
|
|
717
|
-
React2.useEffect(() => {
|
|
718
|
-
if (!resolvedCart || !elementsRef.current) return;
|
|
719
|
-
const checkoutElement = elementsRef.current.getElement("checkout");
|
|
720
|
-
if (checkoutElement) {
|
|
721
|
-
checkoutElement.setCart(transformToCheckoutCart(resolvedCart));
|
|
722
|
-
}
|
|
723
|
-
}, [resolvedCart]);
|
|
724
|
-
const colors = shellColors(isDark ?? false, primaryColor);
|
|
725
|
-
if (isInitializing) {
|
|
726
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, "data-cimplify-checkout": "", children: /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-status": "", style: { fontSize: 13, color: colors.textSecondary }, children: "Preparing checkout..." }) });
|
|
727
|
-
}
|
|
728
|
-
if (!isDemoCheckout && (!resolvedBusinessId || !resolvedCartId)) {
|
|
729
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, "data-cimplify-checkout": "", children: /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-error": "", style: { fontSize: 13, color: colors.error }, children: errorMessage || "Unable to initialize checkout. Please refresh and try again." }) });
|
|
730
|
-
}
|
|
731
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, "data-cimplify-checkout": "", children: [
|
|
732
|
-
isTestMode && !isDemoCheckout && /* @__PURE__ */ jsxRuntime.jsx(
|
|
733
|
-
"p",
|
|
734
|
-
{
|
|
735
|
-
"data-cimplify-test-mode": "",
|
|
736
|
-
style: {
|
|
737
|
-
marginBottom: "10px",
|
|
738
|
-
fontSize: "12px",
|
|
739
|
-
fontWeight: 600,
|
|
740
|
-
color: "#92400e"
|
|
741
|
-
},
|
|
742
|
-
children: "Test mode - no real charges"
|
|
743
|
-
}
|
|
744
|
-
),
|
|
745
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-section": "checkout", children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: isDemoCheckout ? void 0 : checkoutMountRef }) }),
|
|
746
|
-
status && /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-status": "", style: { marginTop: SPACE.sm, fontSize: 13, color: colors.textSecondary }, children: statusText || statusToLabel(status) }),
|
|
747
|
-
errorMessage && /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-error": "", style: { marginTop: SPACE.sm, fontSize: 13, color: colors.error }, children: errorMessage })
|
|
748
|
-
] });
|
|
749
|
-
}
|
|
750
410
|
|
|
751
411
|
// src/types/common.ts
|
|
752
412
|
function money(value) {
|
|
@@ -755,6 +415,59 @@ function money(value) {
|
|
|
755
415
|
function moneyFromNumber(value) {
|
|
756
416
|
return value.toFixed(2);
|
|
757
417
|
}
|
|
418
|
+
var SUPPORTED_CURRENCY_CODES = /* @__PURE__ */ new Set([
|
|
419
|
+
"USD",
|
|
420
|
+
"EUR",
|
|
421
|
+
"GBP",
|
|
422
|
+
"JPY",
|
|
423
|
+
"CNY",
|
|
424
|
+
"CHF",
|
|
425
|
+
"CAD",
|
|
426
|
+
"AUD",
|
|
427
|
+
"GHS",
|
|
428
|
+
"NGN",
|
|
429
|
+
"KES",
|
|
430
|
+
"ZAR",
|
|
431
|
+
"XOF",
|
|
432
|
+
"XAF",
|
|
433
|
+
"EGP",
|
|
434
|
+
"TZS",
|
|
435
|
+
"UGX",
|
|
436
|
+
"RWF",
|
|
437
|
+
"ETB",
|
|
438
|
+
"ZMW",
|
|
439
|
+
"BWP",
|
|
440
|
+
"MUR",
|
|
441
|
+
"NAD",
|
|
442
|
+
"MWK",
|
|
443
|
+
"AOA",
|
|
444
|
+
"CDF",
|
|
445
|
+
"GMD",
|
|
446
|
+
"GNF",
|
|
447
|
+
"LRD",
|
|
448
|
+
"SLL",
|
|
449
|
+
"MZN",
|
|
450
|
+
"BIF",
|
|
451
|
+
"INR",
|
|
452
|
+
"BRL",
|
|
453
|
+
"MXN",
|
|
454
|
+
"KRW",
|
|
455
|
+
"TRY",
|
|
456
|
+
"THB",
|
|
457
|
+
"MYR",
|
|
458
|
+
"PHP",
|
|
459
|
+
"IDR",
|
|
460
|
+
"VND",
|
|
461
|
+
"SGD",
|
|
462
|
+
"HKD",
|
|
463
|
+
"TWD",
|
|
464
|
+
"AED",
|
|
465
|
+
"SAR",
|
|
466
|
+
"ILS"
|
|
467
|
+
]);
|
|
468
|
+
function isSupportedCurrency(code) {
|
|
469
|
+
return SUPPORTED_CURRENCY_CODES.has(code);
|
|
470
|
+
}
|
|
758
471
|
function currencyCode(value) {
|
|
759
472
|
return value;
|
|
760
473
|
}
|
|
@@ -1360,6 +1073,97 @@ var MOBILE_MONEY_PROVIDER = {
|
|
|
1360
1073
|
};
|
|
1361
1074
|
|
|
1362
1075
|
// src/utils/price.ts
|
|
1076
|
+
var CURRENCY_SYMBOLS = {
|
|
1077
|
+
// Major world currencies
|
|
1078
|
+
USD: "$",
|
|
1079
|
+
EUR: "\u20AC",
|
|
1080
|
+
GBP: "\xA3",
|
|
1081
|
+
JPY: "\xA5",
|
|
1082
|
+
CNY: "\xA5",
|
|
1083
|
+
CHF: "CHF",
|
|
1084
|
+
CAD: "C$",
|
|
1085
|
+
AUD: "A$",
|
|
1086
|
+
NZD: "NZ$",
|
|
1087
|
+
HKD: "HK$",
|
|
1088
|
+
SGD: "S$",
|
|
1089
|
+
INR: "\u20B9",
|
|
1090
|
+
BRL: "R$",
|
|
1091
|
+
MXN: "MX$",
|
|
1092
|
+
KRW: "\u20A9",
|
|
1093
|
+
RUB: "\u20BD",
|
|
1094
|
+
TRY: "\u20BA",
|
|
1095
|
+
THB: "\u0E3F",
|
|
1096
|
+
PLN: "z\u0142",
|
|
1097
|
+
SEK: "kr",
|
|
1098
|
+
NOK: "kr",
|
|
1099
|
+
DKK: "kr",
|
|
1100
|
+
CZK: "K\u010D",
|
|
1101
|
+
HUF: "Ft",
|
|
1102
|
+
ILS: "\u20AA",
|
|
1103
|
+
AED: "\u062F.\u0625",
|
|
1104
|
+
SAR: "\uFDFC",
|
|
1105
|
+
MYR: "RM",
|
|
1106
|
+
PHP: "\u20B1",
|
|
1107
|
+
IDR: "Rp",
|
|
1108
|
+
VND: "\u20AB",
|
|
1109
|
+
TWD: "NT$",
|
|
1110
|
+
// African currencies
|
|
1111
|
+
GHS: "GH\u20B5",
|
|
1112
|
+
NGN: "\u20A6",
|
|
1113
|
+
KES: "KSh",
|
|
1114
|
+
ZAR: "R",
|
|
1115
|
+
XOF: "CFA",
|
|
1116
|
+
XAF: "FCFA",
|
|
1117
|
+
EGP: "E\xA3",
|
|
1118
|
+
MAD: "MAD",
|
|
1119
|
+
TZS: "TSh",
|
|
1120
|
+
UGX: "USh",
|
|
1121
|
+
RWF: "FRw",
|
|
1122
|
+
ETB: "Br",
|
|
1123
|
+
ZMW: "ZK",
|
|
1124
|
+
BWP: "P",
|
|
1125
|
+
MUR: "\u20A8",
|
|
1126
|
+
SCR: "\u20A8",
|
|
1127
|
+
NAD: "N$",
|
|
1128
|
+
SZL: "E",
|
|
1129
|
+
LSL: "L",
|
|
1130
|
+
MWK: "MK",
|
|
1131
|
+
AOA: "Kz",
|
|
1132
|
+
CDF: "FC",
|
|
1133
|
+
GMD: "D",
|
|
1134
|
+
GNF: "FG",
|
|
1135
|
+
LRD: "L$",
|
|
1136
|
+
SLL: "Le",
|
|
1137
|
+
MZN: "MT",
|
|
1138
|
+
SDG: "SDG",
|
|
1139
|
+
SSP: "SSP",
|
|
1140
|
+
SOS: "Sh.So.",
|
|
1141
|
+
DJF: "Fdj",
|
|
1142
|
+
ERN: "Nfk",
|
|
1143
|
+
CVE: "$",
|
|
1144
|
+
STN: "Db",
|
|
1145
|
+
KMF: "CF",
|
|
1146
|
+
BIF: "FBu"
|
|
1147
|
+
};
|
|
1148
|
+
function getCurrencySymbol(currencyCode2) {
|
|
1149
|
+
return CURRENCY_SYMBOLS[currencyCode2.toUpperCase()] || currencyCode2;
|
|
1150
|
+
}
|
|
1151
|
+
function formatPrice(amount, currency = "GHS", locale = "en-US") {
|
|
1152
|
+
const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
1153
|
+
if (isNaN(numAmount)) {
|
|
1154
|
+
return `${getCurrencySymbol(currency)}0.00`;
|
|
1155
|
+
}
|
|
1156
|
+
try {
|
|
1157
|
+
return new Intl.NumberFormat(locale, {
|
|
1158
|
+
style: "currency",
|
|
1159
|
+
currency: currency.toUpperCase(),
|
|
1160
|
+
minimumFractionDigits: 2,
|
|
1161
|
+
maximumFractionDigits: 2
|
|
1162
|
+
}).format(numAmount);
|
|
1163
|
+
} catch {
|
|
1164
|
+
return `${getCurrencySymbol(currency)}${numAmount.toFixed(2)}`;
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1363
1167
|
function parsePrice(value) {
|
|
1364
1168
|
if (value === void 0 || value === null) {
|
|
1365
1169
|
return 0;
|
|
@@ -4320,6 +4124,8 @@ function createCimplifyClient(config = {}) {
|
|
|
4320
4124
|
return new CimplifyClient(config);
|
|
4321
4125
|
}
|
|
4322
4126
|
var LOCATION_STORAGE_KEY = "cimplify_location_id";
|
|
4127
|
+
var DISPLAY_CURRENCY_STORAGE_KEY = "cimplify_display_currency";
|
|
4128
|
+
var FX_REFRESH_INTERVAL = 12e4;
|
|
4323
4129
|
var DEFAULT_CURRENCY = "USD";
|
|
4324
4130
|
var DEFAULT_COUNTRY = "US";
|
|
4325
4131
|
function createDefaultClient() {
|
|
@@ -4348,6 +4154,27 @@ function setStoredLocationId(locationId) {
|
|
|
4348
4154
|
}
|
|
4349
4155
|
window.localStorage.setItem(LOCATION_STORAGE_KEY, locationId);
|
|
4350
4156
|
}
|
|
4157
|
+
function getStoredDisplayCurrency() {
|
|
4158
|
+
if (typeof window === "undefined" || !window.localStorage) {
|
|
4159
|
+
return null;
|
|
4160
|
+
}
|
|
4161
|
+
const value = window.localStorage.getItem(DISPLAY_CURRENCY_STORAGE_KEY);
|
|
4162
|
+
if (!value) {
|
|
4163
|
+
return null;
|
|
4164
|
+
}
|
|
4165
|
+
const normalized = value.trim().toUpperCase();
|
|
4166
|
+
return normalized.length > 0 ? normalized : null;
|
|
4167
|
+
}
|
|
4168
|
+
function setStoredDisplayCurrency(currency) {
|
|
4169
|
+
if (typeof window === "undefined" || !window.localStorage) {
|
|
4170
|
+
return;
|
|
4171
|
+
}
|
|
4172
|
+
if (!currency) {
|
|
4173
|
+
window.localStorage.removeItem(DISPLAY_CURRENCY_STORAGE_KEY);
|
|
4174
|
+
return;
|
|
4175
|
+
}
|
|
4176
|
+
window.localStorage.setItem(DISPLAY_CURRENCY_STORAGE_KEY, currency.toUpperCase());
|
|
4177
|
+
}
|
|
4351
4178
|
function resolveInitialLocation(locations) {
|
|
4352
4179
|
if (locations.length === 0) {
|
|
4353
4180
|
return null;
|
|
@@ -4361,23 +4188,77 @@ function resolveInitialLocation(locations) {
|
|
|
4361
4188
|
}
|
|
4362
4189
|
return locations[0];
|
|
4363
4190
|
}
|
|
4364
|
-
var CimplifyContext =
|
|
4191
|
+
var CimplifyContext = React3.createContext(null);
|
|
4365
4192
|
function CimplifyProvider({
|
|
4366
4193
|
client,
|
|
4367
4194
|
children,
|
|
4368
4195
|
onLocationChange
|
|
4369
4196
|
}) {
|
|
4370
|
-
const resolvedClient =
|
|
4371
|
-
const onLocationChangeRef =
|
|
4372
|
-
const [business, setBusiness] =
|
|
4373
|
-
const [locations, setLocations] =
|
|
4374
|
-
const [currentLocation, setCurrentLocationState] =
|
|
4375
|
-
const [isReady, setIsReady] =
|
|
4376
|
-
|
|
4197
|
+
const resolvedClient = React3.useMemo(() => client ?? createDefaultClient(), [client]);
|
|
4198
|
+
const onLocationChangeRef = React3.useRef(onLocationChange);
|
|
4199
|
+
const [business, setBusiness] = React3.useState(null);
|
|
4200
|
+
const [locations, setLocations] = React3.useState([]);
|
|
4201
|
+
const [currentLocation, setCurrentLocationState] = React3.useState(null);
|
|
4202
|
+
const [isReady, setIsReady] = React3.useState(false);
|
|
4203
|
+
React3.useEffect(() => {
|
|
4377
4204
|
onLocationChangeRef.current = onLocationChange;
|
|
4378
4205
|
}, [onLocationChange]);
|
|
4379
4206
|
const isDemoMode = resolvedClient.getPublicKey().trim().length === 0;
|
|
4380
|
-
const
|
|
4207
|
+
const baseCurrency = business?.default_currency || DEFAULT_CURRENCY;
|
|
4208
|
+
const [displayCurrencyOverride, setDisplayCurrencyOverride] = React3.useState(
|
|
4209
|
+
() => getStoredDisplayCurrency()
|
|
4210
|
+
);
|
|
4211
|
+
const [fxRate, setFxRate] = React3.useState(null);
|
|
4212
|
+
const displayCurrency = displayCurrencyOverride && displayCurrencyOverride !== baseCurrency ? displayCurrencyOverride : baseCurrency;
|
|
4213
|
+
const setDisplayCurrency = React3.useCallback(
|
|
4214
|
+
(currency) => {
|
|
4215
|
+
const normalized = currency?.trim().toUpperCase() || null;
|
|
4216
|
+
if (normalized && !isSupportedCurrency(normalized)) {
|
|
4217
|
+
return;
|
|
4218
|
+
}
|
|
4219
|
+
setDisplayCurrencyOverride(normalized);
|
|
4220
|
+
setStoredDisplayCurrency(normalized);
|
|
4221
|
+
if (!normalized || normalized === baseCurrency) {
|
|
4222
|
+
setFxRate(null);
|
|
4223
|
+
}
|
|
4224
|
+
},
|
|
4225
|
+
[baseCurrency]
|
|
4226
|
+
);
|
|
4227
|
+
React3.useEffect(() => {
|
|
4228
|
+
if (displayCurrency === baseCurrency || isDemoMode) {
|
|
4229
|
+
setFxRate(null);
|
|
4230
|
+
return;
|
|
4231
|
+
}
|
|
4232
|
+
let cancelled = false;
|
|
4233
|
+
async function fetchRate() {
|
|
4234
|
+
const result = await resolvedClient.fx.getRate(
|
|
4235
|
+
baseCurrency,
|
|
4236
|
+
displayCurrency
|
|
4237
|
+
);
|
|
4238
|
+
if (cancelled) return;
|
|
4239
|
+
if (result.ok) {
|
|
4240
|
+
setFxRate(result.value.rate);
|
|
4241
|
+
} else {
|
|
4242
|
+
setFxRate(null);
|
|
4243
|
+
}
|
|
4244
|
+
}
|
|
4245
|
+
void fetchRate();
|
|
4246
|
+
const intervalId = setInterval(() => void fetchRate(), FX_REFRESH_INTERVAL);
|
|
4247
|
+
return () => {
|
|
4248
|
+
cancelled = true;
|
|
4249
|
+
clearInterval(intervalId);
|
|
4250
|
+
};
|
|
4251
|
+
}, [resolvedClient, baseCurrency, displayCurrency, isDemoMode]);
|
|
4252
|
+
const convertPrice = React3.useCallback(
|
|
4253
|
+
(amount) => {
|
|
4254
|
+
const num = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
4255
|
+
if (isNaN(num)) return 0;
|
|
4256
|
+
if (!fxRate || displayCurrency === baseCurrency) return num;
|
|
4257
|
+
return Math.round(num * fxRate * 100) / 100;
|
|
4258
|
+
},
|
|
4259
|
+
[fxRate, displayCurrency, baseCurrency]
|
|
4260
|
+
);
|
|
4261
|
+
const setCurrentLocation = React3.useCallback(
|
|
4381
4262
|
(location) => {
|
|
4382
4263
|
setCurrentLocationState(location);
|
|
4383
4264
|
resolvedClient.setLocationId(location.id);
|
|
@@ -4386,7 +4267,7 @@ function CimplifyProvider({
|
|
|
4386
4267
|
},
|
|
4387
4268
|
[resolvedClient]
|
|
4388
4269
|
);
|
|
4389
|
-
|
|
4270
|
+
React3.useEffect(() => {
|
|
4390
4271
|
let cancelled = false;
|
|
4391
4272
|
async function bootstrap() {
|
|
4392
4273
|
setIsReady(false);
|
|
@@ -4401,80 +4282,454 @@ function CimplifyProvider({
|
|
|
4401
4282
|
}
|
|
4402
4283
|
return;
|
|
4403
4284
|
}
|
|
4404
|
-
const [businessResult, locationsResult] = await Promise.all([
|
|
4405
|
-
resolvedClient.business.getInfo(),
|
|
4406
|
-
resolvedClient.business.getLocations()
|
|
4407
|
-
]);
|
|
4408
|
-
if (cancelled) {
|
|
4409
|
-
return;
|
|
4285
|
+
const [businessResult, locationsResult] = await Promise.all([
|
|
4286
|
+
resolvedClient.business.getInfo(),
|
|
4287
|
+
resolvedClient.business.getLocations()
|
|
4288
|
+
]);
|
|
4289
|
+
if (cancelled) {
|
|
4290
|
+
return;
|
|
4291
|
+
}
|
|
4292
|
+
const nextBusiness = businessResult.ok ? businessResult.value : null;
|
|
4293
|
+
const nextLocations = locationsResult.ok && Array.isArray(locationsResult.value) ? locationsResult.value : [];
|
|
4294
|
+
const initialLocation = resolveInitialLocation(nextLocations);
|
|
4295
|
+
setBusiness(nextBusiness);
|
|
4296
|
+
if (nextBusiness?.id) {
|
|
4297
|
+
resolvedClient.setBusinessId(nextBusiness.id);
|
|
4298
|
+
}
|
|
4299
|
+
setLocations(nextLocations);
|
|
4300
|
+
if (initialLocation) {
|
|
4301
|
+
setCurrentLocationState(initialLocation);
|
|
4302
|
+
resolvedClient.setLocationId(initialLocation.id);
|
|
4303
|
+
setStoredLocationId(initialLocation.id);
|
|
4304
|
+
} else {
|
|
4305
|
+
setCurrentLocationState(null);
|
|
4306
|
+
resolvedClient.setLocationId(null);
|
|
4307
|
+
setStoredLocationId(null);
|
|
4308
|
+
}
|
|
4309
|
+
setIsReady(true);
|
|
4310
|
+
}
|
|
4311
|
+
bootstrap().catch(() => {
|
|
4312
|
+
if (cancelled) {
|
|
4313
|
+
return;
|
|
4314
|
+
}
|
|
4315
|
+
setBusiness(null);
|
|
4316
|
+
setLocations([]);
|
|
4317
|
+
setCurrentLocationState(null);
|
|
4318
|
+
resolvedClient.setLocationId(null);
|
|
4319
|
+
setStoredLocationId(null);
|
|
4320
|
+
setIsReady(true);
|
|
4321
|
+
});
|
|
4322
|
+
return () => {
|
|
4323
|
+
cancelled = true;
|
|
4324
|
+
};
|
|
4325
|
+
}, [resolvedClient, isDemoMode]);
|
|
4326
|
+
const contextValue = React3.useMemo(
|
|
4327
|
+
() => ({
|
|
4328
|
+
client: resolvedClient,
|
|
4329
|
+
business,
|
|
4330
|
+
currency: baseCurrency,
|
|
4331
|
+
country: business?.country_code || DEFAULT_COUNTRY,
|
|
4332
|
+
locations,
|
|
4333
|
+
currentLocation,
|
|
4334
|
+
setCurrentLocation,
|
|
4335
|
+
isReady,
|
|
4336
|
+
isDemoMode,
|
|
4337
|
+
baseCurrency,
|
|
4338
|
+
displayCurrency,
|
|
4339
|
+
setDisplayCurrency,
|
|
4340
|
+
convertPrice,
|
|
4341
|
+
fxRate
|
|
4342
|
+
}),
|
|
4343
|
+
[
|
|
4344
|
+
resolvedClient,
|
|
4345
|
+
business,
|
|
4346
|
+
baseCurrency,
|
|
4347
|
+
locations,
|
|
4348
|
+
currentLocation,
|
|
4349
|
+
setCurrentLocation,
|
|
4350
|
+
isReady,
|
|
4351
|
+
isDemoMode,
|
|
4352
|
+
displayCurrency,
|
|
4353
|
+
setDisplayCurrency,
|
|
4354
|
+
convertPrice,
|
|
4355
|
+
fxRate
|
|
4356
|
+
]
|
|
4357
|
+
);
|
|
4358
|
+
return /* @__PURE__ */ jsxRuntime.jsx(CimplifyContext.Provider, { value: contextValue, children });
|
|
4359
|
+
}
|
|
4360
|
+
function useCimplify() {
|
|
4361
|
+
const context = React3.useContext(CimplifyContext);
|
|
4362
|
+
if (!context) {
|
|
4363
|
+
throw new Error("useCimplify must be used within CimplifyProvider");
|
|
4364
|
+
}
|
|
4365
|
+
return context;
|
|
4366
|
+
}
|
|
4367
|
+
function useOptionalCimplify() {
|
|
4368
|
+
return React3.useContext(CimplifyContext);
|
|
4369
|
+
}
|
|
4370
|
+
var SPACE = { sm: 8};
|
|
4371
|
+
function shellColors(isDark, primaryColor) {
|
|
4372
|
+
return {
|
|
4373
|
+
text: isDark ? "#f4f4f5" : "#1a1a1a",
|
|
4374
|
+
textSecondary: isDark ? "#a1a1aa" : "#52525b",
|
|
4375
|
+
textMuted: isDark ? "#71717a" : "#a1a1aa",
|
|
4376
|
+
border: isDark ? "#27272a" : "#e4e4e7",
|
|
4377
|
+
surface: isDark ? "#18181b" : "#fafafa",
|
|
4378
|
+
error: "#dc2626",
|
|
4379
|
+
primary: primaryColor
|
|
4380
|
+
};
|
|
4381
|
+
}
|
|
4382
|
+
function statusToLabel(status) {
|
|
4383
|
+
if (!status) {
|
|
4384
|
+
return "";
|
|
4385
|
+
}
|
|
4386
|
+
if (status === "preparing") {
|
|
4387
|
+
return "Preparing checkout";
|
|
4388
|
+
}
|
|
4389
|
+
if (status === "recovering") {
|
|
4390
|
+
return "Resuming payment";
|
|
4391
|
+
}
|
|
4392
|
+
if (status === "processing") {
|
|
4393
|
+
return "Processing payment";
|
|
4394
|
+
}
|
|
4395
|
+
if (status === "awaiting_authorization") {
|
|
4396
|
+
return "Waiting for authorization";
|
|
4397
|
+
}
|
|
4398
|
+
if (status === "polling") {
|
|
4399
|
+
return "Confirming payment";
|
|
4400
|
+
}
|
|
4401
|
+
if (status === "finalizing") {
|
|
4402
|
+
return "Finalizing order";
|
|
4403
|
+
}
|
|
4404
|
+
if (status === "success") {
|
|
4405
|
+
return "Payment complete";
|
|
4406
|
+
}
|
|
4407
|
+
return "Payment failed";
|
|
4408
|
+
}
|
|
4409
|
+
function CimplifyCheckout({
|
|
4410
|
+
client,
|
|
4411
|
+
businessId,
|
|
4412
|
+
cartId,
|
|
4413
|
+
locationId,
|
|
4414
|
+
linkUrl,
|
|
4415
|
+
orderTypes,
|
|
4416
|
+
enrollInLink = true,
|
|
4417
|
+
onComplete,
|
|
4418
|
+
onError,
|
|
4419
|
+
onStatusChange,
|
|
4420
|
+
appearance,
|
|
4421
|
+
demoMode,
|
|
4422
|
+
className
|
|
4423
|
+
}) {
|
|
4424
|
+
const resolvedOrderTypes = React3.useMemo(
|
|
4425
|
+
() => orderTypes && orderTypes.length > 0 ? orderTypes : ["pickup", "delivery"],
|
|
4426
|
+
[orderTypes]
|
|
4427
|
+
);
|
|
4428
|
+
const [orderType, setOrderType] = React3.useState(resolvedOrderTypes[0] || "pickup");
|
|
4429
|
+
const [status, setStatus] = React3.useState(null);
|
|
4430
|
+
const [statusText, setStatusText] = React3.useState("");
|
|
4431
|
+
const [isSubmitting, setIsSubmitting] = React3.useState(false);
|
|
4432
|
+
const [isInitializing, setIsInitializing] = React3.useState(false);
|
|
4433
|
+
const [errorMessage, setErrorMessage] = React3.useState(null);
|
|
4434
|
+
const [resolvedBusinessId, setResolvedBusinessId] = React3.useState(businessId ?? null);
|
|
4435
|
+
const [resolvedCartId, setResolvedCartId] = React3.useState(cartId ?? null);
|
|
4436
|
+
const [resolvedCart, setResolvedCart] = React3.useState(null);
|
|
4437
|
+
const checkoutMountRef = React3.useRef(null);
|
|
4438
|
+
const elementsRef = React3.useRef(null);
|
|
4439
|
+
const activeCheckoutRef = React3.useRef(null);
|
|
4440
|
+
const initialAppearanceRef = React3.useRef(appearance);
|
|
4441
|
+
const hasWarnedInlineAppearanceRef = React3.useRef(false);
|
|
4442
|
+
const isMountedRef = React3.useRef(true);
|
|
4443
|
+
const demoRunRef = React3.useRef(0);
|
|
4444
|
+
const isDemoCheckout = demoMode ?? client.getPublicKey().trim().length === 0;
|
|
4445
|
+
const isTestMode = client.isTestMode();
|
|
4446
|
+
const cimplifyCtx = useOptionalCimplify();
|
|
4447
|
+
const fxOptions = React3.useMemo(() => {
|
|
4448
|
+
if (!cimplifyCtx?.fxRate) return void 0;
|
|
4449
|
+
if (cimplifyCtx.displayCurrency === cimplifyCtx.baseCurrency) return void 0;
|
|
4450
|
+
return {
|
|
4451
|
+
displayCurrency: cimplifyCtx.displayCurrency,
|
|
4452
|
+
convertPrice: cimplifyCtx.convertPrice
|
|
4453
|
+
};
|
|
4454
|
+
}, [cimplifyCtx?.fxRate, cimplifyCtx?.displayCurrency, cimplifyCtx?.baseCurrency, cimplifyCtx?.convertPrice]);
|
|
4455
|
+
const fxOptionsRef = React3.useRef(fxOptions);
|
|
4456
|
+
fxOptionsRef.current = fxOptions;
|
|
4457
|
+
const resolvedCartRef = React3.useRef(resolvedCart);
|
|
4458
|
+
resolvedCartRef.current = resolvedCart;
|
|
4459
|
+
const primaryColor = appearance?.variables?.primaryColor || "#0a2540";
|
|
4460
|
+
const isDark = appearance?.theme === "dark";
|
|
4461
|
+
const emitStatus = React3__default.default.useEffectEvent(
|
|
4462
|
+
(nextStatus, context = {}) => {
|
|
4463
|
+
setStatus(nextStatus);
|
|
4464
|
+
setStatusText(context.display_text || "");
|
|
4465
|
+
onStatusChange?.(nextStatus, context);
|
|
4466
|
+
}
|
|
4467
|
+
);
|
|
4468
|
+
const fireError = React3__default.default.useEffectEvent(
|
|
4469
|
+
(error) => {
|
|
4470
|
+
onError?.(error);
|
|
4471
|
+
}
|
|
4472
|
+
);
|
|
4473
|
+
React3.useEffect(() => {
|
|
4474
|
+
if (!resolvedOrderTypes.includes(orderType)) {
|
|
4475
|
+
setOrderType(resolvedOrderTypes[0] || "pickup");
|
|
4476
|
+
}
|
|
4477
|
+
}, [resolvedOrderTypes, orderType]);
|
|
4478
|
+
React3.useEffect(() => {
|
|
4479
|
+
if (appearance && appearance !== initialAppearanceRef.current && !hasWarnedInlineAppearanceRef.current) {
|
|
4480
|
+
hasWarnedInlineAppearanceRef.current = true;
|
|
4481
|
+
console.warn(
|
|
4482
|
+
"[Cimplify] `appearance` prop reference changed after mount. Elements keep the initial appearance to avoid iframe remount. Memoize appearance with useMemo() to remove this warning."
|
|
4483
|
+
);
|
|
4484
|
+
}
|
|
4485
|
+
}, [appearance]);
|
|
4486
|
+
React3.useEffect(() => {
|
|
4487
|
+
let cancelled = false;
|
|
4488
|
+
async function bootstrap() {
|
|
4489
|
+
if (isDemoCheckout) {
|
|
4490
|
+
if (!cancelled) {
|
|
4491
|
+
setResolvedBusinessId(businessId ?? null);
|
|
4492
|
+
setResolvedCartId(cartId ?? "cart_demo");
|
|
4493
|
+
setIsInitializing(false);
|
|
4494
|
+
setErrorMessage(null);
|
|
4495
|
+
}
|
|
4496
|
+
return;
|
|
4497
|
+
}
|
|
4498
|
+
const needsBusinessResolve = !businessId;
|
|
4499
|
+
const needsCartResolve = !cartId;
|
|
4500
|
+
if (!needsBusinessResolve && !needsCartResolve) {
|
|
4501
|
+
if (!cancelled) {
|
|
4502
|
+
setResolvedBusinessId(businessId || null);
|
|
4503
|
+
setResolvedCartId(cartId || null);
|
|
4504
|
+
setIsInitializing(false);
|
|
4505
|
+
setErrorMessage(null);
|
|
4506
|
+
}
|
|
4507
|
+
client.cart.get().then((cartResult) => {
|
|
4508
|
+
if (!cancelled && cartResult.ok && cartResult.value) {
|
|
4509
|
+
setResolvedCart(cartResult.value);
|
|
4510
|
+
}
|
|
4511
|
+
}).catch(() => {
|
|
4512
|
+
});
|
|
4513
|
+
return;
|
|
4514
|
+
}
|
|
4515
|
+
if (!cancelled) {
|
|
4516
|
+
setIsInitializing(true);
|
|
4517
|
+
setErrorMessage(null);
|
|
4410
4518
|
}
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4519
|
+
let nextBusinessId = businessId ?? null;
|
|
4520
|
+
if (!nextBusinessId) {
|
|
4521
|
+
try {
|
|
4522
|
+
nextBusinessId = await client.resolveBusinessId();
|
|
4523
|
+
} catch {
|
|
4524
|
+
if (!cancelled) {
|
|
4525
|
+
const message = "Unable to initialize checkout business context.";
|
|
4526
|
+
setResolvedBusinessId(null);
|
|
4527
|
+
setResolvedCartId(null);
|
|
4528
|
+
setErrorMessage(message);
|
|
4529
|
+
setIsInitializing(false);
|
|
4530
|
+
fireError({ code: "BUSINESS_ID_REQUIRED", message });
|
|
4531
|
+
}
|
|
4532
|
+
return;
|
|
4533
|
+
}
|
|
4417
4534
|
}
|
|
4418
|
-
|
|
4419
|
-
if (
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4535
|
+
let nextCartId = cartId ?? null;
|
|
4536
|
+
if (!nextCartId) {
|
|
4537
|
+
const cartResult = await client.cart.get();
|
|
4538
|
+
if (!cartResult.ok || !cartResult.value?.id || cartResult.value.items.length === 0) {
|
|
4539
|
+
if (!cancelled) {
|
|
4540
|
+
const message = "Your cart is empty. Add items before checkout.";
|
|
4541
|
+
setResolvedBusinessId(nextBusinessId);
|
|
4542
|
+
setResolvedCartId(null);
|
|
4543
|
+
setErrorMessage(message);
|
|
4544
|
+
setIsInitializing(false);
|
|
4545
|
+
fireError({ code: "CART_EMPTY", message });
|
|
4546
|
+
}
|
|
4547
|
+
return;
|
|
4548
|
+
}
|
|
4549
|
+
nextCartId = cartResult.value.id;
|
|
4550
|
+
if (!cancelled) {
|
|
4551
|
+
setResolvedCart(cartResult.value);
|
|
4552
|
+
}
|
|
4553
|
+
}
|
|
4554
|
+
if (!cancelled) {
|
|
4555
|
+
setResolvedBusinessId(nextBusinessId);
|
|
4556
|
+
setResolvedCartId(nextCartId);
|
|
4557
|
+
setIsInitializing(false);
|
|
4558
|
+
setErrorMessage(null);
|
|
4427
4559
|
}
|
|
4428
|
-
setIsReady(true);
|
|
4429
4560
|
}
|
|
4430
|
-
bootstrap()
|
|
4431
|
-
|
|
4561
|
+
void bootstrap();
|
|
4562
|
+
return () => {
|
|
4563
|
+
cancelled = true;
|
|
4564
|
+
};
|
|
4565
|
+
}, [businessId, cartId, client, isDemoCheckout]);
|
|
4566
|
+
React3.useEffect(() => {
|
|
4567
|
+
return () => {
|
|
4568
|
+
isMountedRef.current = false;
|
|
4569
|
+
demoRunRef.current += 1;
|
|
4570
|
+
activeCheckoutRef.current?.abort();
|
|
4571
|
+
activeCheckoutRef.current = null;
|
|
4572
|
+
};
|
|
4573
|
+
}, []);
|
|
4574
|
+
const handleSubmit = React3__default.default.useEffectEvent(async () => {
|
|
4575
|
+
if (isSubmitting || isInitializing || !resolvedCartId) {
|
|
4576
|
+
if (!resolvedCartId && !isInitializing) {
|
|
4577
|
+
const message = "Your cart is empty. Add items before checkout.";
|
|
4578
|
+
setErrorMessage(message);
|
|
4579
|
+
fireError({ code: "CART_EMPTY", message });
|
|
4580
|
+
}
|
|
4581
|
+
return;
|
|
4582
|
+
}
|
|
4583
|
+
setErrorMessage(null);
|
|
4584
|
+
setIsSubmitting(true);
|
|
4585
|
+
emitStatus("preparing", { display_text: statusToLabel("preparing") });
|
|
4586
|
+
if (isDemoCheckout) {
|
|
4587
|
+
const runId = demoRunRef.current + 1;
|
|
4588
|
+
demoRunRef.current = runId;
|
|
4589
|
+
const wait = async (ms) => {
|
|
4590
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
4591
|
+
return isMountedRef.current && runId === demoRunRef.current;
|
|
4592
|
+
};
|
|
4593
|
+
try {
|
|
4594
|
+
if (!await wait(400)) return;
|
|
4595
|
+
emitStatus("processing", { display_text: statusToLabel("processing") });
|
|
4596
|
+
if (!await wait(900)) return;
|
|
4597
|
+
emitStatus("polling", { display_text: statusToLabel("polling") });
|
|
4598
|
+
if (!await wait(1200)) return;
|
|
4599
|
+
const result = {
|
|
4600
|
+
success: true,
|
|
4601
|
+
order: {
|
|
4602
|
+
id: `ord_demo_${Date.now()}`,
|
|
4603
|
+
order_number: `DEMO-${Math.random().toString(36).slice(2, 8).toUpperCase()}`,
|
|
4604
|
+
status: "confirmed",
|
|
4605
|
+
total: "0.00",
|
|
4606
|
+
currency: "USD"
|
|
4607
|
+
}
|
|
4608
|
+
};
|
|
4609
|
+
emitStatus("success", {
|
|
4610
|
+
order_id: result.order?.id,
|
|
4611
|
+
order_number: result.order?.order_number,
|
|
4612
|
+
display_text: statusToLabel("success")
|
|
4613
|
+
});
|
|
4614
|
+
onComplete(result);
|
|
4615
|
+
} finally {
|
|
4616
|
+
if (isMountedRef.current && runId === demoRunRef.current) {
|
|
4617
|
+
setIsSubmitting(false);
|
|
4618
|
+
}
|
|
4619
|
+
}
|
|
4620
|
+
return;
|
|
4621
|
+
}
|
|
4622
|
+
if (!elementsRef.current) {
|
|
4623
|
+
const message = "Checkout is still initializing. Please try again.";
|
|
4624
|
+
setErrorMessage(message);
|
|
4625
|
+
fireError({ code: "CHECKOUT_NOT_READY", message });
|
|
4626
|
+
setIsSubmitting(false);
|
|
4627
|
+
return;
|
|
4628
|
+
}
|
|
4629
|
+
const checkout = elementsRef.current.processCheckout({
|
|
4630
|
+
cart_id: resolvedCartId,
|
|
4631
|
+
location_id: locationId ?? client.getLocationId() ?? void 0,
|
|
4632
|
+
order_type: orderType,
|
|
4633
|
+
enroll_in_link: enrollInLink,
|
|
4634
|
+
on_status_change: emitStatus,
|
|
4635
|
+
pay_currency: fxOptions?.displayCurrency
|
|
4636
|
+
});
|
|
4637
|
+
activeCheckoutRef.current = checkout;
|
|
4638
|
+
try {
|
|
4639
|
+
const result = await checkout;
|
|
4640
|
+
if (result.success) {
|
|
4641
|
+
onComplete(result);
|
|
4432
4642
|
return;
|
|
4433
4643
|
}
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4644
|
+
const code = result.error?.code || "CHECKOUT_FAILED";
|
|
4645
|
+
const message = result.error?.message || "Payment failed.";
|
|
4646
|
+
setErrorMessage(message);
|
|
4647
|
+
fireError({ code, message });
|
|
4648
|
+
} finally {
|
|
4649
|
+
if (isMountedRef.current) {
|
|
4650
|
+
activeCheckoutRef.current = null;
|
|
4651
|
+
setIsSubmitting(false);
|
|
4652
|
+
}
|
|
4653
|
+
}
|
|
4654
|
+
});
|
|
4655
|
+
React3.useEffect(() => {
|
|
4656
|
+
if (isDemoCheckout || !resolvedBusinessId) {
|
|
4657
|
+
elementsRef.current = null;
|
|
4658
|
+
return;
|
|
4659
|
+
}
|
|
4660
|
+
const elements = client.elements(resolvedBusinessId, {
|
|
4661
|
+
appearance: initialAppearanceRef.current,
|
|
4662
|
+
linkUrl
|
|
4663
|
+
});
|
|
4664
|
+
elementsRef.current = elements;
|
|
4665
|
+
const checkout = elements.create("checkout", {
|
|
4666
|
+
orderTypes: resolvedOrderTypes,
|
|
4667
|
+
defaultOrderType: resolvedOrderTypes[0]
|
|
4668
|
+
});
|
|
4669
|
+
if (checkoutMountRef.current) {
|
|
4670
|
+
checkout.mount(checkoutMountRef.current);
|
|
4671
|
+
}
|
|
4672
|
+
checkout.on("ready", () => {
|
|
4673
|
+
const cart = resolvedCartRef.current;
|
|
4674
|
+
if (cart) {
|
|
4675
|
+
checkout.setCart(transformToCheckoutCart(cart, fxOptionsRef.current));
|
|
4676
|
+
}
|
|
4677
|
+
});
|
|
4678
|
+
checkout.on("order_type_changed", (data) => {
|
|
4679
|
+
const typed = data;
|
|
4680
|
+
if (typed.orderType) {
|
|
4681
|
+
setOrderType(typed.orderType);
|
|
4682
|
+
}
|
|
4683
|
+
});
|
|
4684
|
+
checkout.on("request_submit", () => {
|
|
4685
|
+
void handleSubmit();
|
|
4440
4686
|
});
|
|
4441
4687
|
return () => {
|
|
4442
|
-
|
|
4688
|
+
activeCheckoutRef.current?.abort();
|
|
4689
|
+
activeCheckoutRef.current = null;
|
|
4690
|
+
elements.destroy();
|
|
4691
|
+
elementsRef.current = null;
|
|
4443
4692
|
};
|
|
4444
|
-
}, [
|
|
4445
|
-
|
|
4446
|
-
()
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
isDemoMode
|
|
4456
|
-
}),
|
|
4457
|
-
[
|
|
4458
|
-
resolvedClient,
|
|
4459
|
-
business,
|
|
4460
|
-
locations,
|
|
4461
|
-
currentLocation,
|
|
4462
|
-
setCurrentLocation,
|
|
4463
|
-
isReady,
|
|
4464
|
-
isDemoMode
|
|
4465
|
-
]
|
|
4466
|
-
);
|
|
4467
|
-
return /* @__PURE__ */ jsxRuntime.jsx(CimplifyContext.Provider, { value: contextValue, children });
|
|
4468
|
-
}
|
|
4469
|
-
function useCimplify() {
|
|
4470
|
-
const context = React2.useContext(CimplifyContext);
|
|
4471
|
-
if (!context) {
|
|
4472
|
-
throw new Error("useCimplify must be used within CimplifyProvider");
|
|
4693
|
+
}, [client, resolvedBusinessId, isDemoCheckout]);
|
|
4694
|
+
React3.useEffect(() => {
|
|
4695
|
+
if (!resolvedCart || !elementsRef.current) return;
|
|
4696
|
+
const checkoutElement = elementsRef.current.getElement("checkout");
|
|
4697
|
+
if (checkoutElement) {
|
|
4698
|
+
checkoutElement.setCart(transformToCheckoutCart(resolvedCart, fxOptions));
|
|
4699
|
+
}
|
|
4700
|
+
}, [resolvedCart, fxOptions]);
|
|
4701
|
+
const colors = shellColors(isDark ?? false, primaryColor);
|
|
4702
|
+
if (isInitializing) {
|
|
4703
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, "data-cimplify-checkout": "", children: /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-status": "", style: { fontSize: 13, color: colors.textSecondary }, children: "Preparing checkout..." }) });
|
|
4473
4704
|
}
|
|
4474
|
-
|
|
4705
|
+
if (!isDemoCheckout && (!resolvedBusinessId || !resolvedCartId)) {
|
|
4706
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, "data-cimplify-checkout": "", children: /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-error": "", style: { fontSize: 13, color: colors.error }, children: errorMessage || "Unable to initialize checkout. Please refresh and try again." }) });
|
|
4707
|
+
}
|
|
4708
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, "data-cimplify-checkout": "", children: [
|
|
4709
|
+
isTestMode && !isDemoCheckout && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4710
|
+
"p",
|
|
4711
|
+
{
|
|
4712
|
+
"data-cimplify-test-mode": "",
|
|
4713
|
+
style: {
|
|
4714
|
+
marginBottom: "10px",
|
|
4715
|
+
fontSize: "12px",
|
|
4716
|
+
fontWeight: 600,
|
|
4717
|
+
color: "#92400e"
|
|
4718
|
+
},
|
|
4719
|
+
children: "Test mode - no real charges"
|
|
4720
|
+
}
|
|
4721
|
+
),
|
|
4722
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-section": "checkout", children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: isDemoCheckout ? void 0 : checkoutMountRef }) }),
|
|
4723
|
+
status && /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-status": "", style: { marginTop: SPACE.sm, fontSize: 13, color: colors.textSecondary }, children: statusText || statusToLabel(status) }),
|
|
4724
|
+
errorMessage && /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-error": "", style: { marginTop: SPACE.sm, fontSize: 13, color: colors.error }, children: errorMessage })
|
|
4725
|
+
] });
|
|
4475
4726
|
}
|
|
4476
|
-
function
|
|
4477
|
-
|
|
4727
|
+
function Price({ amount, className, prefix }) {
|
|
4728
|
+
const { displayCurrency, convertPrice } = useCimplify();
|
|
4729
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className, children: [
|
|
4730
|
+
prefix,
|
|
4731
|
+
formatPrice(convertPrice(amount), displayCurrency)
|
|
4732
|
+
] });
|
|
4478
4733
|
}
|
|
4479
4734
|
var productsCache = /* @__PURE__ */ new Map();
|
|
4480
4735
|
var productsInflight = /* @__PURE__ */ new Map();
|
|
@@ -4493,9 +4748,9 @@ function useProducts(options = {}) {
|
|
|
4493
4748
|
}
|
|
4494
4749
|
const enabled = options.enabled ?? true;
|
|
4495
4750
|
const locationId = client.getLocationId();
|
|
4496
|
-
const previousLocationIdRef =
|
|
4497
|
-
const requestIdRef =
|
|
4498
|
-
const queryOptions =
|
|
4751
|
+
const previousLocationIdRef = React3.useRef(locationId);
|
|
4752
|
+
const requestIdRef = React3.useRef(0);
|
|
4753
|
+
const queryOptions = React3.useMemo(
|
|
4499
4754
|
() => ({
|
|
4500
4755
|
category: options.category,
|
|
4501
4756
|
collection: options.collection,
|
|
@@ -4505,25 +4760,25 @@ function useProducts(options = {}) {
|
|
|
4505
4760
|
}),
|
|
4506
4761
|
[options.category, options.collection, options.featured, options.limit, options.search]
|
|
4507
4762
|
);
|
|
4508
|
-
const cacheKey =
|
|
4763
|
+
const cacheKey = React3.useMemo(
|
|
4509
4764
|
() => buildProductsCacheKey(client, locationId, queryOptions),
|
|
4510
4765
|
[client, locationId, queryOptions]
|
|
4511
4766
|
);
|
|
4512
4767
|
const cached = productsCache.get(cacheKey);
|
|
4513
|
-
const [products, setProducts] =
|
|
4514
|
-
const [isComplete, setIsComplete] =
|
|
4515
|
-
const [totalAvailable, setTotalAvailable] =
|
|
4516
|
-
const [pagination, setPagination] =
|
|
4517
|
-
const [isLoading, setIsLoading] =
|
|
4518
|
-
const [error, setError] =
|
|
4519
|
-
|
|
4768
|
+
const [products, setProducts] = React3.useState(cached?.products ?? []);
|
|
4769
|
+
const [isComplete, setIsComplete] = React3.useState(cached?.is_complete ?? true);
|
|
4770
|
+
const [totalAvailable, setTotalAvailable] = React3.useState(cached?.total_available);
|
|
4771
|
+
const [pagination, setPagination] = React3.useState(cached?.pagination);
|
|
4772
|
+
const [isLoading, setIsLoading] = React3.useState(enabled && !cached);
|
|
4773
|
+
const [error, setError] = React3.useState(null);
|
|
4774
|
+
React3.useEffect(() => {
|
|
4520
4775
|
if (previousLocationIdRef.current !== locationId) {
|
|
4521
4776
|
productsCache.clear();
|
|
4522
4777
|
productsInflight.clear();
|
|
4523
4778
|
previousLocationIdRef.current = locationId;
|
|
4524
4779
|
}
|
|
4525
4780
|
}, [locationId]);
|
|
4526
|
-
const load =
|
|
4781
|
+
const load = React3.useCallback(
|
|
4527
4782
|
async (force = false) => {
|
|
4528
4783
|
if (!enabled) {
|
|
4529
4784
|
setIsLoading(false);
|
|
@@ -4586,10 +4841,10 @@ function useProducts(options = {}) {
|
|
|
4586
4841
|
},
|
|
4587
4842
|
[cacheKey, client, enabled, queryOptions]
|
|
4588
4843
|
);
|
|
4589
|
-
|
|
4844
|
+
React3.useEffect(() => {
|
|
4590
4845
|
void load(false);
|
|
4591
4846
|
}, [load]);
|
|
4592
|
-
const refetch =
|
|
4847
|
+
const refetch = React3.useCallback(async () => {
|
|
4593
4848
|
productsCache.delete(cacheKey);
|
|
4594
4849
|
await load(true);
|
|
4595
4850
|
}, [cacheKey, load]);
|
|
@@ -4623,27 +4878,27 @@ function useProduct(slugOrId, options = {}) {
|
|
|
4623
4878
|
}
|
|
4624
4879
|
const enabled = options.enabled ?? true;
|
|
4625
4880
|
const locationId = client.getLocationId();
|
|
4626
|
-
const previousLocationIdRef =
|
|
4627
|
-
const requestIdRef =
|
|
4628
|
-
const normalizedSlugOrId =
|
|
4629
|
-
const cacheKey =
|
|
4881
|
+
const previousLocationIdRef = React3.useRef(locationId);
|
|
4882
|
+
const requestIdRef = React3.useRef(0);
|
|
4883
|
+
const normalizedSlugOrId = React3.useMemo(() => (slugOrId || "").trim(), [slugOrId]);
|
|
4884
|
+
const cacheKey = React3.useMemo(
|
|
4630
4885
|
() => buildProductCacheKey(client, locationId, normalizedSlugOrId),
|
|
4631
4886
|
[client, locationId, normalizedSlugOrId]
|
|
4632
4887
|
);
|
|
4633
4888
|
const cached = productCache.get(cacheKey);
|
|
4634
|
-
const [product, setProduct] =
|
|
4635
|
-
const [isLoading, setIsLoading] =
|
|
4889
|
+
const [product, setProduct] = React3.useState(cached?.product ?? null);
|
|
4890
|
+
const [isLoading, setIsLoading] = React3.useState(
|
|
4636
4891
|
enabled && normalizedSlugOrId.length > 0 && !cached
|
|
4637
4892
|
);
|
|
4638
|
-
const [error, setError] =
|
|
4639
|
-
|
|
4893
|
+
const [error, setError] = React3.useState(null);
|
|
4894
|
+
React3.useEffect(() => {
|
|
4640
4895
|
if (previousLocationIdRef.current !== locationId) {
|
|
4641
4896
|
productCache.clear();
|
|
4642
4897
|
productInflight.clear();
|
|
4643
4898
|
previousLocationIdRef.current = locationId;
|
|
4644
4899
|
}
|
|
4645
4900
|
}, [locationId]);
|
|
4646
|
-
const load =
|
|
4901
|
+
const load = React3.useCallback(
|
|
4647
4902
|
async (force = false) => {
|
|
4648
4903
|
if (!enabled || normalizedSlugOrId.length === 0) {
|
|
4649
4904
|
setProduct(null);
|
|
@@ -4696,10 +4951,10 @@ function useProduct(slugOrId, options = {}) {
|
|
|
4696
4951
|
},
|
|
4697
4952
|
[cacheKey, client, enabled, normalizedSlugOrId]
|
|
4698
4953
|
);
|
|
4699
|
-
|
|
4954
|
+
React3.useEffect(() => {
|
|
4700
4955
|
void load(false);
|
|
4701
4956
|
}, [load]);
|
|
4702
|
-
const refetch =
|
|
4957
|
+
const refetch = React3.useCallback(async () => {
|
|
4703
4958
|
productCache.delete(cacheKey);
|
|
4704
4959
|
await load(true);
|
|
4705
4960
|
}, [cacheKey, load]);
|
|
@@ -4717,12 +4972,12 @@ function useCategories(options = {}) {
|
|
|
4717
4972
|
throw new Error("useCategories must be used within CimplifyProvider or passed { client }.");
|
|
4718
4973
|
}
|
|
4719
4974
|
const enabled = options.enabled ?? true;
|
|
4720
|
-
const cacheKey =
|
|
4975
|
+
const cacheKey = React3.useMemo(() => buildCategoriesCacheKey(client), [client]);
|
|
4721
4976
|
const cached = categoriesCache.get(cacheKey);
|
|
4722
|
-
const [categories, setCategories] =
|
|
4723
|
-
const [isLoading, setIsLoading] =
|
|
4724
|
-
const [error, setError] =
|
|
4725
|
-
const load =
|
|
4977
|
+
const [categories, setCategories] = React3.useState(cached ?? []);
|
|
4978
|
+
const [isLoading, setIsLoading] = React3.useState(enabled && !cached);
|
|
4979
|
+
const [error, setError] = React3.useState(null);
|
|
4980
|
+
const load = React3.useCallback(
|
|
4726
4981
|
async (force = false) => {
|
|
4727
4982
|
if (!enabled) {
|
|
4728
4983
|
setIsLoading(false);
|
|
@@ -4766,10 +5021,10 @@ function useCategories(options = {}) {
|
|
|
4766
5021
|
},
|
|
4767
5022
|
[cacheKey, client, enabled]
|
|
4768
5023
|
);
|
|
4769
|
-
|
|
5024
|
+
React3.useEffect(() => {
|
|
4770
5025
|
void load(false);
|
|
4771
5026
|
}, [load]);
|
|
4772
|
-
const refetch =
|
|
5027
|
+
const refetch = React3.useCallback(async () => {
|
|
4773
5028
|
categoriesCache.delete(cacheKey);
|
|
4774
5029
|
await load(true);
|
|
4775
5030
|
}, [cacheKey, load]);
|
|
@@ -5290,7 +5545,7 @@ function useCart(options = {}) {
|
|
|
5290
5545
|
const locationId = options.locationId ?? client.getLocationId();
|
|
5291
5546
|
const isDemoMode = options.demoMode ?? context?.isDemoMode ?? client.getPublicKey().trim().length === 0;
|
|
5292
5547
|
const currency = options.currency ?? context?.currency ?? "USD";
|
|
5293
|
-
const store =
|
|
5548
|
+
const store = React3.useMemo(
|
|
5294
5549
|
() => getOrCreateStore({
|
|
5295
5550
|
client,
|
|
5296
5551
|
locationId,
|
|
@@ -5299,43 +5554,43 @@ function useCart(options = {}) {
|
|
|
5299
5554
|
}),
|
|
5300
5555
|
[client, currency, isDemoMode, locationId]
|
|
5301
5556
|
);
|
|
5302
|
-
const snapshot =
|
|
5557
|
+
const snapshot = React3.useSyncExternalStore(
|
|
5303
5558
|
store.subscribe,
|
|
5304
5559
|
store.getSnapshot,
|
|
5305
5560
|
store.getSnapshot
|
|
5306
5561
|
);
|
|
5307
|
-
|
|
5562
|
+
React3.useEffect(() => {
|
|
5308
5563
|
void store.initialize();
|
|
5309
5564
|
}, [store]);
|
|
5310
|
-
const addItem =
|
|
5565
|
+
const addItem = React3.useCallback(
|
|
5311
5566
|
async (product, quantity, addOptions) => {
|
|
5312
5567
|
await store.addItem(product, quantity, addOptions);
|
|
5313
5568
|
},
|
|
5314
5569
|
[store]
|
|
5315
5570
|
);
|
|
5316
|
-
const removeItem =
|
|
5571
|
+
const removeItem = React3.useCallback(
|
|
5317
5572
|
async (itemId) => {
|
|
5318
5573
|
await store.removeItem(itemId);
|
|
5319
5574
|
},
|
|
5320
5575
|
[store]
|
|
5321
5576
|
);
|
|
5322
|
-
const updateQuantity =
|
|
5577
|
+
const updateQuantity = React3.useCallback(
|
|
5323
5578
|
async (itemId, quantity) => {
|
|
5324
5579
|
await store.updateQuantity(itemId, quantity);
|
|
5325
5580
|
},
|
|
5326
5581
|
[store]
|
|
5327
5582
|
);
|
|
5328
|
-
const clearCart =
|
|
5583
|
+
const clearCart = React3.useCallback(async () => {
|
|
5329
5584
|
await store.clearCart();
|
|
5330
5585
|
}, [store]);
|
|
5331
|
-
const sync =
|
|
5586
|
+
const sync = React3.useCallback(async () => {
|
|
5332
5587
|
try {
|
|
5333
5588
|
await store.sync();
|
|
5334
5589
|
} catch (syncError) {
|
|
5335
5590
|
throw syncError;
|
|
5336
5591
|
}
|
|
5337
5592
|
}, [store]);
|
|
5338
|
-
const itemCount =
|
|
5593
|
+
const itemCount = React3.useMemo(
|
|
5339
5594
|
() => snapshot.items.reduce((sum, item) => sum + item.quantity, 0),
|
|
5340
5595
|
[snapshot.items]
|
|
5341
5596
|
);
|
|
@@ -5366,22 +5621,22 @@ function useOrder(orderId, options = {}) {
|
|
|
5366
5621
|
if (!client) {
|
|
5367
5622
|
throw new Error("useOrder must be used within CimplifyProvider or passed { client }.");
|
|
5368
5623
|
}
|
|
5369
|
-
const normalizedOrderId =
|
|
5624
|
+
const normalizedOrderId = React3.useMemo(() => (orderId || "").trim(), [orderId]);
|
|
5370
5625
|
const enabled = options.enabled ?? true;
|
|
5371
5626
|
const poll = options.poll ?? false;
|
|
5372
5627
|
const pollInterval = options.pollInterval ?? 5e3;
|
|
5373
|
-
const requestIdRef =
|
|
5374
|
-
const cacheKey =
|
|
5628
|
+
const requestIdRef = React3.useRef(0);
|
|
5629
|
+
const cacheKey = React3.useMemo(
|
|
5375
5630
|
() => buildOrderCacheKey(client, normalizedOrderId),
|
|
5376
5631
|
[client, normalizedOrderId]
|
|
5377
5632
|
);
|
|
5378
5633
|
const cached = orderCache.get(cacheKey);
|
|
5379
|
-
const [order, setOrder] =
|
|
5380
|
-
const [isLoading, setIsLoading] =
|
|
5634
|
+
const [order, setOrder] = React3.useState(cached?.order ?? null);
|
|
5635
|
+
const [isLoading, setIsLoading] = React3.useState(
|
|
5381
5636
|
enabled && normalizedOrderId.length > 0 && !cached
|
|
5382
5637
|
);
|
|
5383
|
-
const [error, setError] =
|
|
5384
|
-
const load =
|
|
5638
|
+
const [error, setError] = React3.useState(null);
|
|
5639
|
+
const load = React3.useCallback(
|
|
5385
5640
|
async (force = false) => {
|
|
5386
5641
|
if (!enabled || normalizedOrderId.length === 0) {
|
|
5387
5642
|
setOrder(null);
|
|
@@ -5434,10 +5689,10 @@ function useOrder(orderId, options = {}) {
|
|
|
5434
5689
|
},
|
|
5435
5690
|
[cacheKey, client, enabled, normalizedOrderId]
|
|
5436
5691
|
);
|
|
5437
|
-
|
|
5692
|
+
React3.useEffect(() => {
|
|
5438
5693
|
void load(false);
|
|
5439
5694
|
}, [load]);
|
|
5440
|
-
|
|
5695
|
+
React3.useEffect(() => {
|
|
5441
5696
|
if (!poll || !enabled || normalizedOrderId.length === 0) {
|
|
5442
5697
|
return;
|
|
5443
5698
|
}
|
|
@@ -5448,7 +5703,7 @@ function useOrder(orderId, options = {}) {
|
|
|
5448
5703
|
window.clearInterval(timer);
|
|
5449
5704
|
};
|
|
5450
5705
|
}, [enabled, load, normalizedOrderId.length, poll, pollInterval]);
|
|
5451
|
-
const refetch =
|
|
5706
|
+
const refetch = React3.useCallback(async () => {
|
|
5452
5707
|
orderCache.delete(cacheKey);
|
|
5453
5708
|
await load(true);
|
|
5454
5709
|
}, [cacheKey, load]);
|
|
@@ -5499,10 +5754,10 @@ function useLocations(options = {}) {
|
|
|
5499
5754
|
};
|
|
5500
5755
|
}
|
|
5501
5756
|
const client = options.client;
|
|
5502
|
-
const [locations, setLocations] =
|
|
5503
|
-
const [currentLocation, setCurrentLocationState] =
|
|
5504
|
-
const [isLoading, setIsLoading] =
|
|
5505
|
-
const setCurrentLocation =
|
|
5757
|
+
const [locations, setLocations] = React3.useState([]);
|
|
5758
|
+
const [currentLocation, setCurrentLocationState] = React3.useState(null);
|
|
5759
|
+
const [isLoading, setIsLoading] = React3.useState(true);
|
|
5760
|
+
const setCurrentLocation = React3.useCallback(
|
|
5506
5761
|
(location) => {
|
|
5507
5762
|
setCurrentLocationState(location);
|
|
5508
5763
|
if (client) {
|
|
@@ -5512,7 +5767,7 @@ function useLocations(options = {}) {
|
|
|
5512
5767
|
},
|
|
5513
5768
|
[client]
|
|
5514
5769
|
);
|
|
5515
|
-
|
|
5770
|
+
React3.useEffect(() => {
|
|
5516
5771
|
if (!client) {
|
|
5517
5772
|
setLocations([]);
|
|
5518
5773
|
setCurrentLocationState(null);
|
|
@@ -5570,24 +5825,24 @@ function useCollections(options = {}) {
|
|
|
5570
5825
|
}
|
|
5571
5826
|
const enabled = options.enabled ?? true;
|
|
5572
5827
|
const locationId = client.getLocationId();
|
|
5573
|
-
const previousLocationIdRef =
|
|
5574
|
-
const requestIdRef =
|
|
5575
|
-
const cacheKey =
|
|
5828
|
+
const previousLocationIdRef = React3.useRef(locationId);
|
|
5829
|
+
const requestIdRef = React3.useRef(0);
|
|
5830
|
+
const cacheKey = React3.useMemo(
|
|
5576
5831
|
() => buildCollectionsCacheKey(client, locationId),
|
|
5577
5832
|
[client, locationId]
|
|
5578
5833
|
);
|
|
5579
5834
|
const cached = collectionsCache.get(cacheKey);
|
|
5580
|
-
const [collections, setCollections] =
|
|
5581
|
-
const [isLoading, setIsLoading] =
|
|
5582
|
-
const [error, setError] =
|
|
5583
|
-
|
|
5835
|
+
const [collections, setCollections] = React3.useState(cached?.collections ?? []);
|
|
5836
|
+
const [isLoading, setIsLoading] = React3.useState(enabled && !cached);
|
|
5837
|
+
const [error, setError] = React3.useState(null);
|
|
5838
|
+
React3.useEffect(() => {
|
|
5584
5839
|
if (previousLocationIdRef.current !== locationId) {
|
|
5585
5840
|
collectionsCache.clear();
|
|
5586
5841
|
collectionsInflight.clear();
|
|
5587
5842
|
previousLocationIdRef.current = locationId;
|
|
5588
5843
|
}
|
|
5589
5844
|
}, [locationId]);
|
|
5590
|
-
const load =
|
|
5845
|
+
const load = React3.useCallback(
|
|
5591
5846
|
async (force = false) => {
|
|
5592
5847
|
if (!enabled) {
|
|
5593
5848
|
setIsLoading(false);
|
|
@@ -5637,10 +5892,10 @@ function useCollections(options = {}) {
|
|
|
5637
5892
|
},
|
|
5638
5893
|
[cacheKey, client, enabled]
|
|
5639
5894
|
);
|
|
5640
|
-
|
|
5895
|
+
React3.useEffect(() => {
|
|
5641
5896
|
void load(false);
|
|
5642
5897
|
}, [load]);
|
|
5643
|
-
const refetch =
|
|
5898
|
+
const refetch = React3.useCallback(async () => {
|
|
5644
5899
|
collectionsCache.delete(cacheKey);
|
|
5645
5900
|
await load(true);
|
|
5646
5901
|
}, [cacheKey, load]);
|
|
@@ -5666,28 +5921,28 @@ function useCollection(idOrSlug, options = {}) {
|
|
|
5666
5921
|
}
|
|
5667
5922
|
const enabled = options.enabled ?? true;
|
|
5668
5923
|
const locationId = client.getLocationId();
|
|
5669
|
-
const previousLocationIdRef =
|
|
5670
|
-
const requestIdRef =
|
|
5671
|
-
const normalizedIdOrSlug =
|
|
5672
|
-
const cacheKey =
|
|
5924
|
+
const previousLocationIdRef = React3.useRef(locationId);
|
|
5925
|
+
const requestIdRef = React3.useRef(0);
|
|
5926
|
+
const normalizedIdOrSlug = React3.useMemo(() => (idOrSlug || "").trim(), [idOrSlug]);
|
|
5927
|
+
const cacheKey = React3.useMemo(
|
|
5673
5928
|
() => buildCollectionCacheKey(client, locationId, normalizedIdOrSlug),
|
|
5674
5929
|
[client, locationId, normalizedIdOrSlug]
|
|
5675
5930
|
);
|
|
5676
5931
|
const cached = collectionCache.get(cacheKey);
|
|
5677
|
-
const [collection, setCollection] =
|
|
5678
|
-
const [products, setProducts] =
|
|
5679
|
-
const [isLoading, setIsLoading] =
|
|
5932
|
+
const [collection, setCollection] = React3.useState(cached?.collection ?? null);
|
|
5933
|
+
const [products, setProducts] = React3.useState(cached?.products ?? []);
|
|
5934
|
+
const [isLoading, setIsLoading] = React3.useState(
|
|
5680
5935
|
enabled && normalizedIdOrSlug.length > 0 && !cached
|
|
5681
5936
|
);
|
|
5682
|
-
const [error, setError] =
|
|
5683
|
-
|
|
5937
|
+
const [error, setError] = React3.useState(null);
|
|
5938
|
+
React3.useEffect(() => {
|
|
5684
5939
|
if (previousLocationIdRef.current !== locationId) {
|
|
5685
5940
|
collectionCache.clear();
|
|
5686
5941
|
collectionInflight.clear();
|
|
5687
5942
|
previousLocationIdRef.current = locationId;
|
|
5688
5943
|
}
|
|
5689
5944
|
}, [locationId]);
|
|
5690
|
-
const load =
|
|
5945
|
+
const load = React3.useCallback(
|
|
5691
5946
|
async (force = false) => {
|
|
5692
5947
|
if (!enabled || normalizedIdOrSlug.length === 0) {
|
|
5693
5948
|
setCollection(null);
|
|
@@ -5750,10 +6005,10 @@ function useCollection(idOrSlug, options = {}) {
|
|
|
5750
6005
|
},
|
|
5751
6006
|
[cacheKey, client, enabled, normalizedIdOrSlug]
|
|
5752
6007
|
);
|
|
5753
|
-
|
|
6008
|
+
React3.useEffect(() => {
|
|
5754
6009
|
void load(false);
|
|
5755
6010
|
}, [load]);
|
|
5756
|
-
const refetch =
|
|
6011
|
+
const refetch = React3.useCallback(async () => {
|
|
5757
6012
|
collectionCache.delete(cacheKey);
|
|
5758
6013
|
await load(true);
|
|
5759
6014
|
}, [cacheKey, load]);
|
|
@@ -5779,27 +6034,27 @@ function useBundle(idOrSlug, options = {}) {
|
|
|
5779
6034
|
}
|
|
5780
6035
|
const enabled = options.enabled ?? true;
|
|
5781
6036
|
const locationId = client.getLocationId();
|
|
5782
|
-
const previousLocationIdRef =
|
|
5783
|
-
const requestIdRef =
|
|
5784
|
-
const normalizedIdOrSlug =
|
|
5785
|
-
const cacheKey =
|
|
6037
|
+
const previousLocationIdRef = React3.useRef(locationId);
|
|
6038
|
+
const requestIdRef = React3.useRef(0);
|
|
6039
|
+
const normalizedIdOrSlug = React3.useMemo(() => (idOrSlug || "").trim(), [idOrSlug]);
|
|
6040
|
+
const cacheKey = React3.useMemo(
|
|
5786
6041
|
() => buildBundleCacheKey(client, locationId, normalizedIdOrSlug),
|
|
5787
6042
|
[client, locationId, normalizedIdOrSlug]
|
|
5788
6043
|
);
|
|
5789
6044
|
const cached = bundleCache.get(cacheKey);
|
|
5790
|
-
const [bundle, setBundle] =
|
|
5791
|
-
const [isLoading, setIsLoading] =
|
|
6045
|
+
const [bundle, setBundle] = React3.useState(cached?.bundle ?? null);
|
|
6046
|
+
const [isLoading, setIsLoading] = React3.useState(
|
|
5792
6047
|
enabled && normalizedIdOrSlug.length > 0 && !cached
|
|
5793
6048
|
);
|
|
5794
|
-
const [error, setError] =
|
|
5795
|
-
|
|
6049
|
+
const [error, setError] = React3.useState(null);
|
|
6050
|
+
React3.useEffect(() => {
|
|
5796
6051
|
if (previousLocationIdRef.current !== locationId) {
|
|
5797
6052
|
bundleCache.clear();
|
|
5798
6053
|
bundleInflight.clear();
|
|
5799
6054
|
previousLocationIdRef.current = locationId;
|
|
5800
6055
|
}
|
|
5801
6056
|
}, [locationId]);
|
|
5802
|
-
const load =
|
|
6057
|
+
const load = React3.useCallback(
|
|
5803
6058
|
async (force = false) => {
|
|
5804
6059
|
if (!enabled || normalizedIdOrSlug.length === 0) {
|
|
5805
6060
|
setBundle(null);
|
|
@@ -5850,10 +6105,10 @@ function useBundle(idOrSlug, options = {}) {
|
|
|
5850
6105
|
},
|
|
5851
6106
|
[cacheKey, client, enabled, normalizedIdOrSlug]
|
|
5852
6107
|
);
|
|
5853
|
-
|
|
6108
|
+
React3.useEffect(() => {
|
|
5854
6109
|
void load(false);
|
|
5855
6110
|
}, [load]);
|
|
5856
|
-
const refetch =
|
|
6111
|
+
const refetch = React3.useCallback(async () => {
|
|
5857
6112
|
bundleCache.delete(cacheKey);
|
|
5858
6113
|
await load(true);
|
|
5859
6114
|
}, [cacheKey, load]);
|
|
@@ -5883,37 +6138,37 @@ function useComposite(idOrProductId, options = {}) {
|
|
|
5883
6138
|
}
|
|
5884
6139
|
const enabled = options.enabled ?? true;
|
|
5885
6140
|
const locationId = client.getLocationId();
|
|
5886
|
-
const previousLocationIdRef =
|
|
5887
|
-
const requestIdRef =
|
|
5888
|
-
const priceRequestIdRef =
|
|
5889
|
-
const normalizedIdOrProductId =
|
|
6141
|
+
const previousLocationIdRef = React3.useRef(locationId);
|
|
6142
|
+
const requestIdRef = React3.useRef(0);
|
|
6143
|
+
const priceRequestIdRef = React3.useRef(0);
|
|
6144
|
+
const normalizedIdOrProductId = React3.useMemo(
|
|
5890
6145
|
() => (idOrProductId || "").trim(),
|
|
5891
6146
|
[idOrProductId]
|
|
5892
6147
|
);
|
|
5893
|
-
const byProductId =
|
|
6148
|
+
const byProductId = React3.useMemo(
|
|
5894
6149
|
() => shouldFetchByProductId(normalizedIdOrProductId, options.byProductId),
|
|
5895
6150
|
[normalizedIdOrProductId, options.byProductId]
|
|
5896
6151
|
);
|
|
5897
|
-
const cacheKey =
|
|
6152
|
+
const cacheKey = React3.useMemo(
|
|
5898
6153
|
() => buildCompositeCacheKey(client, locationId, normalizedIdOrProductId, byProductId),
|
|
5899
6154
|
[byProductId, client, locationId, normalizedIdOrProductId]
|
|
5900
6155
|
);
|
|
5901
6156
|
const cached = compositeCache.get(cacheKey);
|
|
5902
|
-
const [composite, setComposite] =
|
|
5903
|
-
const [isLoading, setIsLoading] =
|
|
6157
|
+
const [composite, setComposite] = React3.useState(cached?.composite ?? null);
|
|
6158
|
+
const [isLoading, setIsLoading] = React3.useState(
|
|
5904
6159
|
enabled && normalizedIdOrProductId.length > 0 && !cached
|
|
5905
6160
|
);
|
|
5906
|
-
const [error, setError] =
|
|
5907
|
-
const [priceResult, setPriceResult] =
|
|
5908
|
-
const [isPriceLoading, setIsPriceLoading] =
|
|
5909
|
-
|
|
6161
|
+
const [error, setError] = React3.useState(null);
|
|
6162
|
+
const [priceResult, setPriceResult] = React3.useState(null);
|
|
6163
|
+
const [isPriceLoading, setIsPriceLoading] = React3.useState(false);
|
|
6164
|
+
React3.useEffect(() => {
|
|
5910
6165
|
if (previousLocationIdRef.current !== locationId) {
|
|
5911
6166
|
compositeCache.clear();
|
|
5912
6167
|
compositeInflight.clear();
|
|
5913
6168
|
previousLocationIdRef.current = locationId;
|
|
5914
6169
|
}
|
|
5915
6170
|
}, [locationId]);
|
|
5916
|
-
const load =
|
|
6171
|
+
const load = React3.useCallback(
|
|
5917
6172
|
async (force = false) => {
|
|
5918
6173
|
if (!enabled || normalizedIdOrProductId.length === 0) {
|
|
5919
6174
|
setComposite(null);
|
|
@@ -5966,10 +6221,10 @@ function useComposite(idOrProductId, options = {}) {
|
|
|
5966
6221
|
},
|
|
5967
6222
|
[byProductId, cacheKey, client, enabled, normalizedIdOrProductId]
|
|
5968
6223
|
);
|
|
5969
|
-
|
|
6224
|
+
React3.useEffect(() => {
|
|
5970
6225
|
void load(false);
|
|
5971
6226
|
}, [load]);
|
|
5972
|
-
const calculatePrice =
|
|
6227
|
+
const calculatePrice = React3.useCallback(
|
|
5973
6228
|
async (selections, overrideLocationId) => {
|
|
5974
6229
|
if (!composite) {
|
|
5975
6230
|
return null;
|
|
@@ -6003,7 +6258,7 @@ function useComposite(idOrProductId, options = {}) {
|
|
|
6003
6258
|
},
|
|
6004
6259
|
[client, composite]
|
|
6005
6260
|
);
|
|
6006
|
-
const refetch =
|
|
6261
|
+
const refetch = React3.useCallback(async () => {
|
|
6007
6262
|
compositeCache.delete(cacheKey);
|
|
6008
6263
|
await load(true);
|
|
6009
6264
|
}, [cacheKey, load]);
|
|
@@ -6018,13 +6273,13 @@ function useSearch(options = {}) {
|
|
|
6018
6273
|
const minLength = Math.max(0, options.minLength ?? 2);
|
|
6019
6274
|
const debounceMs = Math.max(0, options.debounceMs ?? 300);
|
|
6020
6275
|
const limit = Math.max(1, options.limit ?? 20);
|
|
6021
|
-
const [query, setQueryState] =
|
|
6022
|
-
const [results, setResults] =
|
|
6023
|
-
const [isLoading, setIsLoading] =
|
|
6024
|
-
const [error, setError] =
|
|
6025
|
-
const requestIdRef =
|
|
6026
|
-
const timerRef =
|
|
6027
|
-
|
|
6276
|
+
const [query, setQueryState] = React3.useState("");
|
|
6277
|
+
const [results, setResults] = React3.useState([]);
|
|
6278
|
+
const [isLoading, setIsLoading] = React3.useState(false);
|
|
6279
|
+
const [error, setError] = React3.useState(null);
|
|
6280
|
+
const requestIdRef = React3.useRef(0);
|
|
6281
|
+
const timerRef = React3.useRef(null);
|
|
6282
|
+
React3.useEffect(() => {
|
|
6028
6283
|
if (timerRef.current) {
|
|
6029
6284
|
clearTimeout(timerRef.current);
|
|
6030
6285
|
timerRef.current = null;
|
|
@@ -6071,10 +6326,10 @@ function useSearch(options = {}) {
|
|
|
6071
6326
|
}
|
|
6072
6327
|
};
|
|
6073
6328
|
}, [client, debounceMs, limit, minLength, options.category, query]);
|
|
6074
|
-
const setQuery =
|
|
6329
|
+
const setQuery = React3.useCallback((nextQuery) => {
|
|
6075
6330
|
setQueryState(nextQuery);
|
|
6076
6331
|
}, []);
|
|
6077
|
-
const clear =
|
|
6332
|
+
const clear = React3.useCallback(() => {
|
|
6078
6333
|
requestIdRef.current += 1;
|
|
6079
6334
|
if (timerRef.current) {
|
|
6080
6335
|
clearTimeout(timerRef.current);
|
|
@@ -6130,28 +6385,28 @@ function useQuote(input, options = {}) {
|
|
|
6130
6385
|
const autoRefresh = options.autoRefresh ?? true;
|
|
6131
6386
|
const refreshBeforeExpiryMs = Math.max(0, options.refreshBeforeExpiryMs ?? 3e4);
|
|
6132
6387
|
const locationId = client.getLocationId();
|
|
6133
|
-
const requestIdRef =
|
|
6134
|
-
const refreshTimerRef =
|
|
6135
|
-
const expiryTimerRef =
|
|
6136
|
-
const inputSignature =
|
|
6137
|
-
const normalizedInput =
|
|
6388
|
+
const requestIdRef = React3.useRef(0);
|
|
6389
|
+
const refreshTimerRef = React3.useRef(null);
|
|
6390
|
+
const expiryTimerRef = React3.useRef(null);
|
|
6391
|
+
const inputSignature = React3.useMemo(() => JSON.stringify(input ?? null), [input]);
|
|
6392
|
+
const normalizedInput = React3.useMemo(() => {
|
|
6138
6393
|
if (!input) {
|
|
6139
6394
|
return null;
|
|
6140
6395
|
}
|
|
6141
6396
|
const normalized = normalizeInput(input, locationId);
|
|
6142
6397
|
return normalized.product_id.length > 0 ? normalized : null;
|
|
6143
6398
|
}, [inputSignature, locationId]);
|
|
6144
|
-
const cacheKey =
|
|
6399
|
+
const cacheKey = React3.useMemo(
|
|
6145
6400
|
() => buildQuoteCacheKey(client, locationId, inputSignature),
|
|
6146
6401
|
[client, inputSignature, locationId]
|
|
6147
6402
|
);
|
|
6148
6403
|
const cached = quoteCache.get(cacheKey);
|
|
6149
|
-
const [quote, setQuote] =
|
|
6150
|
-
const [isLoading, setIsLoading] =
|
|
6151
|
-
const [error, setError] =
|
|
6152
|
-
const [isExpired, setIsExpired] =
|
|
6153
|
-
const [messages, setMessages] =
|
|
6154
|
-
const load =
|
|
6404
|
+
const [quote, setQuote] = React3.useState(cached?.quote ?? null);
|
|
6405
|
+
const [isLoading, setIsLoading] = React3.useState(enabled && normalizedInput !== null && !cached);
|
|
6406
|
+
const [error, setError] = React3.useState(null);
|
|
6407
|
+
const [isExpired, setIsExpired] = React3.useState(isQuoteExpired(cached?.quote ?? null));
|
|
6408
|
+
const [messages, setMessages] = React3.useState(cached?.quote?.ui_messages ?? []);
|
|
6409
|
+
const load = React3.useCallback(
|
|
6155
6410
|
async (force = false) => {
|
|
6156
6411
|
if (!enabled || !normalizedInput) {
|
|
6157
6412
|
setQuote(null);
|
|
@@ -6209,10 +6464,10 @@ function useQuote(input, options = {}) {
|
|
|
6209
6464
|
},
|
|
6210
6465
|
[cacheKey, client, enabled, normalizedInput]
|
|
6211
6466
|
);
|
|
6212
|
-
|
|
6467
|
+
React3.useEffect(() => {
|
|
6213
6468
|
void load(false);
|
|
6214
6469
|
}, [load]);
|
|
6215
|
-
const refresh =
|
|
6470
|
+
const refresh = React3.useCallback(async () => {
|
|
6216
6471
|
if (!enabled || !normalizedInput) {
|
|
6217
6472
|
return;
|
|
6218
6473
|
}
|
|
@@ -6249,7 +6504,7 @@ function useQuote(input, options = {}) {
|
|
|
6249
6504
|
}
|
|
6250
6505
|
}
|
|
6251
6506
|
}, [cacheKey, client, enabled, load, normalizedInput, quote]);
|
|
6252
|
-
|
|
6507
|
+
React3.useEffect(() => {
|
|
6253
6508
|
if (expiryTimerRef.current) {
|
|
6254
6509
|
clearTimeout(expiryTimerRef.current);
|
|
6255
6510
|
expiryTimerRef.current = null;
|
|
@@ -6273,7 +6528,7 @@ function useQuote(input, options = {}) {
|
|
|
6273
6528
|
}
|
|
6274
6529
|
};
|
|
6275
6530
|
}, [quote?.expires_at, quote?.quote_id]);
|
|
6276
|
-
|
|
6531
|
+
React3.useEffect(() => {
|
|
6277
6532
|
if (refreshTimerRef.current) {
|
|
6278
6533
|
clearTimeout(refreshTimerRef.current);
|
|
6279
6534
|
refreshTimerRef.current = null;
|
|
@@ -6298,15 +6553,15 @@ function useQuote(input, options = {}) {
|
|
|
6298
6553
|
}, [autoRefresh, enabled, quote?.expires_at, quote?.quote_id, refresh, refreshBeforeExpiryMs]);
|
|
6299
6554
|
return { quote, isLoading, error, refresh, isExpired, messages };
|
|
6300
6555
|
}
|
|
6301
|
-
var ElementsContext =
|
|
6556
|
+
var ElementsContext = React3.createContext({
|
|
6302
6557
|
elements: null,
|
|
6303
6558
|
isReady: false
|
|
6304
6559
|
});
|
|
6305
6560
|
function useElements() {
|
|
6306
|
-
return
|
|
6561
|
+
return React3.useContext(ElementsContext).elements;
|
|
6307
6562
|
}
|
|
6308
6563
|
function useElementsReady() {
|
|
6309
|
-
return
|
|
6564
|
+
return React3.useContext(ElementsContext).isReady;
|
|
6310
6565
|
}
|
|
6311
6566
|
function ElementsProvider({
|
|
6312
6567
|
client,
|
|
@@ -6314,10 +6569,10 @@ function ElementsProvider({
|
|
|
6314
6569
|
options,
|
|
6315
6570
|
children
|
|
6316
6571
|
}) {
|
|
6317
|
-
const [elements, setElements] =
|
|
6318
|
-
const [isReady, setIsReady] =
|
|
6319
|
-
const initialOptionsRef =
|
|
6320
|
-
|
|
6572
|
+
const [elements, setElements] = React3.useState(null);
|
|
6573
|
+
const [isReady, setIsReady] = React3.useState(false);
|
|
6574
|
+
const initialOptionsRef = React3.useRef(options);
|
|
6575
|
+
React3.useEffect(() => {
|
|
6321
6576
|
let cancelled = false;
|
|
6322
6577
|
let instance = null;
|
|
6323
6578
|
setIsReady(false);
|
|
@@ -6358,20 +6613,20 @@ function AuthElement({
|
|
|
6358
6613
|
onRequiresOtp,
|
|
6359
6614
|
onError
|
|
6360
6615
|
}) {
|
|
6361
|
-
const containerRef =
|
|
6362
|
-
const elementRef =
|
|
6616
|
+
const containerRef = React3.useRef(null);
|
|
6617
|
+
const elementRef = React3.useRef(null);
|
|
6363
6618
|
const elements = useElements();
|
|
6364
|
-
const onReadyRef =
|
|
6365
|
-
const onAuthenticatedRef =
|
|
6366
|
-
const onRequiresOtpRef =
|
|
6367
|
-
const onErrorRef =
|
|
6368
|
-
|
|
6619
|
+
const onReadyRef = React3.useRef(onReady);
|
|
6620
|
+
const onAuthenticatedRef = React3.useRef(onAuthenticated);
|
|
6621
|
+
const onRequiresOtpRef = React3.useRef(onRequiresOtp);
|
|
6622
|
+
const onErrorRef = React3.useRef(onError);
|
|
6623
|
+
React3.useEffect(() => {
|
|
6369
6624
|
onReadyRef.current = onReady;
|
|
6370
6625
|
onAuthenticatedRef.current = onAuthenticated;
|
|
6371
6626
|
onRequiresOtpRef.current = onRequiresOtp;
|
|
6372
6627
|
onErrorRef.current = onError;
|
|
6373
6628
|
}, [onReady, onAuthenticated, onRequiresOtp, onError]);
|
|
6374
|
-
|
|
6629
|
+
React3.useEffect(() => {
|
|
6375
6630
|
if (!elements || !containerRef.current) return;
|
|
6376
6631
|
const element = elements.create(ELEMENT_TYPES.AUTH, { prefillEmail });
|
|
6377
6632
|
elementRef.current = element;
|
|
@@ -6401,18 +6656,18 @@ function AddressElement({
|
|
|
6401
6656
|
onChange,
|
|
6402
6657
|
onError
|
|
6403
6658
|
}) {
|
|
6404
|
-
const containerRef =
|
|
6405
|
-
const elementRef =
|
|
6659
|
+
const containerRef = React3.useRef(null);
|
|
6660
|
+
const elementRef = React3.useRef(null);
|
|
6406
6661
|
const elements = useElements();
|
|
6407
|
-
const onReadyRef =
|
|
6408
|
-
const onChangeRef =
|
|
6409
|
-
const onErrorRef =
|
|
6410
|
-
|
|
6662
|
+
const onReadyRef = React3.useRef(onReady);
|
|
6663
|
+
const onChangeRef = React3.useRef(onChange);
|
|
6664
|
+
const onErrorRef = React3.useRef(onError);
|
|
6665
|
+
React3.useEffect(() => {
|
|
6411
6666
|
onReadyRef.current = onReady;
|
|
6412
6667
|
onChangeRef.current = onChange;
|
|
6413
6668
|
onErrorRef.current = onError;
|
|
6414
6669
|
}, [onReady, onChange, onError]);
|
|
6415
|
-
|
|
6670
|
+
React3.useEffect(() => {
|
|
6416
6671
|
if (!elements || !containerRef.current) return;
|
|
6417
6672
|
const element = elements.create(ELEMENT_TYPES.ADDRESS, { mode });
|
|
6418
6673
|
elementRef.current = element;
|
|
@@ -6439,18 +6694,18 @@ function PaymentElement({
|
|
|
6439
6694
|
onChange,
|
|
6440
6695
|
onError
|
|
6441
6696
|
}) {
|
|
6442
|
-
const containerRef =
|
|
6443
|
-
const elementRef =
|
|
6697
|
+
const containerRef = React3.useRef(null);
|
|
6698
|
+
const elementRef = React3.useRef(null);
|
|
6444
6699
|
const elements = useElements();
|
|
6445
|
-
const onReadyRef =
|
|
6446
|
-
const onChangeRef =
|
|
6447
|
-
const onErrorRef =
|
|
6448
|
-
|
|
6700
|
+
const onReadyRef = React3.useRef(onReady);
|
|
6701
|
+
const onChangeRef = React3.useRef(onChange);
|
|
6702
|
+
const onErrorRef = React3.useRef(onError);
|
|
6703
|
+
React3.useEffect(() => {
|
|
6449
6704
|
onReadyRef.current = onReady;
|
|
6450
6705
|
onChangeRef.current = onChange;
|
|
6451
6706
|
onErrorRef.current = onError;
|
|
6452
6707
|
}, [onReady, onChange, onError]);
|
|
6453
|
-
|
|
6708
|
+
React3.useEffect(() => {
|
|
6454
6709
|
if (!elements || !containerRef.current) return;
|
|
6455
6710
|
const element = elements.create(ELEMENT_TYPES.PAYMENT, { amount, currency });
|
|
6456
6711
|
elementRef.current = element;
|
|
@@ -6470,8 +6725,8 @@ function PaymentElement({
|
|
|
6470
6725
|
}
|
|
6471
6726
|
function useCheckout() {
|
|
6472
6727
|
const elements = useElements();
|
|
6473
|
-
const [isLoading, setIsLoading] =
|
|
6474
|
-
const submit =
|
|
6728
|
+
const [isLoading, setIsLoading] = React3.useState(false);
|
|
6729
|
+
const submit = React3.useCallback(
|
|
6475
6730
|
async (data) => {
|
|
6476
6731
|
if (!elements) {
|
|
6477
6732
|
return { success: false, error: { code: "NO_ELEMENTS", message: "Elements not initialized" } };
|
|
@@ -6485,7 +6740,7 @@ function useCheckout() {
|
|
|
6485
6740
|
},
|
|
6486
6741
|
[elements]
|
|
6487
6742
|
);
|
|
6488
|
-
const process =
|
|
6743
|
+
const process = React3.useCallback(
|
|
6489
6744
|
async (options) => {
|
|
6490
6745
|
if (!elements) {
|
|
6491
6746
|
return {
|
|
@@ -6513,6 +6768,7 @@ exports.CimplifyCheckout = CimplifyCheckout;
|
|
|
6513
6768
|
exports.CimplifyProvider = CimplifyProvider;
|
|
6514
6769
|
exports.ElementsProvider = ElementsProvider;
|
|
6515
6770
|
exports.PaymentElement = PaymentElement;
|
|
6771
|
+
exports.Price = Price;
|
|
6516
6772
|
exports.useAds = useAds;
|
|
6517
6773
|
exports.useBundle = useBundle;
|
|
6518
6774
|
exports.useCart = useCart;
|