@cimplify/sdk 0.30.0 → 0.35.0
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 +6 -2
- package/dist/advanced.d.ts +6 -2
- package/dist/advanced.js +21 -21
- package/dist/advanced.mjs +2 -2
- package/dist/{chunk-WGAVNFEQ.mjs → chunk-2X6P5WJZ.mjs} +117 -32
- package/dist/{chunk-E3HC2YAE.mjs → chunk-6TVQQYQ5.mjs} +14 -1
- package/dist/{chunk-2CGA3MUW.js → chunk-HKVRUGM6.js} +142 -91
- package/dist/{chunk-3J4PPSMI.mjs → chunk-TFHKVQLL.mjs} +123 -72
- package/dist/{chunk-PEDLCL72.js → chunk-V2O5AO7I.js} +15 -0
- package/dist/{chunk-F47XFKYP.js → chunk-ZYACIPKO.js} +169 -84
- package/dist/{index-DaXyvlxk.d.mts → client-CkGlXZRd.d.mts} +122 -72
- package/dist/{index-DTdtu4OO.d.ts → client-lvLvB1_K.d.ts} +122 -72
- package/dist/{index-D4oNCc37.d.mts → index-CC1JPhB2.d.mts} +2 -2
- package/dist/{index-BHVJgyqM.d.ts → index-CPcFayQg.d.ts} +2 -2
- package/dist/index.d.mts +6 -5
- package/dist/index.d.ts +6 -5
- package/dist/index.js +117 -109
- package/dist/index.mjs +3 -3
- package/dist/{payment-DnU_eLuT.d.mts → payment-DA1i5hhk.d.mts} +13 -12
- package/dist/{payment-DnU_eLuT.d.ts → payment-DA1i5hhk.d.ts} +13 -12
- package/dist/{price-DUVmRTaz.d.ts → price-Bv4G8aOO.d.ts} +1 -1
- package/dist/{price-D-hso3np.d.mts → price-s1XN0edJ.d.mts} +1 -1
- package/dist/react.d.mts +21 -5
- package/dist/react.d.ts +21 -5
- package/dist/react.js +908 -728
- package/dist/react.mjs +798 -618
- package/dist/styles.css +1 -1
- package/dist/utils.d.mts +3 -3
- package/dist/utils.d.ts +3 -3
- package/dist/utils.js +28 -28
- package/dist/utils.mjs +1 -1
- package/package.json +8 -8
- package/registry/cart-summary.json +1 -1
package/dist/react.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
var
|
|
4
|
+
var chunkZYACIPKO_js = require('./chunk-ZYACIPKO.js');
|
|
5
|
+
var chunkHKVRUGM6_js = require('./chunk-HKVRUGM6.js');
|
|
6
|
+
var chunkV2O5AO7I_js = require('./chunk-V2O5AO7I.js');
|
|
7
7
|
var React10 = require('react');
|
|
8
8
|
var jsxRuntime = require('react/jsx-runtime');
|
|
9
9
|
var clsx = require('clsx');
|
|
@@ -403,19 +403,114 @@ function transformToCheckoutCart(cart, fx) {
|
|
|
403
403
|
currency: fx?.displayCurrency ?? cart.pricing.currency
|
|
404
404
|
};
|
|
405
405
|
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
void store.clearCart();
|
|
406
|
+
|
|
407
|
+
// src/internal/collection.ts
|
|
408
|
+
function newOpId() {
|
|
409
|
+
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
410
|
+
return `op_${crypto.randomUUID()}`;
|
|
412
411
|
}
|
|
413
|
-
|
|
412
|
+
return `op_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
|
|
414
413
|
}
|
|
415
|
-
function
|
|
416
|
-
|
|
417
|
-
|
|
414
|
+
function createCollection(config) {
|
|
415
|
+
let base = config.initialBase ?? null;
|
|
416
|
+
let ops = [];
|
|
417
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
418
|
+
let cachedView;
|
|
419
|
+
let cachedBaseRef;
|
|
420
|
+
let cachedOpsVersion = -1;
|
|
421
|
+
let opsVersion = 0;
|
|
422
|
+
function notify() {
|
|
423
|
+
for (const listener of listeners) {
|
|
424
|
+
listener();
|
|
425
|
+
}
|
|
418
426
|
}
|
|
427
|
+
function recompute() {
|
|
428
|
+
if (cachedView !== void 0 && cachedBaseRef === base && cachedOpsVersion === opsVersion) {
|
|
429
|
+
return cachedView;
|
|
430
|
+
}
|
|
431
|
+
const view = config.toView(base, ops);
|
|
432
|
+
cachedView = view;
|
|
433
|
+
cachedBaseRef = base;
|
|
434
|
+
cachedOpsVersion = opsVersion;
|
|
435
|
+
return view;
|
|
436
|
+
}
|
|
437
|
+
return {
|
|
438
|
+
subscribe(listener) {
|
|
439
|
+
listeners.add(listener);
|
|
440
|
+
return () => {
|
|
441
|
+
listeners.delete(listener);
|
|
442
|
+
};
|
|
443
|
+
},
|
|
444
|
+
getSnapshot() {
|
|
445
|
+
return recompute();
|
|
446
|
+
},
|
|
447
|
+
setBase(next) {
|
|
448
|
+
base = next;
|
|
449
|
+
opsVersion++;
|
|
450
|
+
notify();
|
|
451
|
+
},
|
|
452
|
+
enqueue(patch, idempotencyKey) {
|
|
453
|
+
const op = {
|
|
454
|
+
id: newOpId(),
|
|
455
|
+
idempotencyKey,
|
|
456
|
+
patch,
|
|
457
|
+
status: "pending",
|
|
458
|
+
attemptCount: 0,
|
|
459
|
+
enqueuedAt: Date.now()
|
|
460
|
+
};
|
|
461
|
+
ops = [...ops, op];
|
|
462
|
+
opsVersion++;
|
|
463
|
+
notify();
|
|
464
|
+
return op.id;
|
|
465
|
+
},
|
|
466
|
+
confirm(opId, newBase) {
|
|
467
|
+
const idx = ops.findIndex((op) => op.id === opId);
|
|
468
|
+
if (idx === -1 && newBase === void 0) {
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
if (idx !== -1) {
|
|
472
|
+
ops = ops.filter((op) => op.id !== opId);
|
|
473
|
+
}
|
|
474
|
+
if (newBase !== void 0) {
|
|
475
|
+
base = newBase;
|
|
476
|
+
}
|
|
477
|
+
opsVersion++;
|
|
478
|
+
notify();
|
|
479
|
+
},
|
|
480
|
+
fail(opId, error) {
|
|
481
|
+
const idx = ops.findIndex((op) => op.id === opId);
|
|
482
|
+
if (idx === -1) return;
|
|
483
|
+
ops = ops.map(
|
|
484
|
+
(op, i) => i === idx ? {
|
|
485
|
+
...op,
|
|
486
|
+
status: "failed",
|
|
487
|
+
attemptCount: op.attemptCount + 1,
|
|
488
|
+
lastError: error
|
|
489
|
+
} : op
|
|
490
|
+
);
|
|
491
|
+
opsVersion++;
|
|
492
|
+
notify();
|
|
493
|
+
},
|
|
494
|
+
remove(opId) {
|
|
495
|
+
const next = ops.filter((op) => op.id !== opId);
|
|
496
|
+
if (next.length === ops.length) return;
|
|
497
|
+
ops = next;
|
|
498
|
+
opsVersion++;
|
|
499
|
+
notify();
|
|
500
|
+
},
|
|
501
|
+
getOps() {
|
|
502
|
+
return ops;
|
|
503
|
+
},
|
|
504
|
+
getBase() {
|
|
505
|
+
return base;
|
|
506
|
+
}
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// src/internal/cart-patches.ts
|
|
511
|
+
var DEFAULT_TAX_RATE = 0;
|
|
512
|
+
function toNumber(value) {
|
|
513
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
419
514
|
if (typeof value === "string") {
|
|
420
515
|
const parsed = Number.parseFloat(value);
|
|
421
516
|
return Number.isFinite(parsed) ? parsed : 0;
|
|
@@ -426,30 +521,20 @@ function roundMoney(value) {
|
|
|
426
521
|
return Math.max(0, Number(value.toFixed(2)));
|
|
427
522
|
}
|
|
428
523
|
function clampQuantity(quantity) {
|
|
429
|
-
if (!Number.isFinite(quantity))
|
|
430
|
-
return 1;
|
|
431
|
-
}
|
|
524
|
+
if (!Number.isFinite(quantity)) return 1;
|
|
432
525
|
return Math.max(1, Math.floor(quantity));
|
|
433
526
|
}
|
|
434
527
|
function normalizeOptionIds(value) {
|
|
435
|
-
if (!value || value.length === 0)
|
|
436
|
-
return void 0;
|
|
437
|
-
}
|
|
528
|
+
if (!value || value.length === 0) return void 0;
|
|
438
529
|
const normalized = Array.from(
|
|
439
|
-
new Set(
|
|
440
|
-
value.map((entry) => entry.trim()).filter((entry) => entry.length > 0)
|
|
441
|
-
)
|
|
530
|
+
new Set(value.map((entry) => entry.trim()).filter((entry) => entry.length > 0))
|
|
442
531
|
).sort();
|
|
443
532
|
return normalized.length > 0 ? normalized : void 0;
|
|
444
533
|
}
|
|
445
534
|
function buildLineKey(productId, options) {
|
|
446
535
|
const parts = [productId];
|
|
447
|
-
if (options.locationId) {
|
|
448
|
-
|
|
449
|
-
}
|
|
450
|
-
if (options.variantId) {
|
|
451
|
-
parts.push(`v:${options.variantId}`);
|
|
452
|
-
}
|
|
536
|
+
if (options.locationId) parts.push(`l:${options.locationId}`);
|
|
537
|
+
if (options.variantId) parts.push(`v:${options.variantId}`);
|
|
453
538
|
const addOnOptionIds = normalizeOptionIds(options.addOnOptionIds);
|
|
454
539
|
if (addOnOptionIds && addOnOptionIds.length > 0) {
|
|
455
540
|
parts.push(`a:${addOnOptionIds.join(",")}`);
|
|
@@ -460,41 +545,12 @@ function buildLineKey(productId, options) {
|
|
|
460
545
|
if (options.compositeSelections && options.compositeSelections.length > 0) {
|
|
461
546
|
parts.push(`c:${JSON.stringify(options.compositeSelections)}`);
|
|
462
547
|
}
|
|
463
|
-
if (options.quoteId) {
|
|
464
|
-
|
|
465
|
-
}
|
|
466
|
-
if (options.
|
|
467
|
-
parts.push(`ss:${options.scheduledStart}`);
|
|
468
|
-
}
|
|
469
|
-
if (options.staffId) {
|
|
470
|
-
parts.push(`st:${options.staffId}`);
|
|
471
|
-
}
|
|
472
|
-
if (options.resourceId) {
|
|
473
|
-
parts.push(`r:${options.resourceId}`);
|
|
474
|
-
}
|
|
548
|
+
if (options.quoteId) parts.push(`q:${options.quoteId}`);
|
|
549
|
+
if (options.scheduledStart) parts.push(`ss:${options.scheduledStart}`);
|
|
550
|
+
if (options.staffId) parts.push(`st:${options.staffId}`);
|
|
551
|
+
if (options.resourceId) parts.push(`r:${options.resourceId}`);
|
|
475
552
|
return parts.join("|");
|
|
476
553
|
}
|
|
477
|
-
function calculateLineSubtotal(item) {
|
|
478
|
-
let unitPrice = chunkPEDLCL72_js.parsePrice(item.product.default_price);
|
|
479
|
-
if (item.variant?.price_adjustment) {
|
|
480
|
-
unitPrice += chunkPEDLCL72_js.parsePrice(item.variant.price_adjustment);
|
|
481
|
-
}
|
|
482
|
-
for (const option of item.addOnOptions || []) {
|
|
483
|
-
if (option.default_price) {
|
|
484
|
-
unitPrice += chunkPEDLCL72_js.parsePrice(option.default_price);
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
return roundMoney(unitPrice * item.quantity);
|
|
488
|
-
}
|
|
489
|
-
function calculateSummary(items) {
|
|
490
|
-
const subtotal = roundMoney(items.reduce((sum, item) => sum + calculateLineSubtotal(item), 0));
|
|
491
|
-
const tax = roundMoney(subtotal * DEFAULT_TAX_RATE);
|
|
492
|
-
return {
|
|
493
|
-
subtotal,
|
|
494
|
-
tax,
|
|
495
|
-
total: roundMoney(subtotal + tax)
|
|
496
|
-
};
|
|
497
|
-
}
|
|
498
554
|
function lineKeyFromItem(item) {
|
|
499
555
|
return buildLineKey(item.product.id, {
|
|
500
556
|
locationId: item.locationId,
|
|
@@ -508,13 +564,103 @@ function lineKeyFromItem(item) {
|
|
|
508
564
|
});
|
|
509
565
|
}
|
|
510
566
|
function attachInternalItemMetadata(item) {
|
|
511
|
-
return {
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
567
|
+
return { ...item, _lineKey: lineKeyFromItem(item) };
|
|
568
|
+
}
|
|
569
|
+
function calculateLineSubtotal(item) {
|
|
570
|
+
let unitPrice = chunkV2O5AO7I_js.parsePrice(item.product.default_price);
|
|
571
|
+
if (item.variant?.price_adjustment) {
|
|
572
|
+
unitPrice += chunkV2O5AO7I_js.parsePrice(item.variant.price_adjustment);
|
|
573
|
+
}
|
|
574
|
+
for (const option of item.addOnOptions || []) {
|
|
575
|
+
if (option.default_price) unitPrice += chunkV2O5AO7I_js.parsePrice(option.default_price);
|
|
576
|
+
}
|
|
577
|
+
return roundMoney(unitPrice * item.quantity);
|
|
578
|
+
}
|
|
579
|
+
function calculateSummary(items) {
|
|
580
|
+
const subtotal = roundMoney(items.reduce((sum, item) => sum + calculateLineSubtotal(item), 0));
|
|
581
|
+
const tax = roundMoney(subtotal * DEFAULT_TAX_RATE);
|
|
582
|
+
return { subtotal, tax, total: roundMoney(subtotal + tax) };
|
|
583
|
+
}
|
|
584
|
+
function applyCartPatch(base, patch) {
|
|
585
|
+
switch (patch.kind) {
|
|
586
|
+
case "add_item": {
|
|
587
|
+
const existingIndex = base.items.findIndex(
|
|
588
|
+
(item) => (item._lineKey ?? lineKeyFromItem(item)) === patch.lineKey
|
|
589
|
+
);
|
|
590
|
+
const nextItems = [...base.items];
|
|
591
|
+
if (existingIndex >= 0) {
|
|
592
|
+
const existing = nextItems[existingIndex];
|
|
593
|
+
nextItems[existingIndex] = {
|
|
594
|
+
...existing,
|
|
595
|
+
quantity: existing.quantity + patch.tempItem.quantity
|
|
596
|
+
};
|
|
597
|
+
} else {
|
|
598
|
+
nextItems.push(patch.tempItem);
|
|
599
|
+
}
|
|
600
|
+
return { ...base, items: nextItems, ...calculateSummary(nextItems) };
|
|
601
|
+
}
|
|
602
|
+
case "remove_item": {
|
|
603
|
+
const nextItems = base.items.filter((item) => item.id !== patch.itemId);
|
|
604
|
+
return { ...base, items: nextItems, ...calculateSummary(nextItems) };
|
|
605
|
+
}
|
|
606
|
+
case "set_quantity": {
|
|
607
|
+
const resolved = clampQuantity(patch.quantity);
|
|
608
|
+
const nextItems = base.items.map(
|
|
609
|
+
(item) => item.id === patch.itemId ? { ...item, quantity: resolved } : item
|
|
610
|
+
);
|
|
611
|
+
return { ...base, items: nextItems, ...calculateSummary(nextItems) };
|
|
612
|
+
}
|
|
613
|
+
case "clear": {
|
|
614
|
+
return { ...base, items: [], subtotal: 0, tax: 0, total: 0 };
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
function useCollectionStore(collection) {
|
|
619
|
+
return React10.useSyncExternalStore(
|
|
620
|
+
(listener) => collection.subscribe(listener),
|
|
621
|
+
() => collection.getSnapshot(),
|
|
622
|
+
() => collection.getSnapshot()
|
|
623
|
+
);
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
// src/react/hooks/use-cart.ts
|
|
627
|
+
var CART_STORAGE_PREFIX = "cimplify:cart:v3";
|
|
628
|
+
var cartStores = /* @__PURE__ */ new Map();
|
|
629
|
+
var ROLLBACK_VISIBLE_DELAY_MS = 3e3;
|
|
630
|
+
function clearAllCartStores() {
|
|
631
|
+
for (const [, entry] of cartStores) {
|
|
632
|
+
entry.collection.setBase(emptyBase(entry.currency));
|
|
633
|
+
for (const handle of entry.failedOpRemovers) {
|
|
634
|
+
clearTimeout(handle);
|
|
635
|
+
}
|
|
636
|
+
entry.failedOpRemovers.clear();
|
|
637
|
+
if (entry.persistTimer) {
|
|
638
|
+
clearTimeout(entry.persistTimer);
|
|
639
|
+
entry.persistTimer = null;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
cartStores.clear();
|
|
643
|
+
}
|
|
644
|
+
function emptyBase(currency, isLoading = true) {
|
|
645
|
+
return { items: [], subtotal: 0, tax: 0, total: 0, currency, isLoading };
|
|
646
|
+
}
|
|
647
|
+
function advanceBaseWithPatch(entry, patch) {
|
|
648
|
+
const current = entry.collection.getBase() ?? emptyBase(entry.currency, false);
|
|
649
|
+
entry.collection.setBase({ ...applyCartPatch(current, patch), isLoading: false });
|
|
650
|
+
persistBase(entry);
|
|
651
|
+
}
|
|
652
|
+
function buildStoreKey(client, locationId, isDemoMode) {
|
|
653
|
+
return [
|
|
654
|
+
client.getPublicKey() || "__demo__",
|
|
655
|
+
locationId || "__no_location__",
|
|
656
|
+
isDemoMode ? "demo" : "live"
|
|
657
|
+
].join(":");
|
|
658
|
+
}
|
|
659
|
+
function buildStorageKey(storeKey) {
|
|
660
|
+
return `${CART_STORAGE_PREFIX}:${storeKey}`;
|
|
515
661
|
}
|
|
516
662
|
function stripInternalItemMetadata(item) {
|
|
517
|
-
const { _lineKey, ...rest } = item;
|
|
663
|
+
const { _lineKey, isOptimistic, ...rest } = item;
|
|
518
664
|
return rest;
|
|
519
665
|
}
|
|
520
666
|
function toProductFromServerItem(item, businessId) {
|
|
@@ -533,12 +679,10 @@ function toProductFromServerItem(item, businessId) {
|
|
|
533
679
|
is_active: item.is_available,
|
|
534
680
|
created_at: item.created_at,
|
|
535
681
|
updated_at: item.updated_at,
|
|
536
|
-
metadata: {
|
|
537
|
-
from_sdk: true
|
|
538
|
-
}
|
|
682
|
+
metadata: { from_sdk: true }
|
|
539
683
|
};
|
|
540
684
|
}
|
|
541
|
-
function mapServerCart(serverCart) {
|
|
685
|
+
function mapServerCart(serverCart, fallbackCurrency) {
|
|
542
686
|
const items = serverCart.items.map((item) => {
|
|
543
687
|
const variant = item.variant_info || item.variant_name ? {
|
|
544
688
|
id: item.variant_info?.id || item.variant_id || "",
|
|
@@ -579,207 +723,219 @@ function mapServerCart(serverCart) {
|
|
|
579
723
|
subtotal: roundMoney(toNumber(serverCart.pricing.subtotal)),
|
|
580
724
|
tax: roundMoney(toNumber(serverCart.pricing.tax_amount)),
|
|
581
725
|
total: roundMoney(toNumber(serverCart.pricing.total_price)),
|
|
582
|
-
currency: serverCart.pricing.currency ||
|
|
726
|
+
currency: serverCart.pricing.currency || fallbackCurrency,
|
|
727
|
+
isLoading: false
|
|
583
728
|
};
|
|
584
729
|
}
|
|
585
|
-
function
|
|
586
|
-
return
|
|
587
|
-
|
|
588
|
-
|
|
730
|
+
function annotateOptimisticItems(base, ops) {
|
|
731
|
+
if (ops.length === 0) return base;
|
|
732
|
+
const optimisticIds = /* @__PURE__ */ new Set();
|
|
733
|
+
for (const op of ops) {
|
|
734
|
+
if (op.patch.kind === "add_item") {
|
|
735
|
+
optimisticIds.add(op.patch.tempItem.id);
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
if (optimisticIds.size === 0) return base;
|
|
589
739
|
return {
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
currency,
|
|
595
|
-
isLoading: true
|
|
740
|
+
...base,
|
|
741
|
+
items: base.items.map(
|
|
742
|
+
(item) => optimisticIds.has(item.id) ? { ...item, isOptimistic: true } : item
|
|
743
|
+
)
|
|
596
744
|
};
|
|
597
745
|
}
|
|
598
|
-
function
|
|
599
|
-
const
|
|
600
|
-
|
|
601
|
-
const
|
|
602
|
-
|
|
603
|
-
let initialized = false;
|
|
604
|
-
let initializePromise = null;
|
|
605
|
-
let persistTimer = null;
|
|
606
|
-
function emit() {
|
|
607
|
-
listeners.forEach((listener) => {
|
|
608
|
-
listener();
|
|
609
|
-
});
|
|
610
|
-
}
|
|
611
|
-
function setSnapshot(nextSnapshot) {
|
|
612
|
-
snapshot = nextSnapshot;
|
|
613
|
-
schedulePersist();
|
|
614
|
-
emit();
|
|
615
|
-
}
|
|
616
|
-
function updateSnapshot(updater) {
|
|
617
|
-
setSnapshot(updater(snapshot));
|
|
746
|
+
function deriveView(base, ops) {
|
|
747
|
+
const start = base ?? emptyBase("USD");
|
|
748
|
+
let folded = start;
|
|
749
|
+
for (const op of ops) {
|
|
750
|
+
folded = applyCartPatch(folded, op.patch);
|
|
618
751
|
}
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
752
|
+
folded = annotateOptimisticItems(folded, ops);
|
|
753
|
+
return {
|
|
754
|
+
...folded,
|
|
755
|
+
isOptimistic: ops.length > 0,
|
|
756
|
+
pendingOpCount: ops.length
|
|
757
|
+
};
|
|
758
|
+
}
|
|
759
|
+
function persistBase(entry) {
|
|
760
|
+
if (typeof window === "undefined" || !window.localStorage) return;
|
|
761
|
+
if (entry.persistTimer) return;
|
|
762
|
+
entry.persistTimer = setTimeout(() => {
|
|
763
|
+
entry.persistTimer = null;
|
|
764
|
+
if (typeof window === "undefined" || !window.localStorage) return;
|
|
765
|
+
const base = entry.collection.getBase();
|
|
766
|
+
if (!base) return;
|
|
623
767
|
try {
|
|
624
768
|
window.localStorage.setItem(
|
|
625
|
-
storageKey,
|
|
769
|
+
entry.storageKey,
|
|
626
770
|
JSON.stringify({
|
|
627
|
-
items:
|
|
628
|
-
subtotal:
|
|
629
|
-
tax:
|
|
630
|
-
total:
|
|
631
|
-
currency:
|
|
771
|
+
items: base.items.map((item) => stripInternalItemMetadata(item)),
|
|
772
|
+
subtotal: base.subtotal,
|
|
773
|
+
tax: base.tax,
|
|
774
|
+
total: base.total,
|
|
775
|
+
currency: base.currency
|
|
632
776
|
})
|
|
633
777
|
);
|
|
634
778
|
} catch {
|
|
635
779
|
}
|
|
780
|
+
}, 100);
|
|
781
|
+
}
|
|
782
|
+
function hydrateFromStorage(entry) {
|
|
783
|
+
if (typeof window === "undefined" || !window.localStorage) return;
|
|
784
|
+
try {
|
|
785
|
+
const raw = window.localStorage.getItem(entry.storageKey);
|
|
786
|
+
if (!raw) return;
|
|
787
|
+
const parsed = JSON.parse(raw);
|
|
788
|
+
if (!parsed || !Array.isArray(parsed.items)) return;
|
|
789
|
+
const items = parsed.items.map((item) => attachInternalItemMetadata(item));
|
|
790
|
+
entry.collection.setBase({
|
|
791
|
+
items,
|
|
792
|
+
subtotal: toNumber(parsed.subtotal),
|
|
793
|
+
tax: toNumber(parsed.tax),
|
|
794
|
+
total: toNumber(parsed.total),
|
|
795
|
+
currency: typeof parsed.currency === "string" && parsed.currency ? parsed.currency : entry.currency,
|
|
796
|
+
isLoading: !entry.isDemoMode
|
|
797
|
+
});
|
|
798
|
+
} catch {
|
|
636
799
|
}
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
persistSnapshot();
|
|
644
|
-
}, 100);
|
|
800
|
+
}
|
|
801
|
+
async function syncFromServer(entry) {
|
|
802
|
+
if (entry.isDemoMode) {
|
|
803
|
+
const base = entry.collection.getBase() ?? emptyBase(entry.currency);
|
|
804
|
+
entry.collection.setBase({ ...base, isLoading: false });
|
|
805
|
+
return;
|
|
645
806
|
}
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
807
|
+
if (entry.syncing) return;
|
|
808
|
+
entry.syncing = true;
|
|
809
|
+
try {
|
|
810
|
+
const result = await entry.client.cart.get();
|
|
811
|
+
if (!result.ok) throw result.error;
|
|
812
|
+
entry.collection.setBase(mapServerCart(result.value, entry.currency));
|
|
813
|
+
persistBase(entry);
|
|
814
|
+
} finally {
|
|
815
|
+
entry.syncing = false;
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
function emitMutationError(entry, operation, opId, idempotencyKey, error) {
|
|
819
|
+
entry.client.events.emit("mutation:error", {
|
|
820
|
+
service: "cart",
|
|
821
|
+
operation,
|
|
822
|
+
opId,
|
|
823
|
+
idempotencyKey,
|
|
824
|
+
error
|
|
825
|
+
});
|
|
826
|
+
}
|
|
827
|
+
function scheduleFailedOpRemoval(entry, opId) {
|
|
828
|
+
const handle = setTimeout(() => {
|
|
829
|
+
entry.failedOpRemovers.delete(handle);
|
|
830
|
+
entry.collection.remove(opId);
|
|
831
|
+
}, ROLLBACK_VISIBLE_DELAY_MS);
|
|
832
|
+
entry.failedOpRemovers.add(handle);
|
|
833
|
+
}
|
|
834
|
+
function getOrCreateStore(params) {
|
|
835
|
+
const { client, locationId, isDemoMode, currency, optimisticEnabled } = params;
|
|
836
|
+
const storeKey = buildStoreKey(client, locationId, isDemoMode);
|
|
837
|
+
const existing = cartStores.get(storeKey);
|
|
838
|
+
if (existing) {
|
|
839
|
+
existing.optimisticEnabled = optimisticEnabled;
|
|
840
|
+
return existing;
|
|
670
841
|
}
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
842
|
+
const collection = createCollection({
|
|
843
|
+
applyPatch: applyCartPatch,
|
|
844
|
+
toView: (base, ops) => deriveView(base, ops),
|
|
845
|
+
initialBase: emptyBase(currency)
|
|
846
|
+
});
|
|
847
|
+
const entry = {
|
|
848
|
+
collection,
|
|
849
|
+
client,
|
|
850
|
+
storageKey: buildStorageKey(storeKey),
|
|
851
|
+
locationId,
|
|
852
|
+
currency,
|
|
853
|
+
isDemoMode,
|
|
854
|
+
optimisticEnabled,
|
|
855
|
+
initialized: false,
|
|
856
|
+
initializePromise: null,
|
|
857
|
+
persistTimer: null,
|
|
858
|
+
syncing: false,
|
|
859
|
+
failedOpRemovers: /* @__PURE__ */ new Set()
|
|
860
|
+
};
|
|
861
|
+
cartStores.set(storeKey, entry);
|
|
862
|
+
return entry;
|
|
863
|
+
}
|
|
864
|
+
async function ensureInitialized(entry) {
|
|
865
|
+
if (entry.initialized) {
|
|
866
|
+
if (entry.initializePromise) await entry.initializePromise;
|
|
867
|
+
return;
|
|
696
868
|
}
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
options.variantId || addOnOptionIds && addOnOptionIds.length > 0 || options.bundleSelections && options.bundleSelections.length > 0 || options.compositeSelections && options.compositeSelections.length > 0
|
|
704
|
-
);
|
|
705
|
-
if (!requiresQuote || isDemoMode) {
|
|
706
|
-
return void 0;
|
|
707
|
-
}
|
|
708
|
-
const quoteResult = await client.catalogue.fetchQuote({
|
|
709
|
-
product_id: product.id,
|
|
710
|
-
quantity,
|
|
711
|
-
location_id: options.locationId || locationId || void 0,
|
|
712
|
-
variant_id: options.variantId,
|
|
713
|
-
add_on_option_ids: addOnOptionIds,
|
|
714
|
-
bundle_selections: options.bundleSelections,
|
|
715
|
-
composite_selections: options.compositeSelections
|
|
716
|
-
});
|
|
717
|
-
if (!quoteResult.ok) {
|
|
718
|
-
throw quoteResult.error;
|
|
719
|
-
}
|
|
720
|
-
return quoteResult.value.quote_id;
|
|
869
|
+
entry.initialized = true;
|
|
870
|
+
hydrateFromStorage(entry);
|
|
871
|
+
if (entry.isDemoMode) {
|
|
872
|
+
const base = entry.collection.getBase() ?? emptyBase(entry.currency);
|
|
873
|
+
entry.collection.setBase({ ...base, isLoading: false });
|
|
874
|
+
return;
|
|
721
875
|
}
|
|
722
|
-
|
|
723
|
-
const
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
876
|
+
entry.initializePromise = syncFromServer(entry).catch(() => {
|
|
877
|
+
const base = entry.collection.getBase() ?? emptyBase(entry.currency);
|
|
878
|
+
entry.collection.setBase({ ...base, isLoading: false });
|
|
879
|
+
});
|
|
880
|
+
await entry.initializePromise;
|
|
881
|
+
entry.initializePromise = null;
|
|
882
|
+
}
|
|
883
|
+
async function maybeResolveQuoteId(entry, product, quantity, options) {
|
|
884
|
+
if (options.quoteId) return options.quoteId;
|
|
885
|
+
const addOnOptionIds = normalizeOptionIds(options.addOnOptionIds);
|
|
886
|
+
const requiresQuote = Boolean(
|
|
887
|
+
options.variantId || addOnOptionIds && addOnOptionIds.length > 0 || options.bundleSelections && options.bundleSelections.length > 0 || options.compositeSelections && options.compositeSelections.length > 0
|
|
888
|
+
);
|
|
889
|
+
if (!requiresQuote || entry.isDemoMode) return void 0;
|
|
890
|
+
const quoteResult = await entry.client.catalogue.fetchQuote({
|
|
891
|
+
product_id: product.id,
|
|
892
|
+
quantity,
|
|
893
|
+
location_id: options.locationId || entry.locationId || void 0,
|
|
894
|
+
variant_id: options.variantId,
|
|
895
|
+
add_on_option_ids: addOnOptionIds,
|
|
896
|
+
bundle_selections: options.bundleSelections,
|
|
897
|
+
composite_selections: options.compositeSelections
|
|
898
|
+
});
|
|
899
|
+
if (!quoteResult.ok) throw quoteResult.error;
|
|
900
|
+
return quoteResult.value.quote_id;
|
|
901
|
+
}
|
|
902
|
+
async function performAddItem(entry, product, quantity, options) {
|
|
903
|
+
const resolvedQuantity = clampQuantity(quantity);
|
|
904
|
+
const normalizedOptions = {
|
|
905
|
+
...options,
|
|
906
|
+
locationId: options.locationId || entry.locationId || void 0,
|
|
907
|
+
addOnOptionIds: normalizeOptionIds(options.addOnOptionIds)
|
|
908
|
+
};
|
|
909
|
+
const lineKey = buildLineKey(product.id, normalizedOptions);
|
|
910
|
+
const tempItem = attachInternalItemMetadata({
|
|
911
|
+
id: `tmp_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`,
|
|
912
|
+
product,
|
|
913
|
+
quantity: resolvedQuantity,
|
|
914
|
+
locationId: normalizedOptions.locationId,
|
|
915
|
+
variantId: normalizedOptions.variantId,
|
|
916
|
+
variant: normalizedOptions.variant,
|
|
917
|
+
quoteId: normalizedOptions.quoteId,
|
|
918
|
+
addOnOptionIds: normalizedOptions.addOnOptionIds,
|
|
919
|
+
addOnOptions: normalizedOptions.addOnOptions,
|
|
920
|
+
bundleSelections: normalizedOptions.bundleSelections,
|
|
921
|
+
compositeSelections: normalizedOptions.compositeSelections,
|
|
922
|
+
specialInstructions: normalizedOptions.specialInstructions,
|
|
923
|
+
scheduledStart: normalizedOptions.scheduledStart,
|
|
924
|
+
scheduledEnd: normalizedOptions.scheduledEnd,
|
|
925
|
+
staffId: normalizedOptions.staffId
|
|
926
|
+
});
|
|
927
|
+
const idempotencyKey = `idem_${typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : `${Date.now()}_${Math.random().toString(36).slice(2, 10)}`}`;
|
|
928
|
+
const patch = { kind: "add_item", tempItem, lineKey };
|
|
929
|
+
if (entry.isDemoMode) {
|
|
930
|
+
advanceBaseWithPatch(entry, patch);
|
|
931
|
+
return;
|
|
932
|
+
}
|
|
933
|
+
const useOptimistic = entry.optimisticEnabled;
|
|
934
|
+
const opId = useOptimistic ? entry.collection.enqueue(patch, idempotencyKey) : null;
|
|
935
|
+
try {
|
|
936
|
+
const quoteId = await maybeResolveQuoteId(entry, product, resolvedQuantity, normalizedOptions);
|
|
937
|
+
const result = await entry.client.cart.addItem(
|
|
938
|
+
{
|
|
783
939
|
item_id: product.id,
|
|
784
940
|
quantity: resolvedQuantity,
|
|
785
941
|
variant_id: normalizedOptions.variantId,
|
|
@@ -793,186 +949,103 @@ function createCartStore(params) {
|
|
|
793
949
|
staff_id: normalizedOptions.staffId,
|
|
794
950
|
resource_id: normalizedOptions.resourceId,
|
|
795
951
|
customer_inputs: normalizedOptions.customerInputs
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
total: summary.total
|
|
819
|
-
};
|
|
820
|
-
});
|
|
821
|
-
if (isDemoMode) {
|
|
822
|
-
return;
|
|
823
|
-
}
|
|
824
|
-
try {
|
|
825
|
-
const result = await client.cart.removeItem(itemId);
|
|
826
|
-
if (!result.ok) {
|
|
827
|
-
throw result.error;
|
|
828
|
-
}
|
|
829
|
-
await sync();
|
|
830
|
-
} catch (error) {
|
|
831
|
-
snapshot = previousSnapshot;
|
|
832
|
-
persistSnapshot();
|
|
833
|
-
emit();
|
|
834
|
-
throw error;
|
|
835
|
-
}
|
|
952
|
+
},
|
|
953
|
+
{ idempotencyKey }
|
|
954
|
+
);
|
|
955
|
+
if (!result.ok) throw result.error;
|
|
956
|
+
await syncFromServer(entry);
|
|
957
|
+
if (opId) entry.collection.confirm(opId);
|
|
958
|
+
} catch (error) {
|
|
959
|
+
const cimplifyError = error;
|
|
960
|
+
if (opId) {
|
|
961
|
+
entry.collection.fail(opId, cimplifyError);
|
|
962
|
+
emitMutationError(entry, "add_item", opId, idempotencyKey, cimplifyError);
|
|
963
|
+
scheduleFailedOpRemoval(entry, opId);
|
|
964
|
+
}
|
|
965
|
+
throw cimplifyError;
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
async function performRemoveItem(entry, itemId) {
|
|
969
|
+
const idempotencyKey = "";
|
|
970
|
+
const patch = { kind: "remove_item", itemId };
|
|
971
|
+
if (entry.isDemoMode) {
|
|
972
|
+
advanceBaseWithPatch(entry, patch);
|
|
973
|
+
return;
|
|
836
974
|
}
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
const result = await client.cart.updateQuantity(itemId, resolvedQuantity);
|
|
865
|
-
if (!result.ok) {
|
|
866
|
-
throw result.error;
|
|
867
|
-
}
|
|
868
|
-
await sync();
|
|
869
|
-
} catch (error) {
|
|
870
|
-
snapshot = previousSnapshot;
|
|
871
|
-
persistSnapshot();
|
|
872
|
-
emit();
|
|
873
|
-
throw error;
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
async function clearCart() {
|
|
877
|
-
const previousSnapshot = snapshot;
|
|
878
|
-
updateSnapshot((current) => ({
|
|
879
|
-
...current,
|
|
880
|
-
items: [],
|
|
881
|
-
subtotal: 0,
|
|
882
|
-
tax: 0,
|
|
883
|
-
total: 0
|
|
884
|
-
}));
|
|
885
|
-
if (isDemoMode) {
|
|
886
|
-
return;
|
|
887
|
-
}
|
|
888
|
-
try {
|
|
889
|
-
const result = await client.cart.clear();
|
|
890
|
-
if (!result.ok) {
|
|
891
|
-
throw result.error;
|
|
892
|
-
}
|
|
893
|
-
await sync();
|
|
894
|
-
} catch (error) {
|
|
895
|
-
snapshot = previousSnapshot;
|
|
896
|
-
persistSnapshot();
|
|
897
|
-
emit();
|
|
898
|
-
throw error;
|
|
899
|
-
}
|
|
975
|
+
const useOptimistic = entry.optimisticEnabled;
|
|
976
|
+
const opId = useOptimistic ? entry.collection.enqueue(patch, idempotencyKey) : null;
|
|
977
|
+
try {
|
|
978
|
+
const result = await entry.client.cart.removeItem(itemId);
|
|
979
|
+
if (!result.ok) throw result.error;
|
|
980
|
+
await syncFromServer(entry);
|
|
981
|
+
if (opId) entry.collection.confirm(opId);
|
|
982
|
+
} catch (error) {
|
|
983
|
+
const cimplifyError = error;
|
|
984
|
+
if (opId) {
|
|
985
|
+
entry.collection.fail(opId, cimplifyError);
|
|
986
|
+
emitMutationError(entry, "remove_item", opId, idempotencyKey, cimplifyError);
|
|
987
|
+
scheduleFailedOpRemoval(entry, opId);
|
|
988
|
+
}
|
|
989
|
+
throw cimplifyError;
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
async function performUpdateQuantity(entry, itemId, quantity) {
|
|
993
|
+
if (quantity <= 0) {
|
|
994
|
+
return performRemoveItem(entry, itemId);
|
|
995
|
+
}
|
|
996
|
+
const resolved = clampQuantity(quantity);
|
|
997
|
+
const idempotencyKey = "";
|
|
998
|
+
const patch = { kind: "set_quantity", itemId, quantity: resolved };
|
|
999
|
+
if (entry.isDemoMode) {
|
|
1000
|
+
advanceBaseWithPatch(entry, patch);
|
|
1001
|
+
return;
|
|
900
1002
|
}
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
if (
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
initializePromise = null;
|
|
1003
|
+
const useOptimistic = entry.optimisticEnabled;
|
|
1004
|
+
const opId = useOptimistic ? entry.collection.enqueue(patch, idempotencyKey) : null;
|
|
1005
|
+
try {
|
|
1006
|
+
const result = await entry.client.cart.updateQuantity(itemId, resolved);
|
|
1007
|
+
if (!result.ok) throw result.error;
|
|
1008
|
+
await syncFromServer(entry);
|
|
1009
|
+
if (opId) entry.collection.confirm(opId);
|
|
1010
|
+
} catch (error) {
|
|
1011
|
+
const cimplifyError = error;
|
|
1012
|
+
if (opId) {
|
|
1013
|
+
entry.collection.fail(opId, cimplifyError);
|
|
1014
|
+
emitMutationError(entry, "update_quantity", opId, idempotencyKey, cimplifyError);
|
|
1015
|
+
scheduleFailedOpRemoval(entry, opId);
|
|
1016
|
+
}
|
|
1017
|
+
throw cimplifyError;
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
async function performClear(entry) {
|
|
1021
|
+
const idempotencyKey = "";
|
|
1022
|
+
const patch = { kind: "clear" };
|
|
1023
|
+
if (entry.isDemoMode) {
|
|
1024
|
+
advanceBaseWithPatch(entry, patch);
|
|
1025
|
+
return;
|
|
925
1026
|
}
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
1027
|
+
const useOptimistic = entry.optimisticEnabled;
|
|
1028
|
+
const opId = useOptimistic ? entry.collection.enqueue(patch, idempotencyKey) : null;
|
|
1029
|
+
try {
|
|
1030
|
+
const result = await entry.client.cart.clear();
|
|
1031
|
+
if (!result.ok) throw result.error;
|
|
1032
|
+
await syncFromServer(entry);
|
|
1033
|
+
if (opId) entry.collection.confirm(opId);
|
|
1034
|
+
} catch (error) {
|
|
1035
|
+
const cimplifyError = error;
|
|
1036
|
+
if (opId) {
|
|
1037
|
+
entry.collection.fail(opId, cimplifyError);
|
|
1038
|
+
emitMutationError(entry, "clear", opId, idempotencyKey, cimplifyError);
|
|
1039
|
+
scheduleFailedOpRemoval(entry, opId);
|
|
930
1040
|
}
|
|
931
|
-
|
|
932
|
-
return result.value;
|
|
1041
|
+
throw cimplifyError;
|
|
933
1042
|
}
|
|
934
|
-
return {
|
|
935
|
-
subscribe(listener) {
|
|
936
|
-
listeners.add(listener);
|
|
937
|
-
return () => {
|
|
938
|
-
listeners.delete(listener);
|
|
939
|
-
};
|
|
940
|
-
},
|
|
941
|
-
getSnapshot() {
|
|
942
|
-
return snapshot;
|
|
943
|
-
},
|
|
944
|
-
initialize,
|
|
945
|
-
addItem,
|
|
946
|
-
removeItem,
|
|
947
|
-
updateQuantity,
|
|
948
|
-
clearCart,
|
|
949
|
-
sync,
|
|
950
|
-
reorder
|
|
951
|
-
};
|
|
952
1043
|
}
|
|
953
|
-
function
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
].join(":");
|
|
959
|
-
}
|
|
960
|
-
function getOrCreateStore(params) {
|
|
961
|
-
const { client, locationId, isDemoMode, currency } = params;
|
|
962
|
-
const storeKey = getStoreKey(client, locationId, isDemoMode);
|
|
963
|
-
const existing = cartStores.get(storeKey);
|
|
964
|
-
if (existing) {
|
|
965
|
-
return existing;
|
|
966
|
-
}
|
|
967
|
-
const created = createCartStore({
|
|
968
|
-
client,
|
|
969
|
-
storeKey,
|
|
970
|
-
locationId,
|
|
971
|
-
isDemoMode,
|
|
972
|
-
currency
|
|
973
|
-
});
|
|
974
|
-
cartStores.set(storeKey, created);
|
|
975
|
-
return created;
|
|
1044
|
+
async function performReorder(entry, orderId) {
|
|
1045
|
+
const result = await entry.client.cart.reorderFromOrder(orderId);
|
|
1046
|
+
if (!result.ok) throw result.error;
|
|
1047
|
+
await syncFromServer(entry);
|
|
1048
|
+
return result.value;
|
|
976
1049
|
}
|
|
977
1050
|
function useCart(options = {}) {
|
|
978
1051
|
const context = useOptionalCimplifyClient();
|
|
@@ -983,77 +1056,92 @@ function useCart(options = {}) {
|
|
|
983
1056
|
const locationId = options.locationId ?? client.getLocationId();
|
|
984
1057
|
const isDemoMode = options.demoMode ?? context?.isDemoMode ?? client.getPublicKey().trim().length === 0;
|
|
985
1058
|
const currency = options.currency ?? context?.currency ?? "USD";
|
|
986
|
-
const
|
|
1059
|
+
const optimisticEnabled = context?.optimistic ?? true;
|
|
1060
|
+
const entry = React10.useMemo(
|
|
987
1061
|
() => getOrCreateStore({
|
|
988
1062
|
client,
|
|
989
1063
|
locationId,
|
|
990
1064
|
isDemoMode,
|
|
991
|
-
currency
|
|
1065
|
+
currency,
|
|
1066
|
+
optimisticEnabled
|
|
992
1067
|
}),
|
|
993
|
-
[client, currency, isDemoMode, locationId]
|
|
994
|
-
);
|
|
995
|
-
const snapshot = React10.useSyncExternalStore(
|
|
996
|
-
store.subscribe,
|
|
997
|
-
store.getSnapshot,
|
|
998
|
-
store.getSnapshot
|
|
1068
|
+
[client, currency, isDemoMode, locationId, optimisticEnabled]
|
|
999
1069
|
);
|
|
1070
|
+
const view = useCollectionStore(entry.collection);
|
|
1000
1071
|
React10.useEffect(() => {
|
|
1001
|
-
void
|
|
1002
|
-
}, [
|
|
1072
|
+
void ensureInitialized(entry);
|
|
1073
|
+
}, [entry]);
|
|
1003
1074
|
const addItem = React10.useCallback(
|
|
1004
1075
|
async (product, quantity, addOptions) => {
|
|
1005
|
-
await
|
|
1076
|
+
await performAddItem(entry, product, quantity ?? 1, addOptions ?? {});
|
|
1006
1077
|
},
|
|
1007
|
-
[
|
|
1078
|
+
[entry]
|
|
1008
1079
|
);
|
|
1009
1080
|
const removeItem = React10.useCallback(
|
|
1010
1081
|
async (itemId) => {
|
|
1011
|
-
await
|
|
1082
|
+
await performRemoveItem(entry, itemId);
|
|
1012
1083
|
},
|
|
1013
|
-
[
|
|
1084
|
+
[entry]
|
|
1014
1085
|
);
|
|
1015
1086
|
const updateQuantity = React10.useCallback(
|
|
1016
1087
|
async (itemId, quantity) => {
|
|
1017
|
-
await
|
|
1088
|
+
await performUpdateQuantity(entry, itemId, quantity);
|
|
1018
1089
|
},
|
|
1019
|
-
[
|
|
1090
|
+
[entry]
|
|
1020
1091
|
);
|
|
1021
1092
|
const clearCart = React10.useCallback(async () => {
|
|
1022
|
-
await
|
|
1023
|
-
}, [
|
|
1093
|
+
await performClear(entry);
|
|
1094
|
+
}, [entry]);
|
|
1024
1095
|
const sync = React10.useCallback(async () => {
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
} catch (syncError) {
|
|
1028
|
-
throw syncError;
|
|
1029
|
-
}
|
|
1030
|
-
}, [store]);
|
|
1096
|
+
await syncFromServer(entry);
|
|
1097
|
+
}, [entry]);
|
|
1031
1098
|
const reorder = React10.useCallback(
|
|
1032
1099
|
async (orderId) => {
|
|
1033
|
-
return
|
|
1100
|
+
return performReorder(entry, orderId);
|
|
1034
1101
|
},
|
|
1035
|
-
[
|
|
1102
|
+
[entry]
|
|
1036
1103
|
);
|
|
1037
1104
|
const itemCount = React10.useMemo(
|
|
1038
|
-
() =>
|
|
1039
|
-
[
|
|
1105
|
+
() => view.items.reduce((sum, item) => sum + item.quantity, 0),
|
|
1106
|
+
[view.items]
|
|
1107
|
+
);
|
|
1108
|
+
return React10.useMemo(
|
|
1109
|
+
() => ({
|
|
1110
|
+
items: view.items,
|
|
1111
|
+
itemCount,
|
|
1112
|
+
subtotal: view.subtotal,
|
|
1113
|
+
tax: view.tax,
|
|
1114
|
+
total: view.total,
|
|
1115
|
+
currency: view.currency,
|
|
1116
|
+
isEmpty: itemCount === 0,
|
|
1117
|
+
isLoading: view.isLoading,
|
|
1118
|
+
isOptimistic: view.isOptimistic,
|
|
1119
|
+
pendingOpCount: view.pendingOpCount,
|
|
1120
|
+
addItem,
|
|
1121
|
+
removeItem,
|
|
1122
|
+
updateQuantity,
|
|
1123
|
+
clearCart,
|
|
1124
|
+
sync,
|
|
1125
|
+
reorder
|
|
1126
|
+
}),
|
|
1127
|
+
[
|
|
1128
|
+
view.items,
|
|
1129
|
+
itemCount,
|
|
1130
|
+
view.subtotal,
|
|
1131
|
+
view.tax,
|
|
1132
|
+
view.total,
|
|
1133
|
+
view.currency,
|
|
1134
|
+
view.isLoading,
|
|
1135
|
+
view.isOptimistic,
|
|
1136
|
+
view.pendingOpCount,
|
|
1137
|
+
addItem,
|
|
1138
|
+
removeItem,
|
|
1139
|
+
updateQuantity,
|
|
1140
|
+
clearCart,
|
|
1141
|
+
sync,
|
|
1142
|
+
reorder
|
|
1143
|
+
]
|
|
1040
1144
|
);
|
|
1041
|
-
return React10.useMemo(() => ({
|
|
1042
|
-
items: snapshot.items,
|
|
1043
|
-
itemCount,
|
|
1044
|
-
subtotal: snapshot.subtotal,
|
|
1045
|
-
tax: snapshot.tax,
|
|
1046
|
-
total: snapshot.total,
|
|
1047
|
-
currency: snapshot.currency,
|
|
1048
|
-
isEmpty: itemCount === 0,
|
|
1049
|
-
isLoading: snapshot.isLoading,
|
|
1050
|
-
addItem,
|
|
1051
|
-
removeItem,
|
|
1052
|
-
updateQuantity,
|
|
1053
|
-
clearCart,
|
|
1054
|
-
sync,
|
|
1055
|
-
reorder
|
|
1056
|
-
}), [snapshot.items, itemCount, snapshot.subtotal, snapshot.tax, snapshot.total, snapshot.currency, snapshot.isLoading, addItem, removeItem, updateQuantity, clearCart, sync, reorder]);
|
|
1057
1145
|
}
|
|
1058
1146
|
var LOCATION_STORAGE_KEY = "cimplify_location_id";
|
|
1059
1147
|
var DISPLAY_CURRENCY_STORAGE_KEY = "cimplify_display_currency";
|
|
@@ -1063,7 +1151,7 @@ var DEFAULT_COUNTRY = "US";
|
|
|
1063
1151
|
function createDefaultClient() {
|
|
1064
1152
|
const processRef = globalThis.process;
|
|
1065
1153
|
const envPublicKey = processRef?.env?.NEXT_PUBLIC_CIMPLIFY_PUBLIC_KEY || "";
|
|
1066
|
-
return
|
|
1154
|
+
return chunkZYACIPKO_js.createCimplifyClient({ publicKey: envPublicKey });
|
|
1067
1155
|
}
|
|
1068
1156
|
function getStoredLocationId() {
|
|
1069
1157
|
if (typeof window === "undefined" || !window.localStorage) {
|
|
@@ -1125,7 +1213,8 @@ var CimplifyStateContext = React10.createContext(null);
|
|
|
1125
1213
|
function CimplifyProvider({
|
|
1126
1214
|
client,
|
|
1127
1215
|
children,
|
|
1128
|
-
onLocationChange
|
|
1216
|
+
onLocationChange,
|
|
1217
|
+
optimistic = true
|
|
1129
1218
|
}) {
|
|
1130
1219
|
const resolvedClient = React10.useMemo(() => client ?? createDefaultClient(), [client]);
|
|
1131
1220
|
const onLocationChangeRef = React10.useRef(onLocationChange);
|
|
@@ -1146,7 +1235,7 @@ function CimplifyProvider({
|
|
|
1146
1235
|
const setDisplayCurrency = React10.useCallback(
|
|
1147
1236
|
(currency) => {
|
|
1148
1237
|
const normalized = currency?.trim().toUpperCase() || null;
|
|
1149
|
-
if (normalized && !
|
|
1238
|
+
if (normalized && !chunkV2O5AO7I_js.isSupportedCurrency(normalized)) {
|
|
1150
1239
|
return;
|
|
1151
1240
|
}
|
|
1152
1241
|
setDisplayCurrencyOverride(normalized);
|
|
@@ -1269,7 +1358,8 @@ function CimplifyProvider({
|
|
|
1269
1358
|
locations,
|
|
1270
1359
|
isReady,
|
|
1271
1360
|
isDemoMode,
|
|
1272
|
-
baseCurrency
|
|
1361
|
+
baseCurrency,
|
|
1362
|
+
optimistic
|
|
1273
1363
|
}),
|
|
1274
1364
|
[
|
|
1275
1365
|
resolvedClient,
|
|
@@ -1277,7 +1367,8 @@ function CimplifyProvider({
|
|
|
1277
1367
|
baseCurrency,
|
|
1278
1368
|
locations,
|
|
1279
1369
|
isReady,
|
|
1280
|
-
isDemoMode
|
|
1370
|
+
isDemoMode,
|
|
1371
|
+
optimistic
|
|
1281
1372
|
]
|
|
1282
1373
|
);
|
|
1283
1374
|
const stateContextValue = React10.useMemo(
|
|
@@ -1806,7 +1897,7 @@ function Price({ amount, currency, className, prefix }) {
|
|
|
1806
1897
|
const resolvedAmount = typeof convertedAmount === "string" ? parseFloat(convertedAmount) || 0 : convertedAmount;
|
|
1807
1898
|
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className, children: [
|
|
1808
1899
|
prefix,
|
|
1809
|
-
|
|
1900
|
+
chunkV2O5AO7I_js.formatPrice(resolvedAmount, resolvedCurrency)
|
|
1810
1901
|
] });
|
|
1811
1902
|
}
|
|
1812
1903
|
function createCachedQuery(config) {
|
|
@@ -2813,16 +2904,16 @@ function useProductPrice(input) {
|
|
|
2813
2904
|
if (bundleTotalPrice != null) {
|
|
2814
2905
|
unitPrice = bundleTotalPrice;
|
|
2815
2906
|
} else if (compositePrice) {
|
|
2816
|
-
unitPrice =
|
|
2907
|
+
unitPrice = chunkV2O5AO7I_js.parsePrice(compositePrice.final_price);
|
|
2817
2908
|
} else {
|
|
2818
|
-
unitPrice =
|
|
2909
|
+
unitPrice = chunkV2O5AO7I_js.parsePrice(product.default_price);
|
|
2819
2910
|
if (variant?.price_adjustment) {
|
|
2820
|
-
unitPrice +=
|
|
2911
|
+
unitPrice += chunkV2O5AO7I_js.parsePrice(variant.price_adjustment);
|
|
2821
2912
|
}
|
|
2822
2913
|
if (addOnOptions) {
|
|
2823
2914
|
for (const option of addOnOptions) {
|
|
2824
2915
|
if (option.default_price) {
|
|
2825
|
-
unitPrice +=
|
|
2916
|
+
unitPrice += chunkV2O5AO7I_js.parsePrice(option.default_price);
|
|
2826
2917
|
}
|
|
2827
2918
|
}
|
|
2828
2919
|
}
|
|
@@ -3318,6 +3409,8 @@ function useBootstrap(options = {}) {
|
|
|
3318
3409
|
var POLL_INTERVAL_MS = 3e3;
|
|
3319
3410
|
var POLL_IDLE_INTERVAL_MS = 15e3;
|
|
3320
3411
|
var IDLE_TIMEOUT_MS = 6e4;
|
|
3412
|
+
var WS_MAX_RECONNECT_ATTEMPTS = 10;
|
|
3413
|
+
var WS_PATH = "/api/v1/support/conversation/ws";
|
|
3321
3414
|
function useChat(options = {}) {
|
|
3322
3415
|
const context = useOptionalCimplifyClient();
|
|
3323
3416
|
const client = options.client ?? context?.client;
|
|
@@ -3330,26 +3423,34 @@ function useChat(options = {}) {
|
|
|
3330
3423
|
const lastActivityRef = React10.useRef(Date.now());
|
|
3331
3424
|
const openedRef = React10.useRef(false);
|
|
3332
3425
|
const messagesRef = React10.useRef([]);
|
|
3426
|
+
const clientRef = React10.useRef(client);
|
|
3427
|
+
const wsRef = React10.useRef(null);
|
|
3428
|
+
const wsReconnectAttemptRef = React10.useRef(0);
|
|
3429
|
+
const wsReconnectTimerRef = React10.useRef(null);
|
|
3333
3430
|
messagesRef.current = messages;
|
|
3431
|
+
clientRef.current = client;
|
|
3334
3432
|
const pollInterval = options.pollInterval ?? POLL_INTERVAL_MS;
|
|
3335
3433
|
const pollIdleInterval = options.pollIdleInterval ?? POLL_IDLE_INTERVAL_MS;
|
|
3434
|
+
const appendMessages = React10.useCallback((incoming) => {
|
|
3435
|
+
setMessages((prev) => {
|
|
3436
|
+
const ids = new Set(prev.map((m) => m.id));
|
|
3437
|
+
const fresh = incoming.filter((m) => !ids.has(m.id));
|
|
3438
|
+
return fresh.length > 0 ? [...prev, ...fresh] : prev;
|
|
3439
|
+
});
|
|
3440
|
+
}, []);
|
|
3336
3441
|
const pollMessages = React10.useCallback(async () => {
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
if (
|
|
3442
|
+
const c = clientRef.current;
|
|
3443
|
+
if (!c) return;
|
|
3444
|
+
if (Date.now() - lastActivityRef.current > IDLE_TIMEOUT_MS) return;
|
|
3340
3445
|
const last = messagesRef.current[messagesRef.current.length - 1];
|
|
3341
|
-
const result = await
|
|
3446
|
+
const result = await c.support.getMessages({
|
|
3342
3447
|
after: last?.created_at,
|
|
3343
3448
|
limit: 50
|
|
3344
3449
|
});
|
|
3345
3450
|
if (result.ok && result.value.length > 0) {
|
|
3346
|
-
|
|
3347
|
-
const ids = new Set(prev.map((m) => m.id));
|
|
3348
|
-
const fresh = result.value.filter((m) => !ids.has(m.id));
|
|
3349
|
-
return fresh.length > 0 ? [...prev, ...fresh] : prev;
|
|
3350
|
-
});
|
|
3451
|
+
appendMessages(result.value);
|
|
3351
3452
|
}
|
|
3352
|
-
}, [
|
|
3453
|
+
}, [appendMessages]);
|
|
3353
3454
|
const startPolling = React10.useCallback(() => {
|
|
3354
3455
|
if (pollRef.current) clearInterval(pollRef.current);
|
|
3355
3456
|
const interval = Date.now() - lastActivityRef.current > IDLE_TIMEOUT_MS ? pollIdleInterval : pollInterval;
|
|
@@ -3361,7 +3462,57 @@ function useChat(options = {}) {
|
|
|
3361
3462
|
pollRef.current = null;
|
|
3362
3463
|
}
|
|
3363
3464
|
}, []);
|
|
3364
|
-
React10.
|
|
3465
|
+
const connectWebSocket = React10.useCallback(() => {
|
|
3466
|
+
const c = clientRef.current;
|
|
3467
|
+
if (!c || typeof WebSocket === "undefined") {
|
|
3468
|
+
startPolling();
|
|
3469
|
+
return;
|
|
3470
|
+
}
|
|
3471
|
+
if (wsRef.current) {
|
|
3472
|
+
wsRef.current.close();
|
|
3473
|
+
wsRef.current = null;
|
|
3474
|
+
}
|
|
3475
|
+
const url = c.buildWsUrl(WS_PATH);
|
|
3476
|
+
const ws = new WebSocket(url);
|
|
3477
|
+
ws.onopen = () => {
|
|
3478
|
+
wsReconnectAttemptRef.current = 0;
|
|
3479
|
+
stopPolling();
|
|
3480
|
+
};
|
|
3481
|
+
ws.onmessage = (event) => {
|
|
3482
|
+
try {
|
|
3483
|
+
const envelope = JSON.parse(event.data);
|
|
3484
|
+
if (envelope.type === "message.created" && envelope.data) {
|
|
3485
|
+
appendMessages([envelope.data]);
|
|
3486
|
+
}
|
|
3487
|
+
} catch {
|
|
3488
|
+
}
|
|
3489
|
+
};
|
|
3490
|
+
ws.onclose = () => {
|
|
3491
|
+
wsRef.current = null;
|
|
3492
|
+
if (!openedRef.current) return;
|
|
3493
|
+
pollMessages();
|
|
3494
|
+
if (wsReconnectAttemptRef.current < WS_MAX_RECONNECT_ATTEMPTS) {
|
|
3495
|
+
const attempt = wsReconnectAttemptRef.current++;
|
|
3496
|
+
const delay = Math.min(1e3 * Math.pow(2, attempt) + Math.random() * 500, 3e4);
|
|
3497
|
+
wsReconnectTimerRef.current = setTimeout(connectWebSocket, delay);
|
|
3498
|
+
} else {
|
|
3499
|
+
startPolling();
|
|
3500
|
+
}
|
|
3501
|
+
};
|
|
3502
|
+
ws.onerror = () => {
|
|
3503
|
+
};
|
|
3504
|
+
wsRef.current = ws;
|
|
3505
|
+
}, [appendMessages, startPolling, stopPolling, pollMessages]);
|
|
3506
|
+
React10.useEffect(() => {
|
|
3507
|
+
return () => {
|
|
3508
|
+
if (pollRef.current) clearInterval(pollRef.current);
|
|
3509
|
+
if (wsReconnectTimerRef.current) clearTimeout(wsReconnectTimerRef.current);
|
|
3510
|
+
if (wsRef.current) {
|
|
3511
|
+
wsRef.current.onclose = null;
|
|
3512
|
+
wsRef.current.close();
|
|
3513
|
+
}
|
|
3514
|
+
};
|
|
3515
|
+
}, []);
|
|
3365
3516
|
const openConversation = React10.useCallback(async () => {
|
|
3366
3517
|
if (openedRef.current || !client) return;
|
|
3367
3518
|
openedRef.current = true;
|
|
@@ -3371,13 +3522,13 @@ function useChat(options = {}) {
|
|
|
3371
3522
|
if (result.ok) {
|
|
3372
3523
|
setMessages(result.value.messages);
|
|
3373
3524
|
setConversationOpened(true);
|
|
3374
|
-
|
|
3525
|
+
connectWebSocket();
|
|
3375
3526
|
} else {
|
|
3376
3527
|
openedRef.current = false;
|
|
3377
3528
|
setError(result.error);
|
|
3378
3529
|
}
|
|
3379
3530
|
setIsLoading(false);
|
|
3380
|
-
}, [client,
|
|
3531
|
+
}, [client, connectWebSocket]);
|
|
3381
3532
|
const send = React10.useCallback(
|
|
3382
3533
|
async (content) => {
|
|
3383
3534
|
if (!client || !content.trim()) return;
|
|
@@ -3506,19 +3657,19 @@ function AuthElement({
|
|
|
3506
3657
|
}, [onReady, onAuthenticated, onRequiresOtp, onError]);
|
|
3507
3658
|
React10.useEffect(() => {
|
|
3508
3659
|
if (!elements || !containerRef.current) return;
|
|
3509
|
-
const element = elements.create(
|
|
3660
|
+
const element = elements.create(chunkHKVRUGM6_js.ELEMENT_TYPES.AUTH, { prefillEmail });
|
|
3510
3661
|
elementRef.current = element;
|
|
3511
|
-
element.on(
|
|
3662
|
+
element.on(chunkHKVRUGM6_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
|
|
3512
3663
|
element.on(
|
|
3513
|
-
|
|
3664
|
+
chunkHKVRUGM6_js.EVENT_TYPES.AUTHENTICATED,
|
|
3514
3665
|
(data) => onAuthenticatedRef.current?.(data)
|
|
3515
3666
|
);
|
|
3516
3667
|
element.on(
|
|
3517
|
-
|
|
3668
|
+
chunkHKVRUGM6_js.EVENT_TYPES.REQUIRES_OTP,
|
|
3518
3669
|
(data) => onRequiresOtpRef.current?.(data)
|
|
3519
3670
|
);
|
|
3520
3671
|
element.on(
|
|
3521
|
-
|
|
3672
|
+
chunkHKVRUGM6_js.EVENT_TYPES.ERROR,
|
|
3522
3673
|
(data) => onErrorRef.current?.(data)
|
|
3523
3674
|
);
|
|
3524
3675
|
element.mount(containerRef.current);
|
|
@@ -3547,15 +3698,15 @@ function AddressElement({
|
|
|
3547
3698
|
}, [onReady, onChange, onError]);
|
|
3548
3699
|
React10.useEffect(() => {
|
|
3549
3700
|
if (!elements || !containerRef.current) return;
|
|
3550
|
-
const element = elements.create(
|
|
3701
|
+
const element = elements.create(chunkHKVRUGM6_js.ELEMENT_TYPES.ADDRESS, { mode });
|
|
3551
3702
|
elementRef.current = element;
|
|
3552
|
-
element.on(
|
|
3703
|
+
element.on(chunkHKVRUGM6_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
|
|
3553
3704
|
element.on(
|
|
3554
|
-
|
|
3705
|
+
chunkHKVRUGM6_js.EVENT_TYPES.CHANGE,
|
|
3555
3706
|
(data) => onChangeRef.current?.(data)
|
|
3556
3707
|
);
|
|
3557
3708
|
element.on(
|
|
3558
|
-
|
|
3709
|
+
chunkHKVRUGM6_js.EVENT_TYPES.ERROR,
|
|
3559
3710
|
(data) => onErrorRef.current?.(data)
|
|
3560
3711
|
);
|
|
3561
3712
|
element.mount(containerRef.current);
|
|
@@ -3585,15 +3736,15 @@ function PaymentElement({
|
|
|
3585
3736
|
}, [onReady, onChange, onError]);
|
|
3586
3737
|
React10.useEffect(() => {
|
|
3587
3738
|
if (!elements || !containerRef.current) return;
|
|
3588
|
-
const element = elements.create(
|
|
3739
|
+
const element = elements.create(chunkHKVRUGM6_js.ELEMENT_TYPES.PAYMENT, { amount, currency });
|
|
3589
3740
|
elementRef.current = element;
|
|
3590
|
-
element.on(
|
|
3741
|
+
element.on(chunkHKVRUGM6_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
|
|
3591
3742
|
element.on(
|
|
3592
|
-
|
|
3743
|
+
chunkHKVRUGM6_js.EVENT_TYPES.CHANGE,
|
|
3593
3744
|
(data) => onChangeRef.current?.(data)
|
|
3594
3745
|
);
|
|
3595
3746
|
element.on(
|
|
3596
|
-
|
|
3747
|
+
chunkHKVRUGM6_js.EVENT_TYPES.ERROR,
|
|
3597
3748
|
(data) => onErrorRef.current?.(data)
|
|
3598
3749
|
);
|
|
3599
3750
|
element.mount(containerRef.current);
|
|
@@ -3749,7 +3900,7 @@ function VariantSelector({
|
|
|
3749
3900
|
if (!variants || variants.length <= 1) {
|
|
3750
3901
|
return null;
|
|
3751
3902
|
}
|
|
3752
|
-
basePrice != null ?
|
|
3903
|
+
basePrice != null ? chunkV2O5AO7I_js.parsePrice(basePrice) : 0;
|
|
3753
3904
|
if (variantAxes && variantAxes.length > 0) {
|
|
3754
3905
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-variant-selector": true, className: cn("space-y-5", className, classNames?.root), children: variantAxes.map((axis) => {
|
|
3755
3906
|
const labelId = `${idPrefix}-axis-${axis.id}`;
|
|
@@ -3825,7 +3976,7 @@ function VariantSelector({
|
|
|
3825
3976
|
className: cn("divide-y divide-border", classNames?.list),
|
|
3826
3977
|
children: variants.map((variant) => {
|
|
3827
3978
|
const isSelected = selectedVariantId === variant.id;
|
|
3828
|
-
const adjustment =
|
|
3979
|
+
const adjustment = chunkV2O5AO7I_js.parsePrice(variant.price_adjustment);
|
|
3829
3980
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3830
3981
|
radio.Radio.Root,
|
|
3831
3982
|
{
|
|
@@ -3853,7 +4004,7 @@ function VariantSelector({
|
|
|
3853
4004
|
{
|
|
3854
4005
|
"data-cimplify-variant-name": true,
|
|
3855
4006
|
className: cn("flex-1 min-w-0 text-sm", classNames?.name),
|
|
3856
|
-
children:
|
|
4007
|
+
children: chunkZYACIPKO_js.getVariantDisplayName(variant, productName)
|
|
3857
4008
|
}
|
|
3858
4009
|
),
|
|
3859
4010
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-variant-pricing": true, className: cn("text-sm text-muted-foreground", classNames?.pricing), children: [
|
|
@@ -4091,16 +4242,16 @@ function BundleSelector({
|
|
|
4091
4242
|
}, [components, selections, onReady]);
|
|
4092
4243
|
const totalPrice = React10.useMemo(() => {
|
|
4093
4244
|
if (pricingType === "fixed" && bundlePrice) {
|
|
4094
|
-
return
|
|
4245
|
+
return chunkV2O5AO7I_js.parsePrice(bundlePrice);
|
|
4095
4246
|
}
|
|
4096
4247
|
const componentsTotal = components.reduce((sum, comp) => {
|
|
4097
4248
|
return sum + getComponentPrice(comp, variantChoices[comp.id]) * comp.quantity;
|
|
4098
4249
|
}, 0);
|
|
4099
4250
|
if (pricingType === "percentage_discount" && discountValue) {
|
|
4100
|
-
return componentsTotal * (1 -
|
|
4251
|
+
return componentsTotal * (1 - chunkV2O5AO7I_js.parsePrice(discountValue) / 100);
|
|
4101
4252
|
}
|
|
4102
4253
|
if (pricingType === "fixed_discount" && discountValue) {
|
|
4103
|
-
return componentsTotal -
|
|
4254
|
+
return componentsTotal - chunkV2O5AO7I_js.parsePrice(discountValue);
|
|
4104
4255
|
}
|
|
4105
4256
|
return componentsTotal;
|
|
4106
4257
|
}, [components, variantChoices, pricingType, bundlePrice, discountValue]);
|
|
@@ -4161,15 +4312,15 @@ function BundleSelector({
|
|
|
4161
4312
|
}
|
|
4162
4313
|
function getComponentPrice(component, selectedVariantId) {
|
|
4163
4314
|
if (!selectedVariantId || component.available_variants.length === 0) {
|
|
4164
|
-
return
|
|
4315
|
+
return chunkV2O5AO7I_js.parsePrice(component.effective_price);
|
|
4165
4316
|
}
|
|
4166
4317
|
if (selectedVariantId === component.variant_id) {
|
|
4167
|
-
return
|
|
4318
|
+
return chunkV2O5AO7I_js.parsePrice(component.effective_price);
|
|
4168
4319
|
}
|
|
4169
4320
|
const bakedAdj = component.variant_id ? component.available_variants.find((v) => v.id === component.variant_id) : void 0;
|
|
4170
4321
|
const selectedAdj = component.available_variants.find((v) => v.id === selectedVariantId);
|
|
4171
|
-
if (!selectedAdj) return
|
|
4172
|
-
return
|
|
4322
|
+
if (!selectedAdj) return chunkV2O5AO7I_js.parsePrice(component.effective_price);
|
|
4323
|
+
return chunkV2O5AO7I_js.parsePrice(component.effective_price) - chunkV2O5AO7I_js.parsePrice(bakedAdj?.price_adjustment ?? "0") + chunkV2O5AO7I_js.parsePrice(selectedAdj.price_adjustment);
|
|
4173
4324
|
}
|
|
4174
4325
|
function formatDuration(minutes, unit) {
|
|
4175
4326
|
if (unit === "hours" || !unit && minutes >= 60 && minutes % 60 === 0) {
|
|
@@ -4282,7 +4433,7 @@ function BundleComponentCard({
|
|
|
4282
4433
|
className: cn("mt-3 divide-y divide-border", classNames?.variantPicker),
|
|
4283
4434
|
children: component.available_variants.map((variant) => {
|
|
4284
4435
|
const isSelected = selectedVariantId === variant.id;
|
|
4285
|
-
const adjustment =
|
|
4436
|
+
const adjustment = chunkV2O5AO7I_js.parsePrice(variant.price_adjustment);
|
|
4286
4437
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4287
4438
|
radio.Radio.Root,
|
|
4288
4439
|
{
|
|
@@ -4728,7 +4879,7 @@ function CompositeSelector({
|
|
|
4728
4879
|
"data-cimplify-composite-summary": true,
|
|
4729
4880
|
className: cn("border-t border-border pt-4 space-y-1 text-sm", classNames?.summary),
|
|
4730
4881
|
children: [
|
|
4731
|
-
|
|
4882
|
+
chunkV2O5AO7I_js.parsePrice(priceResult.base_price) !== 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4732
4883
|
"div",
|
|
4733
4884
|
{
|
|
4734
4885
|
"data-cimplify-composite-summary-line": true,
|
|
@@ -4739,7 +4890,7 @@ function CompositeSelector({
|
|
|
4739
4890
|
]
|
|
4740
4891
|
}
|
|
4741
4892
|
),
|
|
4742
|
-
|
|
4893
|
+
chunkV2O5AO7I_js.parsePrice(priceResult.components_total) !== 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4743
4894
|
"div",
|
|
4744
4895
|
{
|
|
4745
4896
|
"data-cimplify-composite-summary-line": true,
|
|
@@ -5035,7 +5186,7 @@ function InputField({
|
|
|
5035
5186
|
onFileUpload,
|
|
5036
5187
|
classNames
|
|
5037
5188
|
}) {
|
|
5038
|
-
const hasPriceAdjustment = field.price_adjustment != null &&
|
|
5189
|
+
const hasPriceAdjustment = field.price_adjustment != null && chunkV2O5AO7I_js.parsePrice(field.price_adjustment) > 0;
|
|
5039
5190
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-customer-input": true, "data-field-type": field.field_type, className: classNames?.field, children: [
|
|
5040
5191
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-1.5", children: [
|
|
5041
5192
|
/* @__PURE__ */ jsxRuntime.jsx("label", { className: cn("text-sm font-semibold", classNames?.label), children: field.name }),
|
|
@@ -5070,12 +5221,12 @@ function FieldInput({
|
|
|
5070
5221
|
classNames?.input
|
|
5071
5222
|
);
|
|
5072
5223
|
switch (field.field_type) {
|
|
5073
|
-
case
|
|
5074
|
-
case
|
|
5224
|
+
case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Text:
|
|
5225
|
+
case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Url:
|
|
5075
5226
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5076
5227
|
"input",
|
|
5077
5228
|
{
|
|
5078
|
-
type: field.field_type ===
|
|
5229
|
+
type: field.field_type === chunkZYACIPKO_js.INPUT_FIELD_TYPE.Url ? "url" : "text",
|
|
5079
5230
|
value: typeof value === "string" ? value : "",
|
|
5080
5231
|
onChange: (e) => onValueChange(e.target.value),
|
|
5081
5232
|
placeholder: field.placeholder,
|
|
@@ -5084,7 +5235,7 @@ function FieldInput({
|
|
|
5084
5235
|
className: inputClass
|
|
5085
5236
|
}
|
|
5086
5237
|
);
|
|
5087
|
-
case
|
|
5238
|
+
case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Textarea:
|
|
5088
5239
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5089
5240
|
"textarea",
|
|
5090
5241
|
{
|
|
@@ -5097,7 +5248,7 @@ function FieldInput({
|
|
|
5097
5248
|
className: cn(inputClass, "resize-none", classNames?.textarea)
|
|
5098
5249
|
}
|
|
5099
5250
|
);
|
|
5100
|
-
case
|
|
5251
|
+
case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Number:
|
|
5101
5252
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5102
5253
|
"input",
|
|
5103
5254
|
{
|
|
@@ -5111,7 +5262,7 @@ function FieldInput({
|
|
|
5111
5262
|
className: inputClass
|
|
5112
5263
|
}
|
|
5113
5264
|
);
|
|
5114
|
-
case
|
|
5265
|
+
case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Select:
|
|
5115
5266
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5116
5267
|
"select",
|
|
5117
5268
|
{
|
|
@@ -5125,7 +5276,7 @@ function FieldInput({
|
|
|
5125
5276
|
]
|
|
5126
5277
|
}
|
|
5127
5278
|
);
|
|
5128
|
-
case
|
|
5279
|
+
case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Radio:
|
|
5129
5280
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("space-y-2", classNames?.radioGroup), children: (field.options || []).map((opt) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5130
5281
|
"label",
|
|
5131
5282
|
{
|
|
@@ -5150,7 +5301,7 @@ function FieldInput({
|
|
|
5150
5301
|
},
|
|
5151
5302
|
opt
|
|
5152
5303
|
)) });
|
|
5153
|
-
case
|
|
5304
|
+
case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Checkbox:
|
|
5154
5305
|
return /* @__PURE__ */ jsxRuntime.jsxs("label", { className: cn("flex items-center gap-2 text-sm cursor-pointer", classNames?.checkboxLabel), children: [
|
|
5155
5306
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5156
5307
|
"input",
|
|
@@ -5163,7 +5314,7 @@ function FieldInput({
|
|
|
5163
5314
|
),
|
|
5164
5315
|
field.placeholder || field.name
|
|
5165
5316
|
] });
|
|
5166
|
-
case
|
|
5317
|
+
case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Color:
|
|
5167
5318
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5168
5319
|
"input",
|
|
5169
5320
|
{
|
|
@@ -5173,7 +5324,7 @@ function FieldInput({
|
|
|
5173
5324
|
className: cn("w-12 h-10 rounded-md border border-input cursor-pointer", classNames?.colorInput)
|
|
5174
5325
|
}
|
|
5175
5326
|
);
|
|
5176
|
-
case
|
|
5327
|
+
case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Date:
|
|
5177
5328
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5178
5329
|
"input",
|
|
5179
5330
|
{
|
|
@@ -5184,8 +5335,8 @@ function FieldInput({
|
|
|
5184
5335
|
className: inputClass
|
|
5185
5336
|
}
|
|
5186
5337
|
);
|
|
5187
|
-
case
|
|
5188
|
-
case
|
|
5338
|
+
case chunkZYACIPKO_js.INPUT_FIELD_TYPE.File:
|
|
5339
|
+
case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Image:
|
|
5189
5340
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5190
5341
|
FileUploadInput,
|
|
5191
5342
|
{
|
|
@@ -5196,7 +5347,7 @@ function FieldInput({
|
|
|
5196
5347
|
classNames
|
|
5197
5348
|
}
|
|
5198
5349
|
);
|
|
5199
|
-
case
|
|
5350
|
+
case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Email:
|
|
5200
5351
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5201
5352
|
"input",
|
|
5202
5353
|
{
|
|
@@ -5208,7 +5359,7 @@ function FieldInput({
|
|
|
5208
5359
|
className: inputClass
|
|
5209
5360
|
}
|
|
5210
5361
|
);
|
|
5211
|
-
case
|
|
5362
|
+
case chunkZYACIPKO_js.INPUT_FIELD_TYPE.DateTime: {
|
|
5212
5363
|
const dtLocalValue = typeof value === "string" && value.includes("T") ? value.slice(0, 16) : typeof value === "string" ? value : "";
|
|
5213
5364
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5214
5365
|
"input",
|
|
@@ -5228,7 +5379,7 @@ function FieldInput({
|
|
|
5228
5379
|
}
|
|
5229
5380
|
);
|
|
5230
5381
|
}
|
|
5231
|
-
case
|
|
5382
|
+
case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Time:
|
|
5232
5383
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5233
5384
|
"input",
|
|
5234
5385
|
{
|
|
@@ -5239,7 +5390,7 @@ function FieldInput({
|
|
|
5239
5390
|
className: inputClass
|
|
5240
5391
|
}
|
|
5241
5392
|
);
|
|
5242
|
-
case
|
|
5393
|
+
case chunkZYACIPKO_js.INPUT_FIELD_TYPE.MultiSelect:
|
|
5243
5394
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5244
5395
|
MultiSelectInput,
|
|
5245
5396
|
{
|
|
@@ -5249,7 +5400,7 @@ function FieldInput({
|
|
|
5249
5400
|
classNames
|
|
5250
5401
|
}
|
|
5251
5402
|
);
|
|
5252
|
-
case
|
|
5403
|
+
case chunkZYACIPKO_js.INPUT_FIELD_TYPE.DateRange:
|
|
5253
5404
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5254
5405
|
DateRangeInput,
|
|
5255
5406
|
{
|
|
@@ -5260,7 +5411,7 @@ function FieldInput({
|
|
|
5260
5411
|
inputClass
|
|
5261
5412
|
}
|
|
5262
5413
|
);
|
|
5263
|
-
case
|
|
5414
|
+
case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Address:
|
|
5264
5415
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5265
5416
|
AddressInput,
|
|
5266
5417
|
{
|
|
@@ -5271,7 +5422,7 @@ function FieldInput({
|
|
|
5271
5422
|
inputClass
|
|
5272
5423
|
}
|
|
5273
5424
|
);
|
|
5274
|
-
case
|
|
5425
|
+
case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Location:
|
|
5275
5426
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5276
5427
|
LocationInput,
|
|
5277
5428
|
{
|
|
@@ -5282,7 +5433,7 @@ function FieldInput({
|
|
|
5282
5433
|
inputClass
|
|
5283
5434
|
}
|
|
5284
5435
|
);
|
|
5285
|
-
case
|
|
5436
|
+
case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Phone:
|
|
5286
5437
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5287
5438
|
PhoneInput,
|
|
5288
5439
|
{
|
|
@@ -5293,7 +5444,7 @@ function FieldInput({
|
|
|
5293
5444
|
inputClass
|
|
5294
5445
|
}
|
|
5295
5446
|
);
|
|
5296
|
-
case
|
|
5447
|
+
case chunkZYACIPKO_js.INPUT_FIELD_TYPE.Signature:
|
|
5297
5448
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5298
5449
|
SignatureInput,
|
|
5299
5450
|
{
|
|
@@ -5326,7 +5477,7 @@ function FileUploadInput({
|
|
|
5326
5477
|
const [isUploading, setIsUploading] = React10__default.default.useState(false);
|
|
5327
5478
|
const fileUrl = typeof value === "string" ? value : void 0;
|
|
5328
5479
|
const acceptedFormats = field.validation?.accepted_formats;
|
|
5329
|
-
const accept = acceptedFormats ? acceptedFormats.map((f) => `.${f}`).join(",") : field.field_type ===
|
|
5480
|
+
const accept = acceptedFormats ? acceptedFormats.map((f) => `.${f}`).join(",") : field.field_type === chunkZYACIPKO_js.INPUT_FIELD_TYPE.Image ? "image/*" : void 0;
|
|
5330
5481
|
const handleFile = async (file) => {
|
|
5331
5482
|
if (!onFileUpload) return;
|
|
5332
5483
|
if (field.validation?.max_size_mb) {
|
|
@@ -5344,7 +5495,7 @@ function FileUploadInput({
|
|
|
5344
5495
|
}
|
|
5345
5496
|
};
|
|
5346
5497
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("space-y-2", classNames?.fileInput), children: fileUrl ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
5347
|
-
field.field_type ===
|
|
5498
|
+
field.field_type === chunkZYACIPKO_js.INPUT_FIELD_TYPE.Image && /* @__PURE__ */ jsxRuntime.jsx("img", { src: fileUrl, alt: "Uploaded", className: "w-16 h-16 object-cover rounded-md border border-border" }),
|
|
5348
5499
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-foreground truncate", children: fileUrl.split("/").pop() }) }),
|
|
5349
5500
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5350
5501
|
"button",
|
|
@@ -5370,7 +5521,7 @@ function FileUploadInput({
|
|
|
5370
5521
|
}
|
|
5371
5522
|
),
|
|
5372
5523
|
isUploading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Uploading..." }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5373
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: field.placeholder || `Upload ${field.field_type ===
|
|
5524
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: field.placeholder || `Upload ${field.field_type === chunkZYACIPKO_js.INPUT_FIELD_TYPE.Image ? "image" : "file"}` }),
|
|
5374
5525
|
acceptedFormats && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground/60 mt-1", children: [
|
|
5375
5526
|
acceptedFormats.map((f) => f.toUpperCase()).join(", "),
|
|
5376
5527
|
field.validation?.max_size_mb && ` \xB7 Max ${field.validation.max_size_mb}MB`
|
|
@@ -5929,18 +6080,18 @@ function ProductCustomizer({
|
|
|
5929
6080
|
}, [selectedAddOnOptionIds]);
|
|
5930
6081
|
const localTotalPrice = React10.useMemo(() => {
|
|
5931
6082
|
if (isComposite && compositePrice) {
|
|
5932
|
-
return
|
|
6083
|
+
return chunkV2O5AO7I_js.parsePrice(compositePrice.final_price) * quantity;
|
|
5933
6084
|
}
|
|
5934
6085
|
if (isBundle && bundleTotalPrice != null) {
|
|
5935
6086
|
return bundleTotalPrice * quantity;
|
|
5936
6087
|
}
|
|
5937
|
-
let price =
|
|
6088
|
+
let price = chunkV2O5AO7I_js.parsePrice(product.default_price);
|
|
5938
6089
|
if (selectedVariant?.price_adjustment) {
|
|
5939
|
-
price +=
|
|
6090
|
+
price += chunkV2O5AO7I_js.parsePrice(selectedVariant.price_adjustment);
|
|
5940
6091
|
}
|
|
5941
6092
|
for (const option of selectedAddOnOptions) {
|
|
5942
6093
|
if (option.default_price) {
|
|
5943
|
-
price +=
|
|
6094
|
+
price += chunkV2O5AO7I_js.parsePrice(option.default_price);
|
|
5944
6095
|
}
|
|
5945
6096
|
}
|
|
5946
6097
|
return price * quantity;
|
|
@@ -5989,7 +6140,7 @@ function ProductCustomizer({
|
|
|
5989
6140
|
const priceInfo = quote.quoted_total_price_info ?? quote.final_price_info;
|
|
5990
6141
|
const perUnit = priceInfo.pre_tax_price;
|
|
5991
6142
|
if (perUnit === void 0 || perUnit === null) return void 0;
|
|
5992
|
-
return
|
|
6143
|
+
return chunkV2O5AO7I_js.parsePrice(perUnit) * quantity;
|
|
5993
6144
|
}, [quote, quantity]);
|
|
5994
6145
|
const displayTotalPrice = quotedTotalPrice ?? localTotalPrice;
|
|
5995
6146
|
const handleVariantChange = React10.useCallback(
|
|
@@ -6111,7 +6262,7 @@ function ProductCustomizer({
|
|
|
6111
6262
|
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.deposit_amount })
|
|
6112
6263
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
6113
6264
|
"Deposit required: ",
|
|
6114
|
-
|
|
6265
|
+
chunkV2O5AO7I_js.parsePrice(product.deposit_amount),
|
|
6115
6266
|
"%"
|
|
6116
6267
|
] }) }),
|
|
6117
6268
|
product.allergies && product.allergies.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-customizer-allergens": true, className: cn("flex flex-wrap gap-1.5", classNames?.allergens), children: product.allergies.map((allergen) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -6172,7 +6323,7 @@ function ProductCustomizer({
|
|
|
6172
6323
|
] })
|
|
6173
6324
|
] }),
|
|
6174
6325
|
product.quantity_pricing && product.quantity_pricing.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-customizer-unit-price": true, className: "text-sm text-muted-foreground text-right shrink-0", children: [
|
|
6175
|
-
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount:
|
|
6326
|
+
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: chunkV2O5AO7I_js.getUnitPriceAtQuantity(product.quantity_pricing, quantity, chunkV2O5AO7I_js.parsePrice(product.default_price)), className: "font-medium text-foreground" }),
|
|
6176
6327
|
" ea."
|
|
6177
6328
|
] }),
|
|
6178
6329
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -6295,85 +6446,94 @@ function CartLineItemRow({
|
|
|
6295
6446
|
});
|
|
6296
6447
|
const hasComposite = item.compositeSelections && item.compositeSelections.length > 0;
|
|
6297
6448
|
const hasBundle = item.bundleSelections && item.bundleSelections.length > 0;
|
|
6298
|
-
|
|
6299
|
-
|
|
6300
|
-
|
|
6301
|
-
|
|
6302
|
-
|
|
6303
|
-
|
|
6304
|
-
|
|
6305
|
-
|
|
6306
|
-
|
|
6307
|
-
|
|
6308
|
-
|
|
6309
|
-
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
"
|
|
6315
|
-
" ",
|
|
6316
|
-
|
|
6317
|
-
|
|
6318
|
-
|
|
6319
|
-
|
|
6320
|
-
|
|
6321
|
-
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
|
|
6327
|
-
|
|
6328
|
-
|
|
6329
|
-
|
|
6330
|
-
|
|
6331
|
-
|
|
6332
|
-
|
|
6333
|
-
"
|
|
6334
|
-
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
"
|
|
6338
|
-
|
|
6339
|
-
|
|
6340
|
-
|
|
6341
|
-
|
|
6342
|
-
|
|
6343
|
-
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
|
|
6449
|
+
const isOptimistic = item.isOptimistic === true;
|
|
6450
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6451
|
+
"div",
|
|
6452
|
+
{
|
|
6453
|
+
"data-cimplify-cart-item": true,
|
|
6454
|
+
"data-optimistic": isOptimistic ? "true" : void 0,
|
|
6455
|
+
className: classNames?.item,
|
|
6456
|
+
children: [
|
|
6457
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-item-info": true, children: [
|
|
6458
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-name": true, className: classNames?.itemName, children: item.product.name }),
|
|
6459
|
+
item.variant && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-variant": true, children: chunkZYACIPKO_js.getVariantDisplayName(item.variant, item.product.name) }),
|
|
6460
|
+
item.addOnOptions && item.addOnOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-cart-item-addons": true, children: [
|
|
6461
|
+
"+ ",
|
|
6462
|
+
item.addOnOptions.map((opt) => opt.name).join(", ")
|
|
6463
|
+
] }),
|
|
6464
|
+
(hasComposite || hasBundle) && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-badge": true, children: hasComposite ? "Custom" : "Bundle" }),
|
|
6465
|
+
item.specialInstructions && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-instructions": true, className: "text-xs text-muted-foreground", children: item.specialInstructions }),
|
|
6466
|
+
item.customerInputs && item.customerInputs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-cart-customer-inputs": true, className: classNames?.customerInputs, children: item.customerInputs.map((input) => /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-input": true, children: [
|
|
6467
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-input-label": true, children: input.field_name }),
|
|
6468
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-input-value": true, children: input.field_type === chunkZYACIPKO_js.INPUT_FIELD_TYPE.File || input.field_type === chunkZYACIPKO_js.INPUT_FIELD_TYPE.Image ? String(input.value).split("/").pop() || "Uploaded file" : String(input.value) })
|
|
6469
|
+
] }, input.field_id)) }),
|
|
6470
|
+
(item.lineType === "service" || item.product.type === "service") && item.scheduledStart && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-service-info": true, className: classNames?.serviceInfo, children: [
|
|
6471
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
6472
|
+
"\u{1F4C5}",
|
|
6473
|
+
" ",
|
|
6474
|
+
new Date(item.scheduledStart).toLocaleDateString(),
|
|
6475
|
+
" at ",
|
|
6476
|
+
new Date(item.scheduledStart).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })
|
|
6477
|
+
] }),
|
|
6478
|
+
item.confirmationCode && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
6479
|
+
"Confirmation: ",
|
|
6480
|
+
item.confirmationCode
|
|
6481
|
+
] }),
|
|
6482
|
+
item.serviceStatus && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-status": item.serviceStatus, children: item.serviceStatus })
|
|
6483
|
+
] }),
|
|
6484
|
+
(item.lineType === "digital" || item.product.type === "digital") && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-cart-digital-info": true, className: classNames?.digitalInfo, children: /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
6485
|
+
"\u26A1",
|
|
6486
|
+
" Instant digital delivery"
|
|
6487
|
+
] }) }),
|
|
6488
|
+
item.bundleResolved && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-cart-bundle-breakdown": true, className: classNames?.bundleBreakdown, children: item.bundleResolved.selections.map((sel) => /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-product-type": sel.product_type, children: [
|
|
6489
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
6490
|
+
sel.quantity,
|
|
6491
|
+
"\xD7 ",
|
|
6492
|
+
sel.product_name
|
|
6493
|
+
] }),
|
|
6494
|
+
sel.product_type === "service" && sel.scheduling?.scheduled_start && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
6495
|
+
" \u2014 ",
|
|
6496
|
+
new Date(sel.scheduling.scheduled_start).toLocaleDateString()
|
|
6497
|
+
] }),
|
|
6498
|
+
sel.product_type === "digital" && /* @__PURE__ */ jsxRuntime.jsx("span", { children: " \u2014 Digital" })
|
|
6499
|
+
] }, sel.component_id)) }),
|
|
6500
|
+
item.compositeResolved && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-cart-composite-breakdown": true, className: classNames?.compositeBreakdown, children: item.compositeResolved.selections.map((sel) => /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-product-type": sel.product_type, children: [
|
|
6501
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
6502
|
+
sel.quantity,
|
|
6503
|
+
"\xD7 ",
|
|
6504
|
+
sel.component_name
|
|
6505
|
+
] }),
|
|
6506
|
+
sel.product_type === "service" && sel.scheduling?.scheduled_start && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
6507
|
+
" \u2014 ",
|
|
6508
|
+
new Date(sel.scheduling.scheduled_start).toLocaleDateString()
|
|
6509
|
+
] })
|
|
6510
|
+
] }, sel.component_id)) }),
|
|
6511
|
+
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: unitPrice, className: classNames?.itemPrice })
|
|
6347
6512
|
] }),
|
|
6348
|
-
|
|
6349
|
-
|
|
6350
|
-
|
|
6513
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-item-controls": true, className: classNames?.quantity, children: [
|
|
6514
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6515
|
+
QuantitySelector,
|
|
6516
|
+
{
|
|
6517
|
+
value: item.quantity,
|
|
6518
|
+
onChange: (qty) => onQuantityChange(item.id, qty),
|
|
6519
|
+
min: 0
|
|
6520
|
+
}
|
|
6521
|
+
),
|
|
6522
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6523
|
+
"button",
|
|
6524
|
+
{
|
|
6525
|
+
type: "button",
|
|
6526
|
+
onClick: () => onRemove(item.id),
|
|
6527
|
+
"data-cimplify-cart-item-remove": true,
|
|
6528
|
+
className: classNames?.removeButton,
|
|
6529
|
+
"aria-label": `Remove ${item.product.name}`,
|
|
6530
|
+
children: "Remove"
|
|
6531
|
+
}
|
|
6532
|
+
)
|
|
6351
6533
|
] })
|
|
6352
|
-
]
|
|
6353
|
-
|
|
6354
|
-
|
|
6355
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-item-controls": true, className: classNames?.quantity, children: [
|
|
6356
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6357
|
-
QuantitySelector,
|
|
6358
|
-
{
|
|
6359
|
-
value: item.quantity,
|
|
6360
|
-
onChange: (qty) => onQuantityChange(item.id, qty),
|
|
6361
|
-
min: 0
|
|
6362
|
-
}
|
|
6363
|
-
),
|
|
6364
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6365
|
-
"button",
|
|
6366
|
-
{
|
|
6367
|
-
type: "button",
|
|
6368
|
-
onClick: () => onRemove(item.id),
|
|
6369
|
-
"data-cimplify-cart-item-remove": true,
|
|
6370
|
-
className: classNames?.removeButton,
|
|
6371
|
-
"aria-label": `Remove ${item.product.name}`,
|
|
6372
|
-
children: "Remove"
|
|
6373
|
-
}
|
|
6374
|
-
)
|
|
6375
|
-
] })
|
|
6376
|
-
] });
|
|
6534
|
+
]
|
|
6535
|
+
}
|
|
6536
|
+
);
|
|
6377
6537
|
}
|
|
6378
6538
|
function CartSummary({
|
|
6379
6539
|
cart: serverCart,
|
|
@@ -6384,7 +6544,18 @@ function CartSummary({
|
|
|
6384
6544
|
className,
|
|
6385
6545
|
classNames
|
|
6386
6546
|
}) {
|
|
6387
|
-
const {
|
|
6547
|
+
const {
|
|
6548
|
+
items,
|
|
6549
|
+
itemCount,
|
|
6550
|
+
subtotal,
|
|
6551
|
+
tax,
|
|
6552
|
+
total,
|
|
6553
|
+
isEmpty,
|
|
6554
|
+
isOptimistic,
|
|
6555
|
+
pendingOpCount,
|
|
6556
|
+
removeItem,
|
|
6557
|
+
updateQuantity
|
|
6558
|
+
} = useCart();
|
|
6388
6559
|
const deliveryFee = serverCart?.delivery_fee;
|
|
6389
6560
|
const serviceCharge = serverCart?.service_charge;
|
|
6390
6561
|
const totalDiscounts = serverCart?.total_discounts;
|
|
@@ -6402,60 +6573,69 @@ function CartSummary({
|
|
|
6402
6573
|
void updateQuantity(itemId, qty);
|
|
6403
6574
|
}
|
|
6404
6575
|
};
|
|
6405
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6406
|
-
|
|
6407
|
-
|
|
6408
|
-
|
|
6409
|
-
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
|
|
6414
|
-
|
|
6415
|
-
|
|
6416
|
-
|
|
6417
|
-
|
|
6418
|
-
|
|
6419
|
-
|
|
6420
|
-
|
|
6421
|
-
|
|
6422
|
-
|
|
6423
|
-
|
|
6576
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6577
|
+
"div",
|
|
6578
|
+
{
|
|
6579
|
+
"data-cimplify-cart-summary": true,
|
|
6580
|
+
"data-optimistic": isOptimistic ? "true" : void 0,
|
|
6581
|
+
"data-pending-ops": pendingOpCount > 0 ? pendingOpCount : void 0,
|
|
6582
|
+
className: cn(className, classNames?.root),
|
|
6583
|
+
children: isEmpty ? /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-cart-empty": true, className: classNames?.empty, children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: emptyMessage }) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
6584
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-cart-items": true, children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6585
|
+
CartLineItemRow,
|
|
6586
|
+
{
|
|
6587
|
+
item,
|
|
6588
|
+
onRemove: handleRemove,
|
|
6589
|
+
onQuantityChange: handleQuantityChange,
|
|
6590
|
+
classNames
|
|
6591
|
+
},
|
|
6592
|
+
item.id
|
|
6593
|
+
)) }),
|
|
6594
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-totals": true, className: classNames?.totals, children: [
|
|
6595
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-subtotal": true, className: classNames?.subtotal, children: [
|
|
6596
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
6597
|
+
"Subtotal (",
|
|
6598
|
+
itemCount,
|
|
6599
|
+
" ",
|
|
6600
|
+
itemCount === 1 ? "item" : "items",
|
|
6601
|
+
")"
|
|
6602
|
+
] }),
|
|
6603
|
+
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: subtotal })
|
|
6604
|
+
] }),
|
|
6605
|
+
totalDiscounts != null && chunkV2O5AO7I_js.parsePrice(totalDiscounts) > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-discount": true, className: classNames?.discount, children: [
|
|
6606
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Discount" }),
|
|
6607
|
+
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: totalDiscounts, prefix: "-" })
|
|
6608
|
+
] }),
|
|
6609
|
+
deliveryFee != null && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-delivery-fee": true, className: classNames?.deliveryFee, children: [
|
|
6610
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Delivery fee" }),
|
|
6611
|
+
chunkV2O5AO7I_js.parsePrice(deliveryFee) > 0 ? /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: deliveryFee }) : /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Free delivery" })
|
|
6612
|
+
] }),
|
|
6613
|
+
serviceCharge != null && chunkV2O5AO7I_js.parsePrice(serviceCharge) > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-service-charge": true, className: classNames?.serviceCharge, children: [
|
|
6614
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Service charge" }),
|
|
6615
|
+
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: serviceCharge })
|
|
6616
|
+
] }),
|
|
6617
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-tax": true, className: classNames?.tax, children: [
|
|
6618
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Tax" }),
|
|
6619
|
+
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: tax })
|
|
6620
|
+
] }),
|
|
6621
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-total": true, className: classNames?.total, children: [
|
|
6622
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Total" }),
|
|
6623
|
+
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: total })
|
|
6624
|
+
] })
|
|
6424
6625
|
] }),
|
|
6425
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6426
|
-
|
|
6427
|
-
|
|
6428
|
-
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
serviceCharge != null && chunkPEDLCL72_js.parsePrice(serviceCharge) > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-service-charge": true, className: classNames?.serviceCharge, children: [
|
|
6436
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Service charge" }),
|
|
6437
|
-
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: serviceCharge })
|
|
6438
|
-
] }),
|
|
6439
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-tax": true, className: classNames?.tax, children: [
|
|
6440
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Tax" }),
|
|
6441
|
-
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: tax })
|
|
6442
|
-
] }),
|
|
6443
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-total": true, className: classNames?.total, children: [
|
|
6444
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Total" }),
|
|
6445
|
-
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: total })
|
|
6626
|
+
onCheckout && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6627
|
+
"button",
|
|
6628
|
+
{
|
|
6629
|
+
type: "button",
|
|
6630
|
+
onClick: onCheckout,
|
|
6631
|
+
"data-cimplify-cart-checkout": true,
|
|
6632
|
+
className: classNames?.checkout,
|
|
6633
|
+
children: "Proceed to Checkout"
|
|
6634
|
+
}
|
|
6635
|
+
)
|
|
6446
6636
|
] })
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
"button",
|
|
6450
|
-
{
|
|
6451
|
-
type: "button",
|
|
6452
|
-
onClick: onCheckout,
|
|
6453
|
-
"data-cimplify-cart-checkout": true,
|
|
6454
|
-
className: classNames?.checkout,
|
|
6455
|
-
children: "Proceed to Checkout"
|
|
6456
|
-
}
|
|
6457
|
-
)
|
|
6458
|
-
] }) });
|
|
6637
|
+
}
|
|
6638
|
+
);
|
|
6459
6639
|
}
|
|
6460
6640
|
function AvailabilityBadge({
|
|
6461
6641
|
product,
|
|
@@ -6515,16 +6695,16 @@ function SaleBadge({
|
|
|
6515
6695
|
className,
|
|
6516
6696
|
classNames
|
|
6517
6697
|
}) {
|
|
6518
|
-
const onSale =
|
|
6698
|
+
const onSale = chunkV2O5AO7I_js.isOnSale(product);
|
|
6519
6699
|
const hasDeal = dealInfo !== void 0;
|
|
6520
6700
|
if (!hasDeal && !onSale && !label) {
|
|
6521
6701
|
return null;
|
|
6522
6702
|
}
|
|
6523
6703
|
let percentage = null;
|
|
6524
6704
|
if (hasDeal && dealInfo.benefit_type === "percentage") {
|
|
6525
|
-
percentage =
|
|
6705
|
+
percentage = chunkV2O5AO7I_js.parsePrice(dealInfo.value);
|
|
6526
6706
|
} else if (onSale) {
|
|
6527
|
-
percentage =
|
|
6707
|
+
percentage = chunkV2O5AO7I_js.getDiscountPercentage(product);
|
|
6528
6708
|
}
|
|
6529
6709
|
const badgeText = label ?? dealInfo?.label ?? (percentage != null && percentage > 0 ? `${percentage}% off` : null);
|
|
6530
6710
|
if (!badgeText) {
|
|
@@ -6543,7 +6723,7 @@ function SaleBadge({
|
|
|
6543
6723
|
"%"
|
|
6544
6724
|
] }),
|
|
6545
6725
|
/* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-sale-label": true, className: classNames?.label, children: badgeText }),
|
|
6546
|
-
showOriginalPrice && onSale && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-sale-original-price": true, className: classNames?.originalPrice, children: /* @__PURE__ */ jsxRuntime.jsx(Price, { amount:
|
|
6726
|
+
showOriginalPrice && onSale && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-sale-original-price": true, className: classNames?.originalPrice, children: /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: chunkV2O5AO7I_js.getBasePrice(product) }) })
|
|
6547
6727
|
]
|
|
6548
6728
|
}
|
|
6549
6729
|
);
|
|
@@ -6786,8 +6966,8 @@ function SoldOutOverlay() {
|
|
|
6786
6966
|
);
|
|
6787
6967
|
}
|
|
6788
6968
|
function SaleBadge2({ product }) {
|
|
6789
|
-
if (!
|
|
6790
|
-
const pct =
|
|
6969
|
+
if (!chunkV2O5AO7I_js.isOnSale(product)) return null;
|
|
6970
|
+
const pct = chunkV2O5AO7I_js.getDiscountPercentage(product);
|
|
6791
6971
|
if (!pct || pct <= 0) return null;
|
|
6792
6972
|
return /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-card-sale-badge": true, className: "inline-flex items-center text-[11px] font-semibold tracking-wide bg-destructive text-destructive-foreground px-2 py-0.5 rounded-md", children: [
|
|
6793
6973
|
"-",
|
|
@@ -6827,7 +7007,7 @@ function FoodProductCard({
|
|
|
6827
7007
|
const tags = product.tags || [];
|
|
6828
7008
|
const isSignature = product.metadata?.is_signature === true;
|
|
6829
7009
|
const isNew = product.metadata?.is_new === true;
|
|
6830
|
-
const isComposite = product.type ===
|
|
7010
|
+
const isComposite = product.type === chunkZYACIPKO_js.PRODUCT_TYPE.Composite;
|
|
6831
7011
|
return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, className, children: [
|
|
6832
7012
|
/* @__PURE__ */ jsxRuntime.jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "square", renderImage, children: [
|
|
6833
7013
|
isSignature && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute top-3 left-3 inline-flex items-center gap-1 text-[11px] font-semibold tracking-wide bg-amber-50 text-amber-700 border border-amber-200/60 px-2 py-0.5 rounded-md", children: [
|
|
@@ -6880,7 +7060,7 @@ function RetailProductCard({
|
|
|
6880
7060
|
}) {
|
|
6881
7061
|
const image = product.image_url || product.images?.[0] || "";
|
|
6882
7062
|
const outOfStock = product.inventory_status?.in_stock === false;
|
|
6883
|
-
const onSale =
|
|
7063
|
+
const onSale = chunkV2O5AO7I_js.isOnSale(product);
|
|
6884
7064
|
const swatches = getColorSwatches(product);
|
|
6885
7065
|
return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, disabled: outOfStock, className, children: [
|
|
6886
7066
|
outOfStock && /* @__PURE__ */ jsxRuntime.jsx(SoldOutOverlay, {}),
|
|
@@ -6898,7 +7078,7 @@ function RetailProductCard({
|
|
|
6898
7078
|
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[14.5px] font-semibold text-foreground leading-snug tracking-tight mt-1 truncate", children: product.name }),
|
|
6899
7079
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-2", children: [
|
|
6900
7080
|
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price, className: "text-sm font-bold" }),
|
|
6901
|
-
onSale && /* @__PURE__ */ jsxRuntime.jsx(Price, { amount:
|
|
7081
|
+
onSale && /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: chunkV2O5AO7I_js.getBasePrice(product), className: "text-xs text-muted-foreground line-through" })
|
|
6902
7082
|
] }),
|
|
6903
7083
|
swatches.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-1.5 mt-2.5", children: swatches.map((name) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6904
7084
|
"span",
|
|
@@ -6915,9 +7095,9 @@ function RetailProductCard({
|
|
|
6915
7095
|
function PriceRange({ product, currency, className }) {
|
|
6916
7096
|
const context = useOptionalCimplify();
|
|
6917
7097
|
const resolvedCurrency = currency ?? context?.displayCurrency ?? "USD";
|
|
6918
|
-
const range =
|
|
7098
|
+
const range = chunkV2O5AO7I_js.getPriceRange(product);
|
|
6919
7099
|
if (!range) return null;
|
|
6920
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-price-range": true, className, children:
|
|
7100
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-price-range": true, className, children: chunkV2O5AO7I_js.formatPriceRange(range.min, range.max, resolvedCurrency) });
|
|
6921
7101
|
}
|
|
6922
7102
|
function WholesaleProductCard({
|
|
6923
7103
|
product,
|
|
@@ -7006,8 +7186,8 @@ function BundleProductCard({
|
|
|
7006
7186
|
const image = product.image_url || product.images?.[0] || "";
|
|
7007
7187
|
const components = product.components || [];
|
|
7008
7188
|
const componentCount = components.length;
|
|
7009
|
-
const onSale =
|
|
7010
|
-
const discount =
|
|
7189
|
+
const onSale = chunkV2O5AO7I_js.isOnSale(product);
|
|
7190
|
+
const discount = chunkV2O5AO7I_js.getDiscountPercentage(product);
|
|
7011
7191
|
const hasVariantChoice = components.some((c) => c.allow_variant_choice);
|
|
7012
7192
|
return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, className, children: [
|
|
7013
7193
|
/* @__PURE__ */ jsxRuntime.jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "square", renderImage, children: [
|
|
@@ -7034,7 +7214,7 @@ function BundleProductCard({
|
|
|
7034
7214
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-2.5", children: [
|
|
7035
7215
|
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price, className: "text-sm font-bold" }),
|
|
7036
7216
|
onSale && product.bundle_price && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
7037
|
-
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount:
|
|
7217
|
+
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: chunkV2O5AO7I_js.getBasePrice(product), className: "text-xs text-muted-foreground line-through" }),
|
|
7038
7218
|
discount != null && discount > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] font-semibold text-emerald-600", children: [
|
|
7039
7219
|
"Save ",
|
|
7040
7220
|
discount,
|
|
@@ -7580,26 +7760,26 @@ var BUILT_IN_CARDS = {
|
|
|
7580
7760
|
["composite" /* Composite */]: CompositeProductCard,
|
|
7581
7761
|
["subscription" /* Subscription */]: SubscriptionCard
|
|
7582
7762
|
};
|
|
7583
|
-
var RENTAL_UNITS = /* @__PURE__ */ new Set([
|
|
7584
|
-
var LEASE_UNITS = /* @__PURE__ */ new Set([
|
|
7763
|
+
var RENTAL_UNITS = /* @__PURE__ */ new Set([chunkZYACIPKO_js.DURATION_UNIT.Days, chunkZYACIPKO_js.DURATION_UNIT.Hours]);
|
|
7764
|
+
var LEASE_UNITS = /* @__PURE__ */ new Set([chunkZYACIPKO_js.DURATION_UNIT.Weeks, chunkZYACIPKO_js.DURATION_UNIT.Months, chunkZYACIPKO_js.DURATION_UNIT.Years]);
|
|
7585
7765
|
function resolveCardVariant(product) {
|
|
7586
|
-
if (product.type ===
|
|
7766
|
+
if (product.type === chunkZYACIPKO_js.PRODUCT_TYPE.Bundle) {
|
|
7587
7767
|
return "bundle" /* Bundle */;
|
|
7588
7768
|
}
|
|
7589
|
-
if (product.type ===
|
|
7769
|
+
if (product.type === chunkZYACIPKO_js.PRODUCT_TYPE.Composite) {
|
|
7590
7770
|
return "composite" /* Composite */;
|
|
7591
7771
|
}
|
|
7592
7772
|
if (product.quantity_pricing && product.quantity_pricing.length > 1) {
|
|
7593
7773
|
return "wholesale" /* Wholesale */;
|
|
7594
7774
|
}
|
|
7595
|
-
if (product.type ===
|
|
7775
|
+
if (product.type === chunkZYACIPKO_js.PRODUCT_TYPE.Digital) {
|
|
7596
7776
|
return "digital" /* Digital */;
|
|
7597
7777
|
}
|
|
7598
|
-
if (product.type ===
|
|
7778
|
+
if (product.type === chunkZYACIPKO_js.PRODUCT_TYPE.Service) {
|
|
7599
7779
|
if (product.duration_unit && RENTAL_UNITS.has(product.duration_unit)) {
|
|
7600
7780
|
return "rental" /* Rental */;
|
|
7601
7781
|
}
|
|
7602
|
-
if (product.duration_unit ===
|
|
7782
|
+
if (product.duration_unit === chunkZYACIPKO_js.DURATION_UNIT.Nights) {
|
|
7603
7783
|
return "accommodation" /* Accommodation */;
|
|
7604
7784
|
}
|
|
7605
7785
|
if (product.duration_unit && LEASE_UNITS.has(product.duration_unit)) {
|
|
@@ -7610,10 +7790,10 @@ function resolveCardVariant(product) {
|
|
|
7610
7790
|
}
|
|
7611
7791
|
return "standard" /* Standard */;
|
|
7612
7792
|
}
|
|
7613
|
-
if (product.render_hint ===
|
|
7793
|
+
if (product.render_hint === chunkZYACIPKO_js.RENDER_HINT.Food) {
|
|
7614
7794
|
return "food" /* Food */;
|
|
7615
7795
|
}
|
|
7616
|
-
if (product.render_hint ===
|
|
7796
|
+
if (product.render_hint === chunkZYACIPKO_js.RENDER_HINT.Physical) {
|
|
7617
7797
|
return "retail" /* Retail */;
|
|
7618
7798
|
}
|
|
7619
7799
|
return "retail" /* Retail */;
|
|
@@ -7946,7 +8126,7 @@ function SearchInput({
|
|
|
7946
8126
|
}
|
|
7947
8127
|
),
|
|
7948
8128
|
/* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-search-result-name": true, className: classNames?.resultName, style: { flex: 1, textAlign: "left" }, children: product.name }),
|
|
7949
|
-
product.default_price !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-search-result-price": true, className: classNames?.resultPrice, style: { flexShrink: 0 }, children:
|
|
8129
|
+
product.default_price !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-search-result-price": true, className: classNames?.resultPrice, style: { flexShrink: 0 }, children: chunkV2O5AO7I_js.formatPrice(product.default_price) })
|
|
7950
8130
|
] })
|
|
7951
8131
|
},
|
|
7952
8132
|
product.id
|
|
@@ -8440,19 +8620,19 @@ function OrderSummary({
|
|
|
8440
8620
|
order.customer_notes.map((note, index) => /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-order-note": true, children: note }, index))
|
|
8441
8621
|
] }),
|
|
8442
8622
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-order-totals": true, className: classNames?.totals, children: [
|
|
8443
|
-
order.total_discount != null &&
|
|
8623
|
+
order.total_discount != null && chunkV2O5AO7I_js.parsePrice(order.total_discount) !== 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-order-discount": true, children: [
|
|
8444
8624
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Discount" }),
|
|
8445
8625
|
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: order.total_discount, prefix: "-" })
|
|
8446
8626
|
] }),
|
|
8447
|
-
order.delivery_fee != null &&
|
|
8627
|
+
order.delivery_fee != null && chunkV2O5AO7I_js.parsePrice(order.delivery_fee) > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-order-delivery-fee": true, children: [
|
|
8448
8628
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Delivery fee" }),
|
|
8449
8629
|
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: order.delivery_fee })
|
|
8450
8630
|
] }),
|
|
8451
|
-
order.service_charge != null &&
|
|
8631
|
+
order.service_charge != null && chunkV2O5AO7I_js.parsePrice(order.service_charge) !== 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-order-service-charge": true, children: [
|
|
8452
8632
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Service charge" }),
|
|
8453
8633
|
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: order.service_charge })
|
|
8454
8634
|
] }),
|
|
8455
|
-
order.tax != null &&
|
|
8635
|
+
order.tax != null && chunkV2O5AO7I_js.parsePrice(order.tax) !== 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-order-tax": true, children: [
|
|
8456
8636
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Tax" }),
|
|
8457
8637
|
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: order.tax })
|
|
8458
8638
|
] }),
|
|
@@ -9741,7 +9921,7 @@ function DefaultProductLayout({
|
|
|
9741
9921
|
}) {
|
|
9742
9922
|
const images = product.images || (product.image_url ? [product.image_url] : []);
|
|
9743
9923
|
const hasRange = product.quantity_pricing && product.quantity_pricing.length > 1 || product.variants && product.variants.length > 1;
|
|
9744
|
-
const onSale =
|
|
9924
|
+
const onSale = chunkV2O5AO7I_js.isOnSale(product);
|
|
9745
9925
|
const hasPhysicalDetails = product.sku || product.vendor || product.material;
|
|
9746
9926
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-product-layout": "default", className: cn("space-y-8", className), children: [
|
|
9747
9927
|
renderBreadcrumb?.(product),
|
|
@@ -9763,10 +9943,10 @@ function DefaultProductLayout({
|
|
|
9763
9943
|
/* @__PURE__ */ jsxRuntime.jsx("h1", { "data-cimplify-product-layout-name": true, className: "text-3xl lg:text-4xl font-extrabold tracking-tight", children: product.name }),
|
|
9764
9944
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-baseline gap-3", children: hasRange ? /* @__PURE__ */ jsxRuntime.jsx(PriceRange, { product, className: "text-2xl font-extrabold" }) : onSale ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
9765
9945
|
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price, className: "text-2xl font-extrabold" }),
|
|
9766
|
-
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount:
|
|
9946
|
+
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: chunkV2O5AO7I_js.getBasePrice(product), className: "text-lg text-muted-foreground line-through" }),
|
|
9767
9947
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm font-bold text-destructive bg-destructive/10 px-2 py-0.5", children: [
|
|
9768
9948
|
"Save ",
|
|
9769
|
-
|
|
9949
|
+
chunkV2O5AO7I_js.getDiscountPercentage(product),
|
|
9770
9950
|
"%"
|
|
9771
9951
|
] })
|
|
9772
9952
|
] }) : /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price, className: "text-2xl font-semibold" }) }),
|
|
@@ -9985,7 +10165,7 @@ function ServiceProductLayout({
|
|
|
9985
10165
|
}) {
|
|
9986
10166
|
const images = product.images || (product.image_url ? [product.image_url] : []);
|
|
9987
10167
|
const hasDeposit = product.deposit_type && product.deposit_type !== "none" && product.deposit_amount;
|
|
9988
|
-
const depositAmount = hasDeposit ?
|
|
10168
|
+
const depositAmount = hasDeposit ? chunkV2O5AO7I_js.parsePrice(product.deposit_amount) : 0;
|
|
9989
10169
|
const cancellationHours = product.cancellation_window_minutes ? Math.floor(product.cancellation_window_minutes / 60) : null;
|
|
9990
10170
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-product-layout": "service", className: cn("space-y-8", className), children: [
|
|
9991
10171
|
renderBreadcrumb?.(product),
|
|
@@ -10053,7 +10233,7 @@ function ServiceProductLayout({
|
|
|
10053
10233
|
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: depositAmount, className: "font-medium text-foreground" }),
|
|
10054
10234
|
" deposit charged at booking"
|
|
10055
10235
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
10056
|
-
|
|
10236
|
+
chunkV2O5AO7I_js.parsePrice(product.deposit_amount),
|
|
10057
10237
|
"% deposit charged at booking"
|
|
10058
10238
|
] }) })
|
|
10059
10239
|
] })
|
|
@@ -10212,13 +10392,13 @@ function BundleProductLayout({
|
|
|
10212
10392
|
}) {
|
|
10213
10393
|
const images = product.images || (product.image_url ? [product.image_url] : []);
|
|
10214
10394
|
const components = product.components || [];
|
|
10215
|
-
const onSale =
|
|
10216
|
-
const discount =
|
|
10395
|
+
const onSale = chunkV2O5AO7I_js.isOnSale(product);
|
|
10396
|
+
const discount = chunkV2O5AO7I_js.getDiscountPercentage(product);
|
|
10217
10397
|
const baseTotal = components.reduce(
|
|
10218
|
-
(sum, c) => sum +
|
|
10398
|
+
(sum, c) => sum + chunkV2O5AO7I_js.parsePrice(c.effective_price ?? 0) * (c.quantity ?? 1),
|
|
10219
10399
|
0
|
|
10220
10400
|
);
|
|
10221
|
-
const bundlePrice =
|
|
10401
|
+
const bundlePrice = chunkV2O5AO7I_js.parsePrice(product.default_price);
|
|
10222
10402
|
const savings = baseTotal > bundlePrice ? baseTotal - bundlePrice : 0;
|
|
10223
10403
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-product-layout": "bundle", className: cn("space-y-8", className), children: [
|
|
10224
10404
|
renderBreadcrumb?.(product),
|
|
@@ -10374,25 +10554,25 @@ function resolveTemplateKey(product) {
|
|
|
10374
10554
|
if (typeof metaTemplate === "string" && metaTemplate.trim()) {
|
|
10375
10555
|
return metaTemplate.trim();
|
|
10376
10556
|
}
|
|
10377
|
-
if (product.type ===
|
|
10557
|
+
if (product.type === chunkZYACIPKO_js.PRODUCT_TYPE.Bundle) {
|
|
10378
10558
|
return "bundle" /* Bundle */;
|
|
10379
10559
|
}
|
|
10380
|
-
if (product.type ===
|
|
10560
|
+
if (product.type === chunkZYACIPKO_js.PRODUCT_TYPE.Composite) {
|
|
10381
10561
|
return "composite" /* Composite */;
|
|
10382
10562
|
}
|
|
10383
10563
|
if (product.quantity_pricing && product.quantity_pricing.length > 1) {
|
|
10384
10564
|
return "wholesale" /* Wholesale */;
|
|
10385
10565
|
}
|
|
10386
|
-
if (product.type ===
|
|
10566
|
+
if (product.type === chunkZYACIPKO_js.PRODUCT_TYPE.Service) {
|
|
10387
10567
|
return "service" /* Service */;
|
|
10388
10568
|
}
|
|
10389
|
-
if (product.type ===
|
|
10569
|
+
if (product.type === chunkZYACIPKO_js.PRODUCT_TYPE.Digital) {
|
|
10390
10570
|
return "digital" /* Digital */;
|
|
10391
10571
|
}
|
|
10392
|
-
if (product.render_hint ===
|
|
10572
|
+
if (product.render_hint === chunkZYACIPKO_js.RENDER_HINT.Food) {
|
|
10393
10573
|
return "food" /* Food */;
|
|
10394
10574
|
}
|
|
10395
|
-
if (product.render_hint ===
|
|
10575
|
+
if (product.render_hint === chunkZYACIPKO_js.RENDER_HINT.Physical) {
|
|
10396
10576
|
return "physical" /* Physical */;
|
|
10397
10577
|
}
|
|
10398
10578
|
return "default" /* Default */;
|
|
@@ -10845,9 +11025,9 @@ function CatalogueCollectionLayout({
|
|
|
10845
11025
|
result = result.filter((p) => p.tags?.includes(activeCategory));
|
|
10846
11026
|
}
|
|
10847
11027
|
if (sortBy === "price-asc") {
|
|
10848
|
-
result = [...result].sort((a, b) =>
|
|
11028
|
+
result = [...result].sort((a, b) => chunkV2O5AO7I_js.parsePrice(a.default_price) - chunkV2O5AO7I_js.parsePrice(b.default_price));
|
|
10849
11029
|
} else if (sortBy === "price-desc") {
|
|
10850
|
-
result = [...result].sort((a, b) =>
|
|
11030
|
+
result = [...result].sort((a, b) => chunkV2O5AO7I_js.parsePrice(b.default_price) - chunkV2O5AO7I_js.parsePrice(a.default_price));
|
|
10851
11031
|
} else if (sortBy === "name") {
|
|
10852
11032
|
result = [...result].sort((a, b) => a.name.localeCompare(b.name));
|
|
10853
11033
|
}
|
|
@@ -12456,7 +12636,7 @@ function SparkleIcon({ className }) {
|
|
|
12456
12636
|
|
|
12457
12637
|
Object.defineProperty(exports, "getVariantDisplayName", {
|
|
12458
12638
|
enumerable: true,
|
|
12459
|
-
get: function () { return
|
|
12639
|
+
get: function () { return chunkZYACIPKO_js.getVariantDisplayName; }
|
|
12460
12640
|
});
|
|
12461
12641
|
exports.AccommodationCard = AccommodationCard;
|
|
12462
12642
|
exports.Ad = Ad;
|