@cimplify/sdk 0.100.0 → 0.100.2
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 +3 -3
- package/dist/advanced.d.ts +3 -3
- package/dist/advanced.js +22 -22
- package/dist/advanced.mjs +3 -3
- package/dist/{chunk-X6G6QERR.js → chunk-6JEKKL3M.js} +53 -38
- package/dist/{chunk-7TEMLVDT.mjs → chunk-B2YOCOLH.mjs} +2 -2
- package/dist/{chunk-V5TU5JKA.mjs → chunk-DLW3RWRK.mjs} +30 -6
- package/dist/{chunk-FECGCIVV.js → chunk-IFAQLFAJ.js} +4 -4
- package/dist/{chunk-J3UYIBKH.js → chunk-IJI7KMTG.js} +89 -82
- package/dist/{chunk-AETVRBKI.js → chunk-NIOUSKQQ.js} +1 -0
- package/dist/{chunk-K5EN2W2Q.mjs → chunk-O3YUHLZL.mjs} +1 -0
- package/dist/{chunk-GWKIDFN6.mjs → chunk-PJUXAUM2.mjs} +20 -14
- package/dist/{chunk-ZA5VKVUB.js → chunk-QRBBSIAY.js} +4 -4
- package/dist/{chunk-OX5L6XE7.mjs → chunk-TIQLOH2B.mjs} +30 -15
- package/dist/{chunk-64EDCDBR.js → chunk-WMEC5JWN.js} +32 -7
- package/dist/{chunk-I7L4VRHI.mjs → chunk-YWNJJO2U.mjs} +2 -2
- package/dist/{client-DQpvwf-p.d.mts → client-C6wb92AD.d.mts} +2 -2
- package/dist/{client-DmR3Z6pQ.d.ts → client-CgXkRu2o.d.ts} +2 -2
- package/dist/{client-C1vS5pf0.d.ts → client-D8XcrONA.d.mts} +38 -26
- package/dist/{client-B5MeD8da.d.mts → client-LPg_AUUr.d.ts} +38 -26
- package/dist/{index-Br-vFygC.d.ts → index-B_RYmvlF.d.ts} +3 -3
- package/dist/{index-DUOCn1Cs.d.mts → index-D-LUYk1Y.d.mts} +3 -3
- package/dist/index.d.mts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js +117 -117
- package/dist/index.mjs +5 -5
- package/dist/mock/cli.mjs +1 -1
- package/dist/mock/library.js +1 -1
- package/dist/mock/library.mjs +1 -1
- package/dist/mock/msw.js +1 -1
- package/dist/mock/msw.mjs +1 -1
- package/dist/{payment-BIpS9oPG.d.mts → payment-BSzy7sly.d.mts} +1 -1
- package/dist/{payment-CsuBKHqg.d.ts → payment-jK8ztICx.d.ts} +1 -1
- package/dist/{price-Ml_uPoiY.d.ts → price-CJLfcYKd.d.ts} +1 -1
- package/dist/{price-IOOoVYS-.d.mts → price-D96h6c6L.d.mts} +1 -1
- package/dist/{product-BKV6TBj_.d.ts → product-CeV8euw4.d.mts} +23 -11
- package/dist/{product-BKV6TBj_.d.mts → product-CeV8euw4.d.ts} +23 -11
- package/dist/react.d.mts +10 -5
- package/dist/react.d.ts +10 -5
- package/dist/react.js +856 -450
- package/dist/react.mjs +737 -331
- package/dist/{server-C0iEk55_.d.mts → server--RyVAfPN.d.mts} +1 -1
- package/dist/{server-CfpYhSV_.d.ts → server-CNyy47HL.d.ts} +1 -1
- package/dist/server.d.mts +4 -4
- package/dist/server.d.ts +4 -4
- package/dist/server.js +10 -10
- package/dist/server.mjs +4 -4
- package/dist/testing/msw.d.mts +2 -2
- package/dist/testing/msw.d.ts +2 -2
- package/dist/testing/msw.js +3 -3
- package/dist/testing/msw.mjs +2 -2
- package/dist/testing/suite.d.mts +6 -6
- package/dist/testing/suite.d.ts +6 -6
- package/dist/testing/suite.js +25 -25
- package/dist/testing/suite.mjs +6 -6
- package/dist/testing.d.mts +5 -5
- package/dist/testing.d.ts +5 -5
- package/dist/testing.js +81 -81
- package/dist/testing.mjs +7 -7
- package/dist/utils.d.mts +4 -4
- package/dist/utils.d.ts +4 -4
- package/dist/utils.js +29 -29
- package/dist/utils.mjs +2 -2
- package/package.json +1 -1
- package/registry/cart-summary.json +1 -1
- package/registry/product-customizer.json +1 -1
- package/registry/sale-badge.json +1 -1
package/dist/react.js
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
var chunkQPRI2NII_js = require('./chunk-QPRI2NII.js');
|
|
5
5
|
var chunkXREIZ56K_js = require('./chunk-XREIZ56K.js');
|
|
6
|
-
var
|
|
7
|
-
var
|
|
8
|
-
var
|
|
9
|
-
var
|
|
6
|
+
var chunkIJI7KMTG_js = require('./chunk-IJI7KMTG.js');
|
|
7
|
+
var chunk6JEKKL3M_js = require('./chunk-6JEKKL3M.js');
|
|
8
|
+
var chunkWMEC5JWN_js = require('./chunk-WMEC5JWN.js');
|
|
9
|
+
var chunkNIOUSKQQ_js = require('./chunk-NIOUSKQQ.js');
|
|
10
10
|
require('./chunk-OWW5GUSB.js');
|
|
11
11
|
var React14 = require('react');
|
|
12
12
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -379,6 +379,26 @@ function Ad({
|
|
|
379
379
|
}
|
|
380
380
|
|
|
381
381
|
// src/utils/cart-transform.ts
|
|
382
|
+
var DECIMAL_AMOUNT_PATTERN = /^([+-]?)(\d+)(?:\.(\d+))?$/;
|
|
383
|
+
function multiplyDecimalByInteger(value, multiplier) {
|
|
384
|
+
if (!Number.isSafeInteger(multiplier) || multiplier < 0) {
|
|
385
|
+
throw new RangeError("Cart item quantity must be a non-negative safe integer");
|
|
386
|
+
}
|
|
387
|
+
const source = String(value).trim();
|
|
388
|
+
const match = DECIMAL_AMOUNT_PATTERN.exec(source);
|
|
389
|
+
if (!match) {
|
|
390
|
+
throw new TypeError("Cart item price must be a decimal amount");
|
|
391
|
+
}
|
|
392
|
+
const [, sign, whole, fraction = ""] = match;
|
|
393
|
+
const scaledAmount = BigInt(`${sign}${whole}${fraction}`);
|
|
394
|
+
const scaledTotal = scaledAmount * BigInt(multiplier);
|
|
395
|
+
if (fraction.length === 0) return scaledTotal.toString();
|
|
396
|
+
const negative = scaledTotal < 0n;
|
|
397
|
+
const digits = (negative ? -scaledTotal : scaledTotal).toString().padStart(fraction.length + 1, "0");
|
|
398
|
+
const splitAt = digits.length - fraction.length;
|
|
399
|
+
const formatted = `${digits.slice(0, splitAt)}.${digits.slice(splitAt)}`;
|
|
400
|
+
return negative ? `-${formatted}` : formatted;
|
|
401
|
+
}
|
|
382
402
|
function getSelections(item) {
|
|
383
403
|
if (item.bundle_resolved?.selections?.length) {
|
|
384
404
|
return item.bundle_resolved.selections.map((s) => ({
|
|
@@ -397,11 +417,12 @@ function getSelections(item) {
|
|
|
397
417
|
}
|
|
398
418
|
function mapItem(item, fx) {
|
|
399
419
|
const amt = (value) => fx ? String(fx.convertPrice(value)) : String(value);
|
|
420
|
+
const currentUnitPrice = item.total_price;
|
|
400
421
|
const result = {
|
|
401
422
|
name: item.name,
|
|
402
423
|
quantity: item.quantity,
|
|
403
|
-
unit_price: amt(
|
|
404
|
-
total_price: amt(item.
|
|
424
|
+
unit_price: amt(currentUnitPrice),
|
|
425
|
+
total_price: amt(multiplyDecimalByInteger(currentUnitPrice, item.quantity)),
|
|
405
426
|
line_type: item.line_type
|
|
406
427
|
};
|
|
407
428
|
if (item.image_url) result.image_url = item.image_url;
|
|
@@ -422,9 +443,9 @@ function mapItem(item, fx) {
|
|
|
422
443
|
}
|
|
423
444
|
return result;
|
|
424
445
|
}
|
|
425
|
-
function transformToCheckoutCart(cart, fx) {
|
|
446
|
+
function transformToCheckoutCart(cart, fx, checkout) {
|
|
426
447
|
const amt = (value) => fx ? String(fx.convertPrice(value)) : String(value);
|
|
427
|
-
|
|
448
|
+
const checkoutCart = {
|
|
428
449
|
items: cart.items.map((item) => mapItem(item, fx)),
|
|
429
450
|
subtotal: amt(cart.pricing.subtotal),
|
|
430
451
|
tax_amount: amt(cart.pricing.tax_amount),
|
|
@@ -437,6 +458,7 @@ function transformToCheckoutCart(cart, fx) {
|
|
|
437
458
|
deposit_amount: cart.pricing.deposit_amount != null ? amt(cart.pricing.deposit_amount) : void 0,
|
|
438
459
|
requires_delivery: cart.requires_delivery
|
|
439
460
|
};
|
|
461
|
+
return checkoutCart;
|
|
440
462
|
}
|
|
441
463
|
|
|
442
464
|
// src/internal/collection.ts
|
|
@@ -598,16 +620,26 @@ function lineKeyFromItem(item) {
|
|
|
598
620
|
staffId: item.staffId
|
|
599
621
|
});
|
|
600
622
|
}
|
|
601
|
-
function attachInternalItemMetadata(item) {
|
|
602
|
-
|
|
623
|
+
function attachInternalItemMetadata(item, metadata = {}) {
|
|
624
|
+
const internalItem = {
|
|
625
|
+
...item,
|
|
626
|
+
_lineKey: lineKeyFromItem(item)
|
|
627
|
+
};
|
|
628
|
+
if (metadata.quotedUnitPrice !== void 0) {
|
|
629
|
+
internalItem._quotedUnitPrice = metadata.quotedUnitPrice;
|
|
630
|
+
}
|
|
631
|
+
return internalItem;
|
|
603
632
|
}
|
|
604
633
|
function calculateLineSubtotal(item) {
|
|
605
|
-
|
|
634
|
+
if (item._quotedUnitPrice !== void 0) {
|
|
635
|
+
return roundMoney(chunkWMEC5JWN_js.parsePrice(item._quotedUnitPrice) * item.quantity);
|
|
636
|
+
}
|
|
637
|
+
let unitPrice = chunkWMEC5JWN_js.parsePrice(item.product.default_price);
|
|
606
638
|
if (item.variant?.price_adjustment) {
|
|
607
|
-
unitPrice +=
|
|
639
|
+
unitPrice += chunkWMEC5JWN_js.parsePrice(item.variant.price_adjustment);
|
|
608
640
|
}
|
|
609
641
|
for (const option of item.addOnOptions || []) {
|
|
610
|
-
if (option.default_price) unitPrice +=
|
|
642
|
+
if (option.default_price) unitPrice += chunkWMEC5JWN_js.parsePrice(option.default_price);
|
|
611
643
|
}
|
|
612
644
|
return roundMoney(unitPrice * item.quantity);
|
|
613
645
|
}
|
|
@@ -677,10 +709,7 @@ function emptyBase(currency, isLoading = true) {
|
|
|
677
709
|
return { items: [], subtotal: 0, tax: 0, total: 0, currency, isLoading };
|
|
678
710
|
}
|
|
679
711
|
function buildStoreKey(client, locationId) {
|
|
680
|
-
return [
|
|
681
|
-
client.getPublicKey() || "__no_public_key__",
|
|
682
|
-
locationId || "__no_location__"
|
|
683
|
-
].join(":");
|
|
712
|
+
return [client.getPublicKey() || "__no_public_key__", locationId || "__no_location__"].join(":");
|
|
684
713
|
}
|
|
685
714
|
function purgeLegacyCartCachesOnce() {
|
|
686
715
|
if (legacyCachesPurged) return;
|
|
@@ -709,7 +738,10 @@ function toProductFromServerItem(item, businessId) {
|
|
|
709
738
|
slug: item.item_id,
|
|
710
739
|
description: item.description,
|
|
711
740
|
image_url: item.image_url,
|
|
712
|
-
|
|
741
|
+
// Cart price_info is the accepted item price path. Do not reconstruct it
|
|
742
|
+
// from the catalogue base after a sale or shopper-specific quote.
|
|
743
|
+
default_price: item.price_info.final_price,
|
|
744
|
+
currency: item.price_info.currency,
|
|
713
745
|
type: "product",
|
|
714
746
|
inventory_type: "none",
|
|
715
747
|
variant_strategy: "fetch_all",
|
|
@@ -724,37 +756,44 @@ function mapServerCart(serverCart, fallbackCurrency) {
|
|
|
724
756
|
const variant = item.variant_info || item.variant_name ? {
|
|
725
757
|
id: item.variant_info?.id || item.variant_id || "",
|
|
726
758
|
name: item.variant_info?.name || item.variant_name || "Variant",
|
|
727
|
-
price_adjustment: item.variant_info?.price_adjustment
|
|
759
|
+
price_adjustment: item.variant_info?.price_adjustment,
|
|
760
|
+
price_info: item.price_info
|
|
728
761
|
} : void 0;
|
|
729
762
|
const quoteId = typeof item.metadata?.quote_id === "string" ? item.metadata.quote_id : void 0;
|
|
730
|
-
return attachInternalItemMetadata(
|
|
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
|
-
|
|
763
|
+
return attachInternalItemMetadata(
|
|
764
|
+
{
|
|
765
|
+
id: item.id,
|
|
766
|
+
product: toProductFromServerItem(item, serverCart.business_id),
|
|
767
|
+
quantity: clampQuantity(item.quantity),
|
|
768
|
+
locationId: serverCart.location_id,
|
|
769
|
+
variantId: item.variant_id,
|
|
770
|
+
variant,
|
|
771
|
+
quoteId,
|
|
772
|
+
addOnOptionIds: normalizeOptionIds(item.add_on_option_ids || void 0),
|
|
773
|
+
addOnOptions: (item.add_on_options || []).map((option) => ({
|
|
774
|
+
id: option.id,
|
|
775
|
+
name: option.name,
|
|
776
|
+
default_price: option.price
|
|
777
|
+
})),
|
|
778
|
+
bundleSelections: item.bundle_selections || void 0,
|
|
779
|
+
compositeSelections: item.composite_selections || void 0,
|
|
780
|
+
specialInstructions: item.special_instructions,
|
|
781
|
+
scheduledStart: item.scheduled_start || void 0,
|
|
782
|
+
scheduledEnd: item.scheduled_end || void 0,
|
|
783
|
+
staffId: item.staff_id || void 0,
|
|
784
|
+
units: item.units || void 0,
|
|
785
|
+
lineType: item.line_type,
|
|
786
|
+
confirmationCode: item.confirmation_code || void 0,
|
|
787
|
+
serviceStatus: item.service_status || void 0,
|
|
788
|
+
bundleResolved: item.bundle_resolved || void 0,
|
|
789
|
+
compositeResolved: item.composite_resolved || void 0,
|
|
790
|
+
customerInputs: item.customer_inputs || void 0
|
|
791
|
+
},
|
|
792
|
+
// CartItemDetails.total_price is the accepted configured unit amount,
|
|
793
|
+
// including add-ons. It is the only safe basis for optimistic quantity
|
|
794
|
+
// changes and line rendering after the server replaces the temp item.
|
|
795
|
+
{ quotedUnitPrice: item.total_price }
|
|
796
|
+
);
|
|
758
797
|
});
|
|
759
798
|
return {
|
|
760
799
|
items,
|
|
@@ -806,7 +845,7 @@ async function syncFromServer(entry) {
|
|
|
806
845
|
return next;
|
|
807
846
|
}
|
|
808
847
|
function emitMutationError(entry, operation, opId, idempotencyKey, error) {
|
|
809
|
-
entry.client.events.emit(
|
|
848
|
+
entry.client.events.emit(chunkIJI7KMTG_js.MUTATION_ERROR, {
|
|
810
849
|
service: "cart",
|
|
811
850
|
operation,
|
|
812
851
|
opId,
|
|
@@ -846,10 +885,10 @@ function getOrCreateStore(params) {
|
|
|
846
885
|
syncTail: Promise.resolve(),
|
|
847
886
|
failedOpRemovers: /* @__PURE__ */ new Set()
|
|
848
887
|
};
|
|
849
|
-
client.events.on(
|
|
888
|
+
client.events.on(chunkIJI7KMTG_js.SESSION_CLAIMED, () => {
|
|
850
889
|
if (entry.initialized) void syncFromServer(entry);
|
|
851
890
|
});
|
|
852
|
-
client.events.on(
|
|
891
|
+
client.events.on(chunkIJI7KMTG_js.SESSION_CLEARED, () => {
|
|
853
892
|
if (entry.initialized) void syncFromServer(entry);
|
|
854
893
|
});
|
|
855
894
|
cartStores.set(storeKey, entry);
|
|
@@ -895,24 +934,27 @@ async function performAddItem(entry, product, quantity, options) {
|
|
|
895
934
|
addOnOptionIds: normalizeOptionIds(options.addOnOptionIds)
|
|
896
935
|
};
|
|
897
936
|
const lineKey = buildLineKey(product.id, normalizedOptions);
|
|
898
|
-
const tempItem = attachInternalItemMetadata(
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
937
|
+
const tempItem = attachInternalItemMetadata(
|
|
938
|
+
{
|
|
939
|
+
id: `tmp_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`,
|
|
940
|
+
product,
|
|
941
|
+
quantity: resolvedQuantity,
|
|
942
|
+
locationId: normalizedOptions.locationId,
|
|
943
|
+
variantId: normalizedOptions.variantId,
|
|
944
|
+
variant: normalizedOptions.variant,
|
|
945
|
+
quoteId: normalizedOptions.quoteId,
|
|
946
|
+
addOnOptionIds: normalizedOptions.addOnOptionIds,
|
|
947
|
+
addOnOptions: normalizedOptions.addOnOptions,
|
|
948
|
+
bundleSelections: normalizedOptions.bundleSelections,
|
|
949
|
+
compositeSelections: normalizedOptions.compositeSelections,
|
|
950
|
+
specialInstructions: normalizedOptions.specialInstructions,
|
|
951
|
+
scheduledStart: normalizedOptions.scheduledStart,
|
|
952
|
+
scheduledEnd: normalizedOptions.scheduledEnd,
|
|
953
|
+
staffId: normalizedOptions.staffId,
|
|
954
|
+
units: normalizedOptions.units
|
|
955
|
+
},
|
|
956
|
+
{ quotedUnitPrice: normalizedOptions.quotedUnitPrice }
|
|
957
|
+
);
|
|
916
958
|
const idempotencyKey = `idem_${typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : `${Date.now()}_${Math.random().toString(36).slice(2, 10)}`}`;
|
|
917
959
|
const patch = { kind: "add_item", tempItem, lineKey };
|
|
918
960
|
const useOptimistic = entry.optimisticEnabled;
|
|
@@ -1022,12 +1064,12 @@ async function performReorder(entry, orderId) {
|
|
|
1022
1064
|
return result.value;
|
|
1023
1065
|
}
|
|
1024
1066
|
function useCart(options = {}) {
|
|
1025
|
-
const context =
|
|
1067
|
+
const context = useOptionalCimplify();
|
|
1026
1068
|
const client = options.client ?? context?.client;
|
|
1027
1069
|
if (!client) {
|
|
1028
1070
|
throw new Error("useCart must be used within CimplifyProvider or passed { client }.");
|
|
1029
1071
|
}
|
|
1030
|
-
const locationId = options.locationId ?? client.getLocationId();
|
|
1072
|
+
const locationId = options.locationId ?? (context?.client === client ? context.currentLocation?.id ?? (context.isReady ? null : client.getLocationId()) : client.getLocationId());
|
|
1031
1073
|
const currency = options.currency ?? context?.currency ?? "USD";
|
|
1032
1074
|
const optimisticEnabled = context?.optimistic ?? true;
|
|
1033
1075
|
const entry = React14.useMemo(
|
|
@@ -1040,6 +1082,11 @@ function useCart(options = {}) {
|
|
|
1040
1082
|
[client, currency, locationId, optimisticEnabled]
|
|
1041
1083
|
);
|
|
1042
1084
|
const view = useCollectionStore(entry.collection);
|
|
1085
|
+
React14.useEffect(() => {
|
|
1086
|
+
if (client.getLocationId() !== locationId) {
|
|
1087
|
+
client.setLocationId(locationId);
|
|
1088
|
+
}
|
|
1089
|
+
}, [client, locationId]);
|
|
1043
1090
|
React14.useEffect(() => {
|
|
1044
1091
|
void ensureInitialized(entry);
|
|
1045
1092
|
}, [entry]);
|
|
@@ -1145,7 +1192,7 @@ var DEFAULT_COUNTRY = "US";
|
|
|
1145
1192
|
function createDefaultClient() {
|
|
1146
1193
|
const processRef = globalThis.process;
|
|
1147
1194
|
const envPublicKey = processRef?.env?.NEXT_PUBLIC_CIMPLIFY_PUBLIC_KEY || "";
|
|
1148
|
-
return
|
|
1195
|
+
return chunkIJI7KMTG_js.createCimplifyClient({ publicKey: envPublicKey });
|
|
1149
1196
|
}
|
|
1150
1197
|
function getStoredLocationId() {
|
|
1151
1198
|
if (typeof window === "undefined" || !window.localStorage) {
|
|
@@ -1249,7 +1296,7 @@ function CimplifyProvider({
|
|
|
1249
1296
|
const setDisplayCurrency = React14.useCallback(
|
|
1250
1297
|
(currency) => {
|
|
1251
1298
|
const normalized = currency?.trim().toUpperCase() || null;
|
|
1252
|
-
if (normalized && !
|
|
1299
|
+
if (normalized && !chunkNIOUSKQQ_js.isSupportedCurrency(normalized)) {
|
|
1253
1300
|
return;
|
|
1254
1301
|
}
|
|
1255
1302
|
setDisplayCurrencyOverride(normalized);
|
|
@@ -3193,19 +3240,19 @@ function toAccountLineItem(item, currency) {
|
|
|
3193
3240
|
quantity: s.quantity,
|
|
3194
3241
|
name: s.product_name,
|
|
3195
3242
|
variantName: s.variant_name,
|
|
3196
|
-
priceLabel:
|
|
3243
|
+
priceLabel: chunkWMEC5JWN_js.parsePrice(s.unit_price) > 0 ? chunkWMEC5JWN_js.formatMoney(s.unit_price, currency) : void 0
|
|
3197
3244
|
}));
|
|
3198
3245
|
const customisations = item.composite_selections?.selections.map((s) => ({
|
|
3199
3246
|
quantity: s.quantity,
|
|
3200
3247
|
name: s.component_name,
|
|
3201
|
-
priceLabel:
|
|
3248
|
+
priceLabel: chunkWMEC5JWN_js.parsePrice(s.unit_price) > 0 ? `+${chunkWMEC5JWN_js.formatMoney(s.unit_price, currency)}` : void 0
|
|
3202
3249
|
}));
|
|
3203
3250
|
const data = {
|
|
3204
3251
|
id: item.id,
|
|
3205
3252
|
name: item.product_name ?? "Item",
|
|
3206
3253
|
imageUrl: item.image_url,
|
|
3207
3254
|
subtitle: lineSubtitle(item),
|
|
3208
|
-
priceLabel:
|
|
3255
|
+
priceLabel: chunkWMEC5JWN_js.formatMoney(item.total_price, currency),
|
|
3209
3256
|
lineType: item.line_type,
|
|
3210
3257
|
includes,
|
|
3211
3258
|
customisations,
|
|
@@ -3255,20 +3302,20 @@ var PAYMENT_TONE = {
|
|
|
3255
3302
|
function toAccountOrderView(order, opts = {}) {
|
|
3256
3303
|
const currency = order.payment.currency;
|
|
3257
3304
|
const rows = [
|
|
3258
|
-
{ label: "Subtotal", value:
|
|
3305
|
+
{ label: "Subtotal", value: chunkWMEC5JWN_js.formatMoney(order.pricing.subtotal, currency) }
|
|
3259
3306
|
];
|
|
3260
|
-
if (
|
|
3307
|
+
if (chunkWMEC5JWN_js.parsePrice(order.pricing.total_discount) > 0) {
|
|
3261
3308
|
rows.push({
|
|
3262
3309
|
label: "Discount",
|
|
3263
|
-
value: `\u2212${
|
|
3310
|
+
value: `\u2212${chunkWMEC5JWN_js.formatMoney(order.pricing.total_discount, currency)}`,
|
|
3264
3311
|
tone: "positive"
|
|
3265
3312
|
});
|
|
3266
3313
|
}
|
|
3267
|
-
if (order.pricing.tax &&
|
|
3268
|
-
rows.push({ label: "Tax", value:
|
|
3314
|
+
if (order.pricing.tax && chunkWMEC5JWN_js.parsePrice(order.pricing.tax) > 0) {
|
|
3315
|
+
rows.push({ label: "Tax", value: chunkWMEC5JWN_js.formatMoney(order.pricing.tax, currency) });
|
|
3269
3316
|
}
|
|
3270
|
-
if (order.pricing.service_charge &&
|
|
3271
|
-
rows.push({ label: "Service", value:
|
|
3317
|
+
if (order.pricing.service_charge && chunkWMEC5JWN_js.parsePrice(order.pricing.service_charge) > 0) {
|
|
3318
|
+
rows.push({ label: "Service", value: chunkWMEC5JWN_js.formatMoney(order.pricing.service_charge, currency) });
|
|
3272
3319
|
}
|
|
3273
3320
|
const placed = fmtDateTime(order.timestamps.created_at);
|
|
3274
3321
|
const placedLabel = opts.placedLabel ?? [placed && `Placed ${placed}`, `${order.items.length} item${order.items.length === 1 ? "" : "s"}`].filter(Boolean).join(" \xB7 ");
|
|
@@ -3282,7 +3329,7 @@ function toAccountOrderView(order, opts = {}) {
|
|
|
3282
3329
|
stateLabel: cap(order.payment.computed_status ?? order.payment.state),
|
|
3283
3330
|
stateTone: PAYMENT_TONE[order.payment.state] ?? "muted",
|
|
3284
3331
|
rows,
|
|
3285
|
-
total: { label: "Total", value:
|
|
3332
|
+
total: { label: "Total", value: chunkWMEC5JWN_js.formatMoney(order.pricing.total_price, currency) }
|
|
3286
3333
|
},
|
|
3287
3334
|
shipTo: order.customer.delivery_address ? { lines: order.customer.delivery_address } : void 0,
|
|
3288
3335
|
onBack: opts.onBack
|
|
@@ -3457,7 +3504,7 @@ function CimplifySignInButton({
|
|
|
3457
3504
|
const onClick = async () => {
|
|
3458
3505
|
if (busy || disabled || !signInOpts.clientId) return;
|
|
3459
3506
|
setBusy(true);
|
|
3460
|
-
await
|
|
3507
|
+
await chunk6JEKKL3M_js.startSignIn({
|
|
3461
3508
|
...signInOpts,
|
|
3462
3509
|
onSuccess: () => {
|
|
3463
3510
|
setBusy(false);
|
|
@@ -4312,7 +4359,7 @@ function Price({
|
|
|
4312
4359
|
const resolvedAmount = fxActive ? context.convertPrice(amount) : typeof amount === "string" ? parseFloat(amount) || 0 : amount;
|
|
4313
4360
|
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className, children: [
|
|
4314
4361
|
prefix,
|
|
4315
|
-
|
|
4362
|
+
chunkWMEC5JWN_js.formatPrice(resolvedAmount, resolvedCurrency)
|
|
4316
4363
|
] });
|
|
4317
4364
|
}
|
|
4318
4365
|
function createCachedQuery(config) {
|
|
@@ -4899,19 +4946,53 @@ function useSearch(options = {}) {
|
|
|
4899
4946
|
}
|
|
4900
4947
|
var quoteCache = /* @__PURE__ */ new Map();
|
|
4901
4948
|
var quoteInflight = /* @__PURE__ */ new Map();
|
|
4902
|
-
|
|
4903
|
-
|
|
4949
|
+
var quoteClientNamespaces = /* @__PURE__ */ new WeakMap();
|
|
4950
|
+
var nextQuoteClientNamespace = 0;
|
|
4951
|
+
var QUOTE_LOAD_DEBOUNCE_MS = 150;
|
|
4952
|
+
var MIN_AUTO_REFRESH_DELAY_MS = 1e3;
|
|
4953
|
+
function getQuoteClientNamespace(client) {
|
|
4954
|
+
const existing = quoteClientNamespaces.get(client);
|
|
4955
|
+
if (existing !== void 0) {
|
|
4956
|
+
return existing;
|
|
4957
|
+
}
|
|
4958
|
+
const namespace = nextQuoteClientNamespace++;
|
|
4959
|
+
quoteClientNamespaces.set(client, namespace);
|
|
4960
|
+
return namespace;
|
|
4961
|
+
}
|
|
4962
|
+
function buildQuoteCacheKey(client, sessionEpoch, locationId, inputSignature) {
|
|
4963
|
+
return JSON.stringify([
|
|
4964
|
+
getQuoteClientNamespace(client),
|
|
4965
|
+
client.getPublicKey(),
|
|
4966
|
+
sessionEpoch,
|
|
4967
|
+
locationId ?? "",
|
|
4968
|
+
inputSignature
|
|
4969
|
+
]);
|
|
4970
|
+
}
|
|
4971
|
+
function useClientSessionEpoch(client) {
|
|
4972
|
+
const subscribe = React14.useCallback(
|
|
4973
|
+
(notify) => {
|
|
4974
|
+
const unsubscribe = [
|
|
4975
|
+
client.events.on(chunkIJI7KMTG_js.AUTH_TOKEN_CHANGED, notify),
|
|
4976
|
+
client.events.on(chunkIJI7KMTG_js.SESSION_CLAIMED, notify),
|
|
4977
|
+
client.events.on(chunkIJI7KMTG_js.SESSION_CLEARED, notify)
|
|
4978
|
+
];
|
|
4979
|
+
return () => {
|
|
4980
|
+
for (const stopListening of unsubscribe) {
|
|
4981
|
+
stopListening();
|
|
4982
|
+
}
|
|
4983
|
+
};
|
|
4984
|
+
},
|
|
4985
|
+
[client]
|
|
4986
|
+
);
|
|
4987
|
+
const getSnapshot = React14.useCallback(() => client.getSessionEpoch(), [client]);
|
|
4988
|
+
return React14.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
4904
4989
|
}
|
|
4905
4990
|
function serializeQuoteBundleSelections(selections) {
|
|
4906
4991
|
if (!selections || selections.length === 0) {
|
|
4907
4992
|
return "";
|
|
4908
4993
|
}
|
|
4909
4994
|
return selections.map((selection) => {
|
|
4910
|
-
return [
|
|
4911
|
-
selection.component_id,
|
|
4912
|
-
selection.quantity,
|
|
4913
|
-
selection.variant_id ?? ""
|
|
4914
|
-
].join(":");
|
|
4995
|
+
return [selection.component_id, selection.quantity, selection.variant_id ?? ""].join(":");
|
|
4915
4996
|
}).join(";");
|
|
4916
4997
|
}
|
|
4917
4998
|
function serializeQuoteCompositeSelections(selections) {
|
|
@@ -4941,15 +5022,37 @@ function buildQuoteInputSignature(input) {
|
|
|
4941
5022
|
serializeQuoteCompositeSelections(input.compositeSelections)
|
|
4942
5023
|
].join("|");
|
|
4943
5024
|
}
|
|
4944
|
-
function
|
|
5025
|
+
function quoteExpiryTimestamp(quote) {
|
|
4945
5026
|
if (!quote?.expires_at) {
|
|
4946
|
-
return
|
|
5027
|
+
return Number.NaN;
|
|
4947
5028
|
}
|
|
4948
5029
|
const expiresAt = Date.parse(quote.expires_at);
|
|
4949
|
-
|
|
4950
|
-
|
|
5030
|
+
return Number.isFinite(expiresAt) ? expiresAt : Number.NaN;
|
|
5031
|
+
}
|
|
5032
|
+
function isQuoteExpired(quote, now = Date.now()) {
|
|
5033
|
+
const expiresAt = quoteExpiryTimestamp(quote);
|
|
5034
|
+
return Number.isFinite(expiresAt) && expiresAt <= now;
|
|
5035
|
+
}
|
|
5036
|
+
function readUsableCachedQuote(cacheKey2) {
|
|
5037
|
+
const entry = quoteCache.get(cacheKey2);
|
|
5038
|
+
if (!entry) {
|
|
5039
|
+
return null;
|
|
4951
5040
|
}
|
|
4952
|
-
|
|
5041
|
+
if (isQuoteExpired(entry.quote)) {
|
|
5042
|
+
quoteCache.delete(cacheKey2);
|
|
5043
|
+
return null;
|
|
5044
|
+
}
|
|
5045
|
+
return entry.quote;
|
|
5046
|
+
}
|
|
5047
|
+
function requestState(cacheKey2, quote, isLoading) {
|
|
5048
|
+
return {
|
|
5049
|
+
cacheKey: cacheKey2,
|
|
5050
|
+
quote,
|
|
5051
|
+
isLoading,
|
|
5052
|
+
error: null,
|
|
5053
|
+
isExpired: false,
|
|
5054
|
+
messages: quote?.ui_messages ?? []
|
|
5055
|
+
};
|
|
4953
5056
|
}
|
|
4954
5057
|
function normalizeInput(input, fallbackLocationId) {
|
|
4955
5058
|
const productId = input.productId.trim();
|
|
@@ -4966,7 +5069,7 @@ function normalizeInput(input, fallbackLocationId) {
|
|
|
4966
5069
|
};
|
|
4967
5070
|
}
|
|
4968
5071
|
function useQuote(input, options = {}) {
|
|
4969
|
-
const context =
|
|
5072
|
+
const context = useOptionalCimplify();
|
|
4970
5073
|
const client = options.client ?? context?.client;
|
|
4971
5074
|
if (!client) {
|
|
4972
5075
|
throw new Error("useQuote must be used within CimplifyProvider or passed { client }.");
|
|
@@ -4974,59 +5077,58 @@ function useQuote(input, options = {}) {
|
|
|
4974
5077
|
const enabled = options.enabled ?? true;
|
|
4975
5078
|
const autoRefresh = options.autoRefresh ?? true;
|
|
4976
5079
|
const refreshBeforeExpiryMs = Math.max(0, options.refreshBeforeExpiryMs ?? 3e4);
|
|
4977
|
-
const
|
|
5080
|
+
const sessionEpoch = useClientSessionEpoch(client);
|
|
5081
|
+
const fallbackLocationId = context?.client === client ? context.currentLocation?.id ?? (context.isReady ? null : client.getLocationId()) : client.getLocationId();
|
|
4978
5082
|
const requestIdRef = React14.useRef(0);
|
|
4979
|
-
const debounceTimerRef = React14.useRef(null);
|
|
4980
5083
|
const inputSignature = buildQuoteInputSignature(input);
|
|
4981
5084
|
const normalizedInput = React14.useMemo(() => {
|
|
4982
5085
|
if (!input) {
|
|
4983
5086
|
return null;
|
|
4984
5087
|
}
|
|
4985
|
-
const normalized = normalizeInput(input,
|
|
5088
|
+
const normalized = normalizeInput(input, fallbackLocationId);
|
|
4986
5089
|
return normalized.product_id.length > 0 ? normalized : null;
|
|
4987
|
-
}, [inputSignature,
|
|
5090
|
+
}, [inputSignature, fallbackLocationId]);
|
|
4988
5091
|
const cacheKey2 = React14.useMemo(
|
|
4989
|
-
() => buildQuoteCacheKey(
|
|
4990
|
-
|
|
5092
|
+
() => buildQuoteCacheKey(
|
|
5093
|
+
client,
|
|
5094
|
+
sessionEpoch,
|
|
5095
|
+
normalizedInput?.location_id ?? null,
|
|
5096
|
+
inputSignature
|
|
5097
|
+
),
|
|
5098
|
+
[client, inputSignature, normalizedInput?.location_id, sessionEpoch]
|
|
4991
5099
|
);
|
|
4992
|
-
const
|
|
4993
|
-
|
|
4994
|
-
|
|
4995
|
-
|
|
4996
|
-
const
|
|
4997
|
-
const
|
|
4998
|
-
const
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
|
|
5100
|
+
const [state, setState] = React14.useState(() => {
|
|
5101
|
+
const cached = enabled && normalizedInput ? readUsableCachedQuote(cacheKey2) : null;
|
|
5102
|
+
return requestState(cacheKey2, cached, enabled && normalizedInput !== null && !cached);
|
|
5103
|
+
});
|
|
5104
|
+
const stateIsCurrent = state.cacheKey === cacheKey2 && enabled && normalizedInput !== null;
|
|
5105
|
+
const activeQuote = stateIsCurrent ? state.quote : null;
|
|
5106
|
+
const activeQuoteExpired = isQuoteExpired(activeQuote);
|
|
5107
|
+
const quote = activeQuoteExpired ? null : activeQuote;
|
|
5108
|
+
const isLoading = enabled && normalizedInput !== null && (!stateIsCurrent || state.isLoading);
|
|
5109
|
+
const error = stateIsCurrent ? state.error : null;
|
|
5110
|
+
const isExpired = stateIsCurrent ? state.isExpired || activeQuoteExpired : false;
|
|
5111
|
+
const messages = stateIsCurrent ? state.messages : [];
|
|
5112
|
+
const expiresAt = quoteExpiryTimestamp(activeQuote);
|
|
5005
5113
|
const load = React14.useCallback(
|
|
5006
5114
|
async (force = false) => {
|
|
5007
5115
|
if (!enabled || !normalizedInput) {
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
setIsExpired(false);
|
|
5011
|
-
setError(null);
|
|
5012
|
-
setIsLoading(false);
|
|
5116
|
+
requestIdRef.current += 1;
|
|
5117
|
+
setState(requestState(cacheKey2, null, false));
|
|
5013
5118
|
return;
|
|
5014
5119
|
}
|
|
5015
5120
|
const nextRequestId = ++requestIdRef.current;
|
|
5016
|
-
setError(null);
|
|
5017
5121
|
if (!force) {
|
|
5018
|
-
const
|
|
5019
|
-
if (
|
|
5020
|
-
|
|
5021
|
-
setMessages(cacheEntry.quote?.ui_messages ?? []);
|
|
5022
|
-
setIsExpired(isQuoteExpired(cacheEntry.quote));
|
|
5023
|
-
setIsLoading(false);
|
|
5122
|
+
const cachedQuote = readUsableCachedQuote(cacheKey2);
|
|
5123
|
+
if (cachedQuote) {
|
|
5124
|
+
setState(requestState(cacheKey2, cachedQuote, false));
|
|
5024
5125
|
return;
|
|
5025
5126
|
}
|
|
5026
5127
|
}
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
|
|
5128
|
+
setState((current) => ({
|
|
5129
|
+
...requestState(cacheKey2, null, true),
|
|
5130
|
+
isExpired: current.cacheKey === cacheKey2 && current.isExpired
|
|
5131
|
+
}));
|
|
5030
5132
|
try {
|
|
5031
5133
|
const existing = quoteInflight.get(cacheKey2);
|
|
5032
5134
|
const promise = existing ?? (async () => {
|
|
@@ -5043,55 +5145,58 @@ function useQuote(input, options = {}) {
|
|
|
5043
5145
|
}).catch(() => void 0);
|
|
5044
5146
|
}
|
|
5045
5147
|
const value = await promise;
|
|
5046
|
-
|
|
5047
|
-
if (
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
setError(null);
|
|
5148
|
+
const expired = isQuoteExpired(value);
|
|
5149
|
+
if (expired) {
|
|
5150
|
+
quoteCache.delete(cacheKey2);
|
|
5151
|
+
} else {
|
|
5152
|
+
quoteCache.set(cacheKey2, { quote: value });
|
|
5052
5153
|
}
|
|
5053
|
-
} catch (loadError) {
|
|
5054
5154
|
if (nextRequestId === requestIdRef.current) {
|
|
5055
|
-
|
|
5155
|
+
setState({
|
|
5156
|
+
...requestState(cacheKey2, expired ? null : value, false),
|
|
5157
|
+
isExpired: expired
|
|
5158
|
+
});
|
|
5056
5159
|
}
|
|
5057
|
-
}
|
|
5160
|
+
} catch (loadError) {
|
|
5058
5161
|
if (nextRequestId === requestIdRef.current) {
|
|
5059
|
-
|
|
5162
|
+
setState((current) => ({
|
|
5163
|
+
...requestState(cacheKey2, null, false),
|
|
5164
|
+
error: loadError,
|
|
5165
|
+
isExpired: current.cacheKey === cacheKey2 && current.isExpired
|
|
5166
|
+
}));
|
|
5060
5167
|
}
|
|
5061
5168
|
}
|
|
5062
5169
|
},
|
|
5063
5170
|
[cacheKey2, client, enabled, normalizedInput]
|
|
5064
5171
|
);
|
|
5065
5172
|
React14.useEffect(() => {
|
|
5066
|
-
if (
|
|
5067
|
-
clearTimeout(debounceTimerRef.current);
|
|
5068
|
-
}
|
|
5069
|
-
const hasCached = quoteCache.has(cacheKey2);
|
|
5070
|
-
if (hasCached || !enabled || !normalizedInput) {
|
|
5173
|
+
if (!enabled || !normalizedInput || readUsableCachedQuote(cacheKey2)) {
|
|
5071
5174
|
void load(false);
|
|
5072
|
-
|
|
5073
|
-
debounceTimerRef.current = setTimeout(() => {
|
|
5074
|
-
void load(false);
|
|
5075
|
-
}, 150);
|
|
5175
|
+
return;
|
|
5076
5176
|
}
|
|
5177
|
+
const timer = setTimeout(() => {
|
|
5178
|
+
void load(false);
|
|
5179
|
+
}, QUOTE_LOAD_DEBOUNCE_MS);
|
|
5077
5180
|
return () => {
|
|
5078
|
-
|
|
5079
|
-
clearTimeout(debounceTimerRef.current);
|
|
5080
|
-
debounceTimerRef.current = null;
|
|
5081
|
-
}
|
|
5181
|
+
clearTimeout(timer);
|
|
5082
5182
|
};
|
|
5083
5183
|
}, [load, cacheKey2, enabled, normalizedInput]);
|
|
5084
5184
|
const refresh = React14.useCallback(async () => {
|
|
5085
5185
|
if (!enabled || !normalizedInput) {
|
|
5086
5186
|
return;
|
|
5087
5187
|
}
|
|
5088
|
-
if (!quote?.quote_id) {
|
|
5188
|
+
if (!quote?.quote_id || isQuoteExpired(quote)) {
|
|
5189
|
+
quoteCache.delete(cacheKey2);
|
|
5089
5190
|
await load(true);
|
|
5090
5191
|
return;
|
|
5091
5192
|
}
|
|
5092
5193
|
const nextRequestId = ++requestIdRef.current;
|
|
5093
|
-
|
|
5094
|
-
|
|
5194
|
+
setState((current) => ({
|
|
5195
|
+
...current,
|
|
5196
|
+
cacheKey: cacheKey2,
|
|
5197
|
+
isLoading: true,
|
|
5198
|
+
error: null
|
|
5199
|
+
}));
|
|
5095
5200
|
try {
|
|
5096
5201
|
const result = await client.catalogue.refreshQuote({
|
|
5097
5202
|
quote_id: quote.quote_id,
|
|
@@ -5101,52 +5206,67 @@ function useQuote(input, options = {}) {
|
|
|
5101
5206
|
throw result.error;
|
|
5102
5207
|
}
|
|
5103
5208
|
const refreshed = result.value.quote;
|
|
5104
|
-
|
|
5105
|
-
if (
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
setError(null);
|
|
5209
|
+
const expired = isQuoteExpired(refreshed);
|
|
5210
|
+
if (expired) {
|
|
5211
|
+
quoteCache.delete(cacheKey2);
|
|
5212
|
+
} else {
|
|
5213
|
+
quoteCache.set(cacheKey2, { quote: refreshed });
|
|
5110
5214
|
}
|
|
5111
|
-
} catch (refreshError) {
|
|
5112
5215
|
if (nextRequestId === requestIdRef.current) {
|
|
5113
|
-
|
|
5216
|
+
setState({
|
|
5217
|
+
...requestState(cacheKey2, expired ? null : refreshed, false),
|
|
5218
|
+
isExpired: expired
|
|
5219
|
+
});
|
|
5114
5220
|
}
|
|
5115
|
-
}
|
|
5221
|
+
} catch (refreshError) {
|
|
5116
5222
|
if (nextRequestId === requestIdRef.current) {
|
|
5117
|
-
|
|
5223
|
+
setState((current) => ({
|
|
5224
|
+
...current,
|
|
5225
|
+
cacheKey: cacheKey2,
|
|
5226
|
+
isLoading: false,
|
|
5227
|
+
error: refreshError
|
|
5228
|
+
}));
|
|
5118
5229
|
}
|
|
5119
5230
|
}
|
|
5120
5231
|
}, [cacheKey2, client, enabled, load, normalizedInput, quote]);
|
|
5121
5232
|
React14.useEffect(() => {
|
|
5122
|
-
if (!Number.isFinite(
|
|
5123
|
-
setIsExpired(false);
|
|
5233
|
+
if (!activeQuote || !Number.isFinite(expiresAt)) {
|
|
5124
5234
|
return;
|
|
5125
5235
|
}
|
|
5126
|
-
const
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
timers.push(
|
|
5132
|
-
setTimeout(() => {
|
|
5133
|
-
setIsExpired(true);
|
|
5134
|
-
}, Math.max(0, quoteExpiryTimestamp - now))
|
|
5135
|
-
);
|
|
5136
|
-
}
|
|
5137
|
-
if (autoRefresh && enabled && !isCurrentlyExpired) {
|
|
5138
|
-
timers.push(
|
|
5139
|
-
setTimeout(() => {
|
|
5140
|
-
void refresh();
|
|
5141
|
-
}, Math.max(0, quoteExpiryTimestamp - now - refreshBeforeExpiryMs))
|
|
5142
|
-
);
|
|
5236
|
+
const remainingMs = expiresAt - Date.now();
|
|
5237
|
+
if (remainingMs <= 0) {
|
|
5238
|
+
quoteCache.delete(cacheKey2);
|
|
5239
|
+
void load(true);
|
|
5240
|
+
return;
|
|
5143
5241
|
}
|
|
5242
|
+
const expiryTimer = setTimeout(() => {
|
|
5243
|
+
quoteCache.delete(cacheKey2);
|
|
5244
|
+
setState({
|
|
5245
|
+
...requestState(cacheKey2, null, true),
|
|
5246
|
+
isExpired: true
|
|
5247
|
+
});
|
|
5248
|
+
void load(true);
|
|
5249
|
+
}, remainingMs);
|
|
5250
|
+
const refreshDelayMs = remainingMs - refreshBeforeExpiryMs;
|
|
5251
|
+
const refreshTimer = autoRefresh && enabled && refreshDelayMs >= MIN_AUTO_REFRESH_DELAY_MS ? setTimeout(() => {
|
|
5252
|
+
void refresh();
|
|
5253
|
+
}, refreshDelayMs) : null;
|
|
5144
5254
|
return () => {
|
|
5145
|
-
|
|
5146
|
-
|
|
5255
|
+
clearTimeout(expiryTimer);
|
|
5256
|
+
if (refreshTimer) {
|
|
5257
|
+
clearTimeout(refreshTimer);
|
|
5147
5258
|
}
|
|
5148
5259
|
};
|
|
5149
|
-
}, [
|
|
5260
|
+
}, [
|
|
5261
|
+
activeQuote,
|
|
5262
|
+
autoRefresh,
|
|
5263
|
+
cacheKey2,
|
|
5264
|
+
enabled,
|
|
5265
|
+
expiresAt,
|
|
5266
|
+
load,
|
|
5267
|
+
refresh,
|
|
5268
|
+
refreshBeforeExpiryMs
|
|
5269
|
+
]);
|
|
5150
5270
|
return { quote, isLoading, error, refresh, isExpired, messages };
|
|
5151
5271
|
}
|
|
5152
5272
|
|
|
@@ -5335,29 +5455,19 @@ function useBundles(options = {}) {
|
|
|
5335
5455
|
return { bundles: data ?? [], isLoading, error, refetch };
|
|
5336
5456
|
}
|
|
5337
5457
|
function useProductPrice(input) {
|
|
5338
|
-
const {
|
|
5339
|
-
product,
|
|
5340
|
-
quantity = 1,
|
|
5341
|
-
variant,
|
|
5342
|
-
addOnOptions,
|
|
5343
|
-
compositePrice,
|
|
5344
|
-
bundleTotalPrice
|
|
5345
|
-
} = input;
|
|
5458
|
+
const { product, quantity = 1, variant, addOnOptions, compositePrice, bundleTotalPrice } = input;
|
|
5346
5459
|
return React14.useMemo(() => {
|
|
5347
5460
|
let unitPrice;
|
|
5348
5461
|
if (bundleTotalPrice != null) {
|
|
5349
5462
|
unitPrice = bundleTotalPrice;
|
|
5350
5463
|
} else if (compositePrice) {
|
|
5351
|
-
unitPrice =
|
|
5464
|
+
unitPrice = chunkWMEC5JWN_js.parsePrice(compositePrice.final_price);
|
|
5352
5465
|
} else {
|
|
5353
|
-
unitPrice =
|
|
5354
|
-
if (variant?.price_adjustment) {
|
|
5355
|
-
unitPrice += chunk64EDCDBR_js.parsePrice(variant.price_adjustment);
|
|
5356
|
-
}
|
|
5466
|
+
unitPrice = chunkWMEC5JWN_js.getVariantUnitPrice(product, variant);
|
|
5357
5467
|
if (addOnOptions) {
|
|
5358
5468
|
for (const option of addOnOptions) {
|
|
5359
5469
|
if (option.default_price) {
|
|
5360
|
-
unitPrice +=
|
|
5470
|
+
unitPrice += chunkWMEC5JWN_js.parsePrice(option.default_price);
|
|
5361
5471
|
}
|
|
5362
5472
|
}
|
|
5363
5473
|
}
|
|
@@ -5369,7 +5479,15 @@ function useProductPrice(input) {
|
|
|
5369
5479
|
totalPrice,
|
|
5370
5480
|
displayTotalPrice: totalPrice
|
|
5371
5481
|
};
|
|
5372
|
-
}, [
|
|
5482
|
+
}, [
|
|
5483
|
+
product,
|
|
5484
|
+
quantity,
|
|
5485
|
+
variant?.price_adjustment,
|
|
5486
|
+
variant?.price_info,
|
|
5487
|
+
addOnOptions,
|
|
5488
|
+
compositePrice,
|
|
5489
|
+
bundleTotalPrice
|
|
5490
|
+
]);
|
|
5373
5491
|
}
|
|
5374
5492
|
|
|
5375
5493
|
// src/react/hooks/use-orders.ts
|
|
@@ -6186,7 +6304,7 @@ function useChat(options = {}) {
|
|
|
6186
6304
|
const watchSessionClaims = React14.useCallback(() => {
|
|
6187
6305
|
const c = clientRef.current;
|
|
6188
6306
|
if (!c || claimUnsubRef.current) return;
|
|
6189
|
-
const unsubClaimed = c.events.on(
|
|
6307
|
+
const unsubClaimed = c.events.on(chunkIJI7KMTG_js.SESSION_CLAIMED, (event) => {
|
|
6190
6308
|
setClaimedAs(event.customerName || c.support.claimedCustomerName || null);
|
|
6191
6309
|
if (!openedRef.current) {
|
|
6192
6310
|
void openIfExisting();
|
|
@@ -6195,7 +6313,7 @@ function useChat(options = {}) {
|
|
|
6195
6313
|
connectWebSocket();
|
|
6196
6314
|
void resyncConversation();
|
|
6197
6315
|
});
|
|
6198
|
-
const unsubCleared = c.events.on(
|
|
6316
|
+
const unsubCleared = c.events.on(chunkIJI7KMTG_js.SESSION_CLEARED, resetConversation);
|
|
6199
6317
|
claimUnsubRef.current = () => {
|
|
6200
6318
|
unsubClaimed();
|
|
6201
6319
|
unsubCleared();
|
|
@@ -6247,7 +6365,7 @@ function useChat(options = {}) {
|
|
|
6247
6365
|
if (!openedRef.current) return false;
|
|
6248
6366
|
}
|
|
6249
6367
|
const replyTo = opts?.replyTo;
|
|
6250
|
-
const clientId =
|
|
6368
|
+
const clientId = chunk6JEKKL3M_js.generateIdempotencyKey();
|
|
6251
6369
|
const localId = optimisticId(clientId);
|
|
6252
6370
|
const optimistic = {
|
|
6253
6371
|
id: localId,
|
|
@@ -6436,15 +6554,15 @@ function AuthElement({
|
|
|
6436
6554
|
}, [onReady, onAuthenticated, onError]);
|
|
6437
6555
|
React14.useEffect(() => {
|
|
6438
6556
|
if (!elements || !containerRef.current) return;
|
|
6439
|
-
const element = elements.create(
|
|
6557
|
+
const element = elements.create(chunk6JEKKL3M_js.ELEMENT_TYPES.AUTH, { prefillEmail });
|
|
6440
6558
|
elementRef.current = element;
|
|
6441
|
-
element.on(
|
|
6559
|
+
element.on(chunk6JEKKL3M_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
|
|
6442
6560
|
element.on(
|
|
6443
|
-
|
|
6561
|
+
chunk6JEKKL3M_js.EVENT_TYPES.AUTHENTICATED,
|
|
6444
6562
|
(data) => onAuthenticatedRef.current?.(data)
|
|
6445
6563
|
);
|
|
6446
6564
|
element.on(
|
|
6447
|
-
|
|
6565
|
+
chunk6JEKKL3M_js.EVENT_TYPES.ERROR,
|
|
6448
6566
|
(data) => onErrorRef.current?.(data)
|
|
6449
6567
|
);
|
|
6450
6568
|
element.mount(containerRef.current);
|
|
@@ -6473,15 +6591,15 @@ function AddressElement({
|
|
|
6473
6591
|
}, [onReady, onChange, onError]);
|
|
6474
6592
|
React14.useEffect(() => {
|
|
6475
6593
|
if (!elements || !containerRef.current) return;
|
|
6476
|
-
const element = elements.create(
|
|
6594
|
+
const element = elements.create(chunk6JEKKL3M_js.ELEMENT_TYPES.ADDRESS, { mode });
|
|
6477
6595
|
elementRef.current = element;
|
|
6478
|
-
element.on(
|
|
6596
|
+
element.on(chunk6JEKKL3M_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
|
|
6479
6597
|
element.on(
|
|
6480
|
-
|
|
6598
|
+
chunk6JEKKL3M_js.EVENT_TYPES.CHANGE,
|
|
6481
6599
|
(data) => onChangeRef.current?.(data)
|
|
6482
6600
|
);
|
|
6483
6601
|
element.on(
|
|
6484
|
-
|
|
6602
|
+
chunk6JEKKL3M_js.EVENT_TYPES.ERROR,
|
|
6485
6603
|
(data) => onErrorRef.current?.(data)
|
|
6486
6604
|
);
|
|
6487
6605
|
element.mount(containerRef.current);
|
|
@@ -6511,15 +6629,15 @@ function PaymentElement({
|
|
|
6511
6629
|
}, [onReady, onChange, onError]);
|
|
6512
6630
|
React14.useEffect(() => {
|
|
6513
6631
|
if (!elements || !containerRef.current) return;
|
|
6514
|
-
const element = elements.create(
|
|
6632
|
+
const element = elements.create(chunk6JEKKL3M_js.ELEMENT_TYPES.PAYMENT, { amount, currency });
|
|
6515
6633
|
elementRef.current = element;
|
|
6516
|
-
element.on(
|
|
6634
|
+
element.on(chunk6JEKKL3M_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
|
|
6517
6635
|
element.on(
|
|
6518
|
-
|
|
6636
|
+
chunk6JEKKL3M_js.EVENT_TYPES.CHANGE,
|
|
6519
6637
|
(data) => onChangeRef.current?.(data)
|
|
6520
6638
|
);
|
|
6521
6639
|
element.on(
|
|
6522
|
-
|
|
6640
|
+
chunk6JEKKL3M_js.EVENT_TYPES.ERROR,
|
|
6523
6641
|
(data) => onErrorRef.current?.(data)
|
|
6524
6642
|
);
|
|
6525
6643
|
element.mount(containerRef.current);
|
|
@@ -6676,7 +6794,7 @@ function VariantSelector({
|
|
|
6676
6794
|
if (!variants || variants.length <= 1) {
|
|
6677
6795
|
return null;
|
|
6678
6796
|
}
|
|
6679
|
-
basePrice != null ?
|
|
6797
|
+
basePrice != null ? chunkWMEC5JWN_js.parsePrice(basePrice) : 0;
|
|
6680
6798
|
if (variantAxes && variantAxes.length > 0) {
|
|
6681
6799
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-variant-selector": true, className: cn("space-y-5", className, classNames?.root), children: variantAxes.map((axis) => {
|
|
6682
6800
|
const labelId = `${idPrefix}-axis-${axis.id}`;
|
|
@@ -6782,7 +6900,7 @@ function VariantSelector({
|
|
|
6782
6900
|
className: cn("divide-y divide-border", classNames?.list),
|
|
6783
6901
|
children: variants.map((variant) => {
|
|
6784
6902
|
const isSelected = selectedVariantId === variant.id;
|
|
6785
|
-
const adjustment =
|
|
6903
|
+
const adjustment = chunkWMEC5JWN_js.parsePrice(variant.price_adjustment);
|
|
6786
6904
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6787
6905
|
radio.Radio.Root,
|
|
6788
6906
|
{
|
|
@@ -7050,16 +7168,16 @@ function BundleSelector({
|
|
|
7050
7168
|
}, [components, selections, onReady]);
|
|
7051
7169
|
const totalPrice = React14.useMemo(() => {
|
|
7052
7170
|
if (pricingType === "fixed" && bundlePrice) {
|
|
7053
|
-
return
|
|
7171
|
+
return chunkWMEC5JWN_js.parsePrice(bundlePrice);
|
|
7054
7172
|
}
|
|
7055
7173
|
const componentsTotal = components.reduce((sum, comp) => {
|
|
7056
7174
|
return sum + getComponentPrice(comp, variantChoices[comp.id]) * comp.quantity;
|
|
7057
7175
|
}, 0);
|
|
7058
7176
|
if (pricingType === "percentage_discount" && discountValue) {
|
|
7059
|
-
return componentsTotal * (1 -
|
|
7177
|
+
return componentsTotal * (1 - chunkWMEC5JWN_js.parsePrice(discountValue) / 100);
|
|
7060
7178
|
}
|
|
7061
7179
|
if (pricingType === "fixed_discount" && discountValue) {
|
|
7062
|
-
return componentsTotal -
|
|
7180
|
+
return componentsTotal - chunkWMEC5JWN_js.parsePrice(discountValue);
|
|
7063
7181
|
}
|
|
7064
7182
|
return componentsTotal;
|
|
7065
7183
|
}, [components, variantChoices, pricingType, bundlePrice, discountValue]);
|
|
@@ -7121,15 +7239,15 @@ function BundleSelector({
|
|
|
7121
7239
|
}
|
|
7122
7240
|
function getComponentPrice(component, selectedVariantId) {
|
|
7123
7241
|
if (!selectedVariantId || component.available_variants.length === 0) {
|
|
7124
|
-
return
|
|
7242
|
+
return chunkWMEC5JWN_js.parsePrice(component.effective_price);
|
|
7125
7243
|
}
|
|
7126
7244
|
if (selectedVariantId === component.variant_id) {
|
|
7127
|
-
return
|
|
7245
|
+
return chunkWMEC5JWN_js.parsePrice(component.effective_price);
|
|
7128
7246
|
}
|
|
7129
7247
|
const bakedAdj = component.variant_id ? component.available_variants.find((v) => v.id === component.variant_id) : void 0;
|
|
7130
7248
|
const selectedAdj = component.available_variants.find((v) => v.id === selectedVariantId);
|
|
7131
|
-
if (!selectedAdj) return
|
|
7132
|
-
return
|
|
7249
|
+
if (!selectedAdj) return chunkWMEC5JWN_js.parsePrice(component.effective_price);
|
|
7250
|
+
return chunkWMEC5JWN_js.parsePrice(component.effective_price) - chunkWMEC5JWN_js.parsePrice(bakedAdj?.price_adjustment ?? "0") + chunkWMEC5JWN_js.parsePrice(selectedAdj.price_adjustment);
|
|
7133
7251
|
}
|
|
7134
7252
|
function formatDuration(minutes, unit) {
|
|
7135
7253
|
if (unit === "hours" || !unit && minutes >= 60 && minutes % 60 === 0) {
|
|
@@ -7243,7 +7361,7 @@ function BundleComponentCard({
|
|
|
7243
7361
|
className: cn("mt-3 divide-y divide-border", classNames?.variantPicker),
|
|
7244
7362
|
children: component.available_variants.map((variant) => {
|
|
7245
7363
|
const isSelected = selectedVariantId === variant.id;
|
|
7246
|
-
const adjustment =
|
|
7364
|
+
const adjustment = chunkWMEC5JWN_js.parsePrice(variant.price_adjustment);
|
|
7247
7365
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7248
7366
|
radio.Radio.Root,
|
|
7249
7367
|
{
|
|
@@ -7690,7 +7808,7 @@ function CompositeSelector({
|
|
|
7690
7808
|
"data-cimplify-composite-summary": true,
|
|
7691
7809
|
className: cn("border-t border-border pt-4 space-y-1 text-sm", classNames?.summary),
|
|
7692
7810
|
children: [
|
|
7693
|
-
|
|
7811
|
+
chunkWMEC5JWN_js.parsePrice(priceResult.base_price) !== 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7694
7812
|
"div",
|
|
7695
7813
|
{
|
|
7696
7814
|
"data-cimplify-composite-summary-line": true,
|
|
@@ -7701,7 +7819,7 @@ function CompositeSelector({
|
|
|
7701
7819
|
]
|
|
7702
7820
|
}
|
|
7703
7821
|
),
|
|
7704
|
-
|
|
7822
|
+
chunkWMEC5JWN_js.parsePrice(priceResult.components_total) !== 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7705
7823
|
"div",
|
|
7706
7824
|
{
|
|
7707
7825
|
"data-cimplify-composite-summary-line": true,
|
|
@@ -7845,7 +7963,7 @@ function BookingSummary({
|
|
|
7845
7963
|
className,
|
|
7846
7964
|
classNames
|
|
7847
7965
|
}) {
|
|
7848
|
-
const depositValue = depositAmount != null ?
|
|
7966
|
+
const depositValue = depositAmount != null ? chunkWMEC5JWN_js.parsePrice(depositAmount) : 0;
|
|
7849
7967
|
const depositDue = depositType === "percentage" ? total * depositValue / 100 : depositType === "fixed" ? depositValue : 0;
|
|
7850
7968
|
const hasDeposit = depositDue > 0;
|
|
7851
7969
|
const balance = Math.max(0, total - depositDue);
|
|
@@ -8568,7 +8686,7 @@ function InputField({
|
|
|
8568
8686
|
currency,
|
|
8569
8687
|
classNames
|
|
8570
8688
|
}) {
|
|
8571
|
-
const hasPriceAdjustment = field.price_adjustment != null &&
|
|
8689
|
+
const hasPriceAdjustment = field.price_adjustment != null && chunkWMEC5JWN_js.parsePrice(field.price_adjustment) > 0;
|
|
8572
8690
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-customer-input": true, "data-field-type": field.field_type, className: classNames?.field, children: [
|
|
8573
8691
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-1.5", children: [
|
|
8574
8692
|
/* @__PURE__ */ jsxRuntime.jsx("label", { className: cn("text-sm font-semibold", classNames?.label), children: field.name }),
|
|
@@ -9621,7 +9739,18 @@ function DateSlotPicker({
|
|
|
9621
9739
|
}
|
|
9622
9740
|
);
|
|
9623
9741
|
}
|
|
9624
|
-
|
|
9742
|
+
var REQUIRED_OPTIONS_MESSAGE = "Please select all required options";
|
|
9743
|
+
var QUOTE_LOADING_MESSAGE = "Updating price\u2026";
|
|
9744
|
+
var QUOTE_UNAVAILABLE_MESSAGE = "Price is unavailable. Please try again.";
|
|
9745
|
+
var CUSTOMIZER_VALIDATION_ID = "cimplify-customizer-validation";
|
|
9746
|
+
function initialVariantSelection(product) {
|
|
9747
|
+
const variant = product.variants?.find((candidate) => candidate.is_default) ?? product.variants?.[0];
|
|
9748
|
+
return { id: variant?.id, variant };
|
|
9749
|
+
}
|
|
9750
|
+
function ProductCustomizer(props) {
|
|
9751
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ProductCustomizerContent, { ...props }, props.product.id);
|
|
9752
|
+
}
|
|
9753
|
+
function ProductCustomizerContent({
|
|
9625
9754
|
product,
|
|
9626
9755
|
onAddToCart,
|
|
9627
9756
|
onVariantChange,
|
|
@@ -9633,8 +9762,11 @@ function ProductCustomizer({
|
|
|
9633
9762
|
const [quantity, setQuantity] = React14.useState(product.min_order_quantity ?? 1);
|
|
9634
9763
|
const [isAdded, setIsAdded] = React14.useState(false);
|
|
9635
9764
|
const [isSubmitting, setIsSubmitting] = React14.useState(false);
|
|
9636
|
-
const [
|
|
9637
|
-
|
|
9765
|
+
const [variantSelection, setVariantSelection] = React14.useState(
|
|
9766
|
+
() => initialVariantSelection(product)
|
|
9767
|
+
);
|
|
9768
|
+
const selectedVariantId = variantSelection.id;
|
|
9769
|
+
const selectedVariant = variantSelection.variant;
|
|
9638
9770
|
const [selectedAddOnOptionIds, setSelectedAddOnOptionIds] = React14.useState([]);
|
|
9639
9771
|
const [compositeSelections, setCompositeSelections] = React14.useState([]);
|
|
9640
9772
|
const [compositePrice, setCompositePrice] = React14.useState(null);
|
|
@@ -9649,7 +9781,6 @@ function ProductCustomizer({
|
|
|
9649
9781
|
const [selectedStaffId, setSelectedStaffId] = React14.useState(null);
|
|
9650
9782
|
const [unitsCount, setUnitsCount] = React14.useState(1);
|
|
9651
9783
|
const cart = useCart();
|
|
9652
|
-
const currency = chunk64EDCDBR_js.getProductCurrency(product);
|
|
9653
9784
|
const productType = product.type || "product";
|
|
9654
9785
|
const isComposite = productType === "composite";
|
|
9655
9786
|
const isBundle = productType === "bundle";
|
|
@@ -9659,26 +9790,6 @@ function ProductCustomizer({
|
|
|
9659
9790
|
const isStandard = !isComposite && !isBundle;
|
|
9660
9791
|
const hasVariants = isStandard && product.variants && product.variants.length > 0;
|
|
9661
9792
|
const hasAddOns = isStandard && product.add_ons && product.add_ons.length > 0;
|
|
9662
|
-
React14.useEffect(() => {
|
|
9663
|
-
setQuantity(product.min_order_quantity ?? 1);
|
|
9664
|
-
setIsAdded(false);
|
|
9665
|
-
setIsSubmitting(false);
|
|
9666
|
-
setSelectedVariantId(void 0);
|
|
9667
|
-
setSelectedVariant(void 0);
|
|
9668
|
-
setSelectedAddOnOptionIds([]);
|
|
9669
|
-
setCompositeSelections([]);
|
|
9670
|
-
setCompositePrice(null);
|
|
9671
|
-
setCompositeReady(false);
|
|
9672
|
-
setBundleSelections([]);
|
|
9673
|
-
setBundleTotalPrice(null);
|
|
9674
|
-
setBundleReady(false);
|
|
9675
|
-
setSelectedBillingPlan(null);
|
|
9676
|
-
setCustomerInputValues({});
|
|
9677
|
-
setSpecialInstructions("");
|
|
9678
|
-
setSelectedSlot(null);
|
|
9679
|
-
setSelectedStaffId(null);
|
|
9680
|
-
setUnitsCount(1);
|
|
9681
|
-
}, [product.id, product.min_order_quantity]);
|
|
9682
9793
|
const slotStaff = React14.useMemo(
|
|
9683
9794
|
() => (selectedSlot?.available_staff ?? []).map((member) => ({
|
|
9684
9795
|
id: member.staff_id,
|
|
@@ -9701,26 +9812,34 @@ function ProductCustomizer({
|
|
|
9701
9812
|
}, [product.add_ons, selectedAddOnOptionIds]);
|
|
9702
9813
|
const normalizedAddOnOptionIds = React14.useMemo(() => {
|
|
9703
9814
|
if (selectedAddOnOptionIds.length === 0) return [];
|
|
9704
|
-
return Array.from(
|
|
9815
|
+
return Array.from(
|
|
9816
|
+
new Set(selectedAddOnOptionIds.map((id) => id.trim()).filter(Boolean))
|
|
9817
|
+
).sort();
|
|
9705
9818
|
}, [selectedAddOnOptionIds]);
|
|
9706
9819
|
const localTotalPrice = React14.useMemo(() => {
|
|
9707
9820
|
if (isComposite && compositePrice) {
|
|
9708
|
-
return
|
|
9821
|
+
return chunkWMEC5JWN_js.parsePrice(compositePrice.final_price) * quantity;
|
|
9709
9822
|
}
|
|
9710
9823
|
if (isBundle && bundleTotalPrice != null) {
|
|
9711
9824
|
return bundleTotalPrice * quantity;
|
|
9712
9825
|
}
|
|
9713
|
-
let price =
|
|
9714
|
-
if (selectedVariant?.price_adjustment) {
|
|
9715
|
-
price += chunk64EDCDBR_js.parsePrice(selectedVariant.price_adjustment);
|
|
9716
|
-
}
|
|
9826
|
+
let price = chunkWMEC5JWN_js.getVariantUnitPrice(product, selectedVariant);
|
|
9717
9827
|
for (const option of selectedAddOnOptions) {
|
|
9718
9828
|
if (option.default_price) {
|
|
9719
|
-
price +=
|
|
9829
|
+
price += chunkWMEC5JWN_js.parsePrice(option.default_price);
|
|
9720
9830
|
}
|
|
9721
9831
|
}
|
|
9722
9832
|
return price * quantity;
|
|
9723
|
-
}, [
|
|
9833
|
+
}, [
|
|
9834
|
+
product.default_price,
|
|
9835
|
+
selectedVariant,
|
|
9836
|
+
selectedAddOnOptions,
|
|
9837
|
+
quantity,
|
|
9838
|
+
isComposite,
|
|
9839
|
+
compositePrice,
|
|
9840
|
+
isBundle,
|
|
9841
|
+
bundleTotalPrice
|
|
9842
|
+
]);
|
|
9724
9843
|
const requiredAddOnsSatisfied = React14.useMemo(() => {
|
|
9725
9844
|
if (!product.add_ons) return true;
|
|
9726
9845
|
for (const addOn of product.add_ons) {
|
|
@@ -9745,7 +9864,16 @@ function ProductCustomizer({
|
|
|
9745
9864
|
bundleSelections: isBundle && bundleSelections.length > 0 ? bundleSelections : void 0,
|
|
9746
9865
|
compositeSelections: isComposite && compositeSelections.length > 0 ? compositeSelections : void 0
|
|
9747
9866
|
}),
|
|
9748
|
-
[
|
|
9867
|
+
[
|
|
9868
|
+
product.id,
|
|
9869
|
+
quantity,
|
|
9870
|
+
selectedVariantId,
|
|
9871
|
+
normalizedAddOnOptionIds,
|
|
9872
|
+
isBundle,
|
|
9873
|
+
bundleSelections,
|
|
9874
|
+
isComposite,
|
|
9875
|
+
compositeSelections
|
|
9876
|
+
]
|
|
9749
9877
|
);
|
|
9750
9878
|
const requiredInputsSatisfied = React14.useMemo(() => {
|
|
9751
9879
|
if (!product.input_fields || product.input_fields.length === 0) return true;
|
|
@@ -9756,17 +9884,23 @@ function ProductCustomizer({
|
|
|
9756
9884
|
});
|
|
9757
9885
|
}, [product.input_fields, customerInputValues]);
|
|
9758
9886
|
const quoteEnabled = isComposite ? compositeReady && requiredInputsSatisfied : isBundle ? bundleReady && requiredInputsSatisfied : requiredAddOnsSatisfied && requiredInputsSatisfied;
|
|
9759
|
-
const {
|
|
9887
|
+
const {
|
|
9888
|
+
quote,
|
|
9889
|
+
isLoading: isQuoteLoading,
|
|
9890
|
+
error: quoteError,
|
|
9891
|
+
isExpired: isQuoteExpired2
|
|
9892
|
+
} = useQuote(quoteInput, {
|
|
9760
9893
|
enabled: quoteEnabled
|
|
9761
9894
|
});
|
|
9895
|
+
const currency = quote?.currency ?? chunkWMEC5JWN_js.getProductCurrency(product);
|
|
9762
9896
|
const quoteId = quote?.quote_id;
|
|
9897
|
+
const quotedUnitPrice = (quote?.quoted_total_price_info ?? quote?.final_price_info)?.final_price;
|
|
9763
9898
|
const quotedTotalPrice = React14.useMemo(() => {
|
|
9764
|
-
if (
|
|
9765
|
-
|
|
9766
|
-
|
|
9767
|
-
|
|
9768
|
-
|
|
9769
|
-
}, [quote, quantity]);
|
|
9899
|
+
if (quotedUnitPrice === void 0 || quotedUnitPrice === null) return void 0;
|
|
9900
|
+
return chunkWMEC5JWN_js.parsePrice(quotedUnitPrice) * quantity;
|
|
9901
|
+
}, [quotedUnitPrice, quantity]);
|
|
9902
|
+
const quoteIsReady = quoteEnabled && quote !== null && !isQuoteLoading && !quoteError && !isQuoteExpired2;
|
|
9903
|
+
const validationMessage = !quoteEnabled ? REQUIRED_OPTIONS_MESSAGE : quoteError ? QUOTE_UNAVAILABLE_MESSAGE : !quoteIsReady ? QUOTE_LOADING_MESSAGE : null;
|
|
9770
9904
|
const displayTotalPrice = React14.useMemo(() => {
|
|
9771
9905
|
const total = quotedTotalPrice ?? localTotalPrice;
|
|
9772
9906
|
const multiplier = chunkQPRI2NII_js.serviceBillingMultiplier(product, {
|
|
@@ -9780,8 +9914,7 @@ function ProductCustomizer({
|
|
|
9780
9914
|
}, [quotedTotalPrice, localTotalPrice, product, quantity, unitsCount, selectedSlot]);
|
|
9781
9915
|
const handleVariantChange = React14.useCallback(
|
|
9782
9916
|
(variantId, variant) => {
|
|
9783
|
-
|
|
9784
|
-
setSelectedVariant(variant);
|
|
9917
|
+
setVariantSelection({ id: variantId, variant });
|
|
9785
9918
|
onVariantChange?.(variantId, variant);
|
|
9786
9919
|
},
|
|
9787
9920
|
[onVariantChange]
|
|
@@ -9789,12 +9922,21 @@ function ProductCustomizer({
|
|
|
9789
9922
|
const addedTimerRef = React14.useRef(void 0);
|
|
9790
9923
|
React14.useEffect(() => () => clearTimeout(addedTimerRef.current), []);
|
|
9791
9924
|
const handleAddToCart = React14.useCallback(async () => {
|
|
9792
|
-
if (isSubmitting)
|
|
9925
|
+
if (isSubmitting || !quoteIsReady || !quote || quotedUnitPrice === void 0 || quotedUnitPrice === null) {
|
|
9926
|
+
return;
|
|
9927
|
+
}
|
|
9793
9928
|
setIsSubmitting(true);
|
|
9794
9929
|
const options = {
|
|
9930
|
+
locationId: quote.location_id ?? void 0,
|
|
9795
9931
|
variantId: selectedVariantId,
|
|
9796
|
-
variant: selectedVariant ? {
|
|
9932
|
+
variant: selectedVariant ? {
|
|
9933
|
+
id: selectedVariant.id,
|
|
9934
|
+
name: selectedVariant.name || "",
|
|
9935
|
+
price_adjustment: selectedVariant.price_adjustment,
|
|
9936
|
+
price_info: selectedVariant.price_info
|
|
9937
|
+
} : void 0,
|
|
9797
9938
|
quoteId,
|
|
9939
|
+
quotedUnitPrice,
|
|
9798
9940
|
addOnOptionIds: normalizedAddOnOptionIds.length > 0 ? normalizedAddOnOptionIds : void 0,
|
|
9799
9941
|
addOnOptions: selectedAddOnOptions.length > 0 ? selectedAddOnOptions.map((opt) => ({
|
|
9800
9942
|
id: opt.id,
|
|
@@ -9831,7 +9973,32 @@ function ProductCustomizer({
|
|
|
9831
9973
|
} finally {
|
|
9832
9974
|
setIsSubmitting(false);
|
|
9833
9975
|
}
|
|
9834
|
-
}, [
|
|
9976
|
+
}, [
|
|
9977
|
+
product,
|
|
9978
|
+
quantity,
|
|
9979
|
+
selectedVariantId,
|
|
9980
|
+
selectedVariant,
|
|
9981
|
+
quoteId,
|
|
9982
|
+
quotedUnitPrice,
|
|
9983
|
+
normalizedAddOnOptionIds,
|
|
9984
|
+
selectedAddOnOptions,
|
|
9985
|
+
isComposite,
|
|
9986
|
+
compositeSelections,
|
|
9987
|
+
isBundle,
|
|
9988
|
+
bundleSelections,
|
|
9989
|
+
selectedBillingPlan,
|
|
9990
|
+
customerInputValues,
|
|
9991
|
+
specialInstructions,
|
|
9992
|
+
isService,
|
|
9993
|
+
selectedSlot,
|
|
9994
|
+
selectedStaffId,
|
|
9995
|
+
unitsCount,
|
|
9996
|
+
isSubmitting,
|
|
9997
|
+
onAddToCart,
|
|
9998
|
+
cart,
|
|
9999
|
+
quoteIsReady,
|
|
10000
|
+
quote
|
|
10001
|
+
]);
|
|
9835
10002
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-customizer": true, className: cn("space-y-6", className, classNames?.root), children: [
|
|
9836
10003
|
isComposite && product.groups && product.composite_id && /* @__PURE__ */ jsxRuntime.jsx(
|
|
9837
10004
|
CompositeSelector,
|
|
@@ -9944,27 +10111,48 @@ function ProductCustomizer({
|
|
|
9944
10111
|
currency
|
|
9945
10112
|
}
|
|
9946
10113
|
),
|
|
9947
|
-
product.deposit_type && product.deposit_type !== "none" && product.deposit_amount && /* @__PURE__ */ jsxRuntime.jsx(
|
|
9948
|
-
"
|
|
9949
|
-
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.deposit_amount, currency })
|
|
9950
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
9951
|
-
"Deposit required: ",
|
|
9952
|
-
chunk64EDCDBR_js.parsePrice(product.deposit_amount),
|
|
9953
|
-
"%"
|
|
9954
|
-
] }) }),
|
|
9955
|
-
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(
|
|
9956
|
-
"span",
|
|
10114
|
+
product.deposit_type && product.deposit_type !== "none" && product.deposit_amount && /* @__PURE__ */ jsxRuntime.jsx(
|
|
10115
|
+
"div",
|
|
9957
10116
|
{
|
|
9958
|
-
"data-cimplify-
|
|
9959
|
-
className: "
|
|
9960
|
-
children:
|
|
9961
|
-
|
|
9962
|
-
|
|
9963
|
-
|
|
9964
|
-
|
|
9965
|
-
|
|
9966
|
-
|
|
9967
|
-
|
|
10117
|
+
"data-cimplify-customizer-deposit": true,
|
|
10118
|
+
className: cn("text-sm text-muted-foreground", classNames?.depositInfo),
|
|
10119
|
+
children: product.deposit_type === "fixed" ? /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
10120
|
+
"Deposit required: ",
|
|
10121
|
+
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.deposit_amount, currency })
|
|
10122
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
10123
|
+
"Deposit required: ",
|
|
10124
|
+
chunkWMEC5JWN_js.parsePrice(product.deposit_amount),
|
|
10125
|
+
"%"
|
|
10126
|
+
] })
|
|
10127
|
+
}
|
|
10128
|
+
),
|
|
10129
|
+
product.allergies && product.allergies.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
10130
|
+
"div",
|
|
10131
|
+
{
|
|
10132
|
+
"data-cimplify-customizer-allergens": true,
|
|
10133
|
+
className: cn("flex flex-wrap gap-1.5", classNames?.allergens),
|
|
10134
|
+
children: product.allergies.map((allergen) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
10135
|
+
"span",
|
|
10136
|
+
{
|
|
10137
|
+
"data-cimplify-allergen-tag": true,
|
|
10138
|
+
className: "inline-block text-xs px-2 py-0.5 rounded-full bg-muted text-muted-foreground",
|
|
10139
|
+
children: allergen
|
|
10140
|
+
},
|
|
10141
|
+
allergen
|
|
10142
|
+
))
|
|
10143
|
+
}
|
|
10144
|
+
),
|
|
10145
|
+
isService && product.duration_minutes != null && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
10146
|
+
"div",
|
|
10147
|
+
{
|
|
10148
|
+
"data-cimplify-customizer-duration": true,
|
|
10149
|
+
className: cn("text-sm text-muted-foreground", classNames?.duration),
|
|
10150
|
+
children: [
|
|
10151
|
+
"Duration: ",
|
|
10152
|
+
formatDuration2(product.duration_minutes, product.duration_unit)
|
|
10153
|
+
]
|
|
10154
|
+
}
|
|
10155
|
+
),
|
|
9968
10156
|
showSpecialInstructions && !isDigital && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-customizer-special-instructions": true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9969
10157
|
"textarea",
|
|
9970
10158
|
{
|
|
@@ -9997,13 +10185,17 @@ function ProductCustomizer({
|
|
|
9997
10185
|
"data-cimplify-customizer-actions": true,
|
|
9998
10186
|
className: cn("pt-4 border-t border-border", classNames?.actions),
|
|
9999
10187
|
children: [
|
|
10000
|
-
|
|
10188
|
+
validationMessage && /* @__PURE__ */ jsxRuntime.jsx(
|
|
10001
10189
|
"p",
|
|
10002
10190
|
{
|
|
10003
|
-
id:
|
|
10191
|
+
id: CUSTOMIZER_VALIDATION_ID,
|
|
10004
10192
|
"data-cimplify-customizer-validation": true,
|
|
10005
|
-
className: cn(
|
|
10006
|
-
|
|
10193
|
+
className: cn(
|
|
10194
|
+
"text-sm mb-3",
|
|
10195
|
+
quoteError ? "text-destructive" : "text-muted-foreground",
|
|
10196
|
+
classNames?.validation
|
|
10197
|
+
),
|
|
10198
|
+
children: validationMessage
|
|
10007
10199
|
}
|
|
10008
10200
|
),
|
|
10009
10201
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
|
|
@@ -10016,28 +10208,54 @@ function ProductCustomizer({
|
|
|
10016
10208
|
min: product.min_order_quantity ?? 1
|
|
10017
10209
|
}
|
|
10018
10210
|
),
|
|
10019
|
-
product.min_order_quantity && product.min_order_quantity > 1 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
10020
|
-
"
|
|
10021
|
-
|
|
10022
|
-
|
|
10023
|
-
|
|
10024
|
-
|
|
10025
|
-
|
|
10026
|
-
|
|
10211
|
+
product.min_order_quantity && product.min_order_quantity > 1 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
10212
|
+
"span",
|
|
10213
|
+
{
|
|
10214
|
+
"data-cimplify-customizer-min-hint": true,
|
|
10215
|
+
className: "text-xs text-muted-foreground text-center",
|
|
10216
|
+
children: [
|
|
10217
|
+
"Min. ",
|
|
10218
|
+
product.min_order_quantity
|
|
10219
|
+
]
|
|
10220
|
+
}
|
|
10221
|
+
)
|
|
10027
10222
|
] }),
|
|
10223
|
+
product.quantity_pricing && product.quantity_pricing.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
10224
|
+
"div",
|
|
10225
|
+
{
|
|
10226
|
+
"data-cimplify-customizer-unit-price": true,
|
|
10227
|
+
className: "text-sm text-muted-foreground text-right shrink-0",
|
|
10228
|
+
children: [
|
|
10229
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
10230
|
+
Price,
|
|
10231
|
+
{
|
|
10232
|
+
amount: chunkWMEC5JWN_js.getUnitPriceAtQuantity(
|
|
10233
|
+
product.quantity_pricing,
|
|
10234
|
+
quantity,
|
|
10235
|
+
chunkWMEC5JWN_js.parsePrice(product.default_price)
|
|
10236
|
+
),
|
|
10237
|
+
currency,
|
|
10238
|
+
className: "font-medium text-foreground"
|
|
10239
|
+
}
|
|
10240
|
+
),
|
|
10241
|
+
" ",
|
|
10242
|
+
"ea."
|
|
10243
|
+
]
|
|
10244
|
+
}
|
|
10245
|
+
),
|
|
10028
10246
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
10029
10247
|
button.Button,
|
|
10030
10248
|
{
|
|
10031
10249
|
onClick: handleAddToCart,
|
|
10032
|
-
disabled: isAdded || isSubmitting || !
|
|
10033
|
-
"aria-describedby":
|
|
10250
|
+
disabled: isAdded || isSubmitting || !quoteIsReady,
|
|
10251
|
+
"aria-describedby": validationMessage ? CUSTOMIZER_VALIDATION_ID : void 0,
|
|
10034
10252
|
"data-cimplify-customizer-submit": true,
|
|
10035
10253
|
className: cn(
|
|
10036
10254
|
"flex-1 h-14 text-base bg-primary text-primary-foreground font-medium hover:bg-primary/90 transition-colors disabled:opacity-50 disabled:cursor-not-allowed rounded-full",
|
|
10037
10255
|
isAdded && classNames?.submitButtonAdded,
|
|
10038
10256
|
classNames?.submitButton
|
|
10039
10257
|
),
|
|
10040
|
-
children: isAdded ? "Added" : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
10258
|
+
children: isAdded ? "Added" : !quoteEnabled ? submitLabel ?? "Add to Cart" : !quoteIsReady ? quoteError ? QUOTE_UNAVAILABLE_MESSAGE : QUOTE_LOADING_MESSAGE : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
10041
10259
|
submitLabel ?? "Add to Cart",
|
|
10042
10260
|
" \xB7",
|
|
10043
10261
|
" ",
|
|
@@ -10471,17 +10689,20 @@ function CartLineItemRow({
|
|
|
10471
10689
|
item,
|
|
10472
10690
|
onRemove,
|
|
10473
10691
|
onQuantityChange,
|
|
10692
|
+
currency,
|
|
10474
10693
|
classNames
|
|
10475
10694
|
}) {
|
|
10476
|
-
const { unitPrice } = useProductPrice({
|
|
10695
|
+
const { unitPrice: locallyResolvedUnitPrice } = useProductPrice({
|
|
10477
10696
|
product: item.product,
|
|
10478
10697
|
variant: item.variant,
|
|
10479
10698
|
addOnOptions: item.addOnOptions
|
|
10480
10699
|
});
|
|
10700
|
+
const pinnedUnitPrice = item._quotedUnitPrice;
|
|
10701
|
+
const unitPrice = pinnedUnitPrice === void 0 ? locallyResolvedUnitPrice : chunkWMEC5JWN_js.parsePrice(pinnedUnitPrice);
|
|
10481
10702
|
const hasComposite = item.compositeSelections && item.compositeSelections.length > 0;
|
|
10482
10703
|
const hasBundle = item.bundleSelections && item.bundleSelections.length > 0;
|
|
10483
10704
|
const isOptimistic2 = item.isOptimistic === true;
|
|
10484
|
-
const lineTotal =
|
|
10705
|
+
const lineTotal = chunkWMEC5JWN_js.parsePrice(unitPrice) * item.quantity;
|
|
10485
10706
|
const imageUrl = item.product.image_url;
|
|
10486
10707
|
const variantLabel2 = item.variant ? chunkQPRI2NII_js.getVariantDisplayName(item.variant, item.product.name) : null;
|
|
10487
10708
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -10500,15 +10721,25 @@ function CartLineItemRow({
|
|
|
10500
10721
|
{
|
|
10501
10722
|
"data-cimplify-cart-item-image": true,
|
|
10502
10723
|
className: "relative w-20 h-20 shrink-0 rounded-md overflow-hidden bg-muted",
|
|
10503
|
-
children: imageUrl ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
10504
|
-
"
|
|
10724
|
+
children: imageUrl ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: imageUrl, alt: "", className: "w-full h-full object-cover", loading: "lazy" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full grid place-items-center text-muted-foreground/40", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10725
|
+
"svg",
|
|
10505
10726
|
{
|
|
10506
|
-
|
|
10507
|
-
|
|
10508
|
-
|
|
10509
|
-
|
|
10727
|
+
className: "w-6 h-6",
|
|
10728
|
+
fill: "none",
|
|
10729
|
+
stroke: "currentColor",
|
|
10730
|
+
strokeWidth: "1.5",
|
|
10731
|
+
viewBox: "0 0 24 24",
|
|
10732
|
+
"aria-hidden": true,
|
|
10733
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10734
|
+
"path",
|
|
10735
|
+
{
|
|
10736
|
+
strokeLinecap: "round",
|
|
10737
|
+
strokeLinejoin: "round",
|
|
10738
|
+
d: "M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 001.5-1.5V6a1.5 1.5 0 00-1.5-1.5H3.75A1.5 1.5 0 002.25 6v12a1.5 1.5 0 001.5 1.5zm10.5-11.25h.008v.008h-.008V8.25zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z"
|
|
10739
|
+
}
|
|
10740
|
+
)
|
|
10510
10741
|
}
|
|
10511
|
-
)
|
|
10742
|
+
) })
|
|
10512
10743
|
}
|
|
10513
10744
|
),
|
|
10514
10745
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-item-info": true, className: "flex-1 min-w-0 flex flex-col", children: [
|
|
@@ -10532,7 +10763,18 @@ function CartLineItemRow({
|
|
|
10532
10763
|
classNames?.removeButton
|
|
10533
10764
|
),
|
|
10534
10765
|
"aria-label": `Remove ${item.product.name}`,
|
|
10535
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10766
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10767
|
+
"svg",
|
|
10768
|
+
{
|
|
10769
|
+
className: "w-3.5 h-3.5",
|
|
10770
|
+
fill: "none",
|
|
10771
|
+
stroke: "currentColor",
|
|
10772
|
+
strokeWidth: "2",
|
|
10773
|
+
viewBox: "0 0 24 24",
|
|
10774
|
+
"aria-hidden": true,
|
|
10775
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" })
|
|
10776
|
+
}
|
|
10777
|
+
)
|
|
10536
10778
|
}
|
|
10537
10779
|
)
|
|
10538
10780
|
] }),
|
|
@@ -10578,43 +10820,124 @@ function CartLineItemRow({
|
|
|
10578
10820
|
]
|
|
10579
10821
|
}
|
|
10580
10822
|
),
|
|
10581
|
-
item.customerInputs && item.customerInputs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
10582
|
-
|
|
10583
|
-
|
|
10584
|
-
":
|
|
10585
|
-
|
|
10586
|
-
|
|
10587
|
-
|
|
10588
|
-
|
|
10589
|
-
|
|
10590
|
-
|
|
10591
|
-
|
|
10592
|
-
|
|
10593
|
-
|
|
10594
|
-
|
|
10595
|
-
|
|
10596
|
-
|
|
10597
|
-
|
|
10598
|
-
|
|
10599
|
-
|
|
10600
|
-
|
|
10601
|
-
|
|
10823
|
+
item.customerInputs && item.customerInputs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
10824
|
+
"dl",
|
|
10825
|
+
{
|
|
10826
|
+
"data-cimplify-cart-customer-inputs": true,
|
|
10827
|
+
className: cn("mt-1.5 text-xs space-y-0.5", classNames?.customerInputs),
|
|
10828
|
+
children: item.customerInputs.map((input) => /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-input": true, className: "flex gap-1.5", children: [
|
|
10829
|
+
/* @__PURE__ */ jsxRuntime.jsxs("dt", { "data-cimplify-cart-input-label": true, className: "text-muted-foreground", children: [
|
|
10830
|
+
input.field_name,
|
|
10831
|
+
":"
|
|
10832
|
+
] }),
|
|
10833
|
+
/* @__PURE__ */ jsxRuntime.jsx("dd", { "data-cimplify-cart-input-value": true, className: "text-foreground m-0 truncate", children: input.field_type === chunkQPRI2NII_js.INPUT_FIELD_TYPE.File || input.field_type === chunkQPRI2NII_js.INPUT_FIELD_TYPE.Image ? String(input.value).split("/").pop() || "Uploaded file" : String(input.value) })
|
|
10834
|
+
] }, input.field_id))
|
|
10835
|
+
}
|
|
10836
|
+
),
|
|
10837
|
+
(item.lineType === "service" || item.product.type === "service") && item.scheduledStart && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
10838
|
+
"div",
|
|
10839
|
+
{
|
|
10840
|
+
"data-cimplify-cart-service-info": true,
|
|
10841
|
+
className: cn(
|
|
10842
|
+
"mt-1.5 flex items-center gap-1.5 text-xs text-muted-foreground",
|
|
10843
|
+
classNames?.serviceInfo
|
|
10844
|
+
),
|
|
10845
|
+
children: [
|
|
10846
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
10847
|
+
"svg",
|
|
10848
|
+
{
|
|
10849
|
+
className: "w-3.5 h-3.5 shrink-0",
|
|
10850
|
+
fill: "none",
|
|
10851
|
+
stroke: "currentColor",
|
|
10852
|
+
strokeWidth: "2",
|
|
10853
|
+
viewBox: "0 0 24 24",
|
|
10854
|
+
"aria-hidden": true,
|
|
10855
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10856
|
+
"path",
|
|
10857
|
+
{
|
|
10858
|
+
strokeLinecap: "round",
|
|
10859
|
+
strokeLinejoin: "round",
|
|
10860
|
+
d: "M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
|
|
10861
|
+
}
|
|
10862
|
+
)
|
|
10863
|
+
}
|
|
10864
|
+
),
|
|
10865
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
10866
|
+
new Date(item.scheduledStart).toLocaleDateString(void 0, {
|
|
10867
|
+
month: "short",
|
|
10868
|
+
day: "numeric"
|
|
10869
|
+
}),
|
|
10870
|
+
" ",
|
|
10871
|
+
"at",
|
|
10872
|
+
" ",
|
|
10873
|
+
new Date(item.scheduledStart).toLocaleTimeString([], {
|
|
10874
|
+
hour: "2-digit",
|
|
10875
|
+
minute: "2-digit"
|
|
10876
|
+
})
|
|
10877
|
+
] }),
|
|
10878
|
+
item.serviceStatus && /* @__PURE__ */ jsxRuntime.jsx(
|
|
10879
|
+
"span",
|
|
10880
|
+
{
|
|
10881
|
+
"data-status": item.serviceStatus,
|
|
10882
|
+
className: "ml-auto px-1.5 py-0.5 rounded-full bg-muted text-[10px] uppercase tracking-wider",
|
|
10883
|
+
children: item.serviceStatus
|
|
10884
|
+
}
|
|
10885
|
+
)
|
|
10886
|
+
]
|
|
10887
|
+
}
|
|
10888
|
+
),
|
|
10889
|
+
(item.lineType === "digital" || item.product.type === "digital") && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
10890
|
+
"div",
|
|
10891
|
+
{
|
|
10892
|
+
"data-cimplify-cart-digital-info": true,
|
|
10893
|
+
className: cn(
|
|
10894
|
+
"mt-1.5 flex items-center gap-1 text-xs text-muted-foreground",
|
|
10895
|
+
classNames?.digitalInfo
|
|
10896
|
+
),
|
|
10897
|
+
children: [
|
|
10898
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
10899
|
+
"svg",
|
|
10900
|
+
{
|
|
10901
|
+
className: "w-3.5 h-3.5 shrink-0",
|
|
10902
|
+
fill: "none",
|
|
10903
|
+
stroke: "currentColor",
|
|
10904
|
+
strokeWidth: "2",
|
|
10905
|
+
viewBox: "0 0 24 24",
|
|
10906
|
+
"aria-hidden": true,
|
|
10907
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M13 10V3L4 14h7v7l9-11h-7z" })
|
|
10908
|
+
}
|
|
10909
|
+
),
|
|
10910
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Instant digital delivery" })
|
|
10911
|
+
]
|
|
10912
|
+
}
|
|
10913
|
+
),
|
|
10602
10914
|
(item.bundleResolved || item.compositeResolved) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
10603
10915
|
"ul",
|
|
10604
10916
|
{
|
|
10605
10917
|
"data-cimplify-cart-composite-breakdown": item.compositeResolved ? "" : void 0,
|
|
10606
10918
|
"data-cimplify-cart-bundle-breakdown": item.bundleResolved ? "" : void 0,
|
|
10607
|
-
className: cn(
|
|
10919
|
+
className: cn(
|
|
10920
|
+
"mt-1.5 pl-3 border-l border-border space-y-0.5 text-xs text-muted-foreground",
|
|
10921
|
+
item.compositeResolved ? classNames?.compositeBreakdown : classNames?.bundleBreakdown
|
|
10922
|
+
),
|
|
10608
10923
|
children: (item.bundleResolved?.selections ?? item.compositeResolved?.selections ?? []).map((sel) => {
|
|
10609
10924
|
const name = sel.product_name ?? sel.component_name ?? "";
|
|
10610
10925
|
const compId = sel.component_id ?? `${name}-${sel.quantity}`;
|
|
10611
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
10612
|
-
|
|
10613
|
-
|
|
10614
|
-
"
|
|
10615
|
-
|
|
10616
|
-
|
|
10617
|
-
|
|
10926
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
10927
|
+
"li",
|
|
10928
|
+
{
|
|
10929
|
+
"data-product-type": sel.product_type,
|
|
10930
|
+
className: "flex items-baseline gap-1.5 m-0",
|
|
10931
|
+
children: [
|
|
10932
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium text-foreground/80", children: [
|
|
10933
|
+
sel.quantity,
|
|
10934
|
+
"\\u00D7"
|
|
10935
|
+
] }),
|
|
10936
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: name })
|
|
10937
|
+
]
|
|
10938
|
+
},
|
|
10939
|
+
compId
|
|
10940
|
+
);
|
|
10618
10941
|
})
|
|
10619
10942
|
}
|
|
10620
10943
|
),
|
|
@@ -10623,6 +10946,7 @@ function CartLineItemRow({
|
|
|
10623
10946
|
Price,
|
|
10624
10947
|
{
|
|
10625
10948
|
amount: lineTotal,
|
|
10949
|
+
currency,
|
|
10626
10950
|
className: cn("text-sm font-semibold tabular-nums", classNames?.itemPrice)
|
|
10627
10951
|
}
|
|
10628
10952
|
),
|
|
@@ -10660,9 +10984,11 @@ function CartSummary({
|
|
|
10660
10984
|
isEmpty,
|
|
10661
10985
|
isOptimistic: isOptimistic2,
|
|
10662
10986
|
pendingOpCount,
|
|
10987
|
+
currency,
|
|
10663
10988
|
removeItem,
|
|
10664
10989
|
updateQuantity
|
|
10665
10990
|
} = useCart();
|
|
10991
|
+
const displayCurrency = serverCart?.currency ?? chunkNIOUSKQQ_js.currencyCode(currency);
|
|
10666
10992
|
const deliveryFee = serverCart?.delivery_fee;
|
|
10667
10993
|
const serviceCharge = serverCart?.service_charge;
|
|
10668
10994
|
const totalDiscounts = serverCart?.total_discounts;
|
|
@@ -10694,6 +11020,7 @@ function CartSummary({
|
|
|
10694
11020
|
item,
|
|
10695
11021
|
onRemove: handleRemove,
|
|
10696
11022
|
onQuantityChange: handleQuantityChange,
|
|
11023
|
+
currency: displayCurrency,
|
|
10697
11024
|
classNames
|
|
10698
11025
|
},
|
|
10699
11026
|
item.id
|
|
@@ -10702,38 +11029,115 @@ function CartSummary({
|
|
|
10702
11029
|
"div",
|
|
10703
11030
|
{
|
|
10704
11031
|
"data-cimplify-cart-totals": true,
|
|
10705
|
-
className: cn(
|
|
11032
|
+
className: cn(
|
|
11033
|
+
"mt-6 pt-4 border-t border-border space-y-2 text-sm",
|
|
11034
|
+
classNames?.totals
|
|
11035
|
+
),
|
|
10706
11036
|
children: [
|
|
10707
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
10708
|
-
|
|
10709
|
-
|
|
10710
|
-
|
|
10711
|
-
" ",
|
|
10712
|
-
|
|
10713
|
-
|
|
10714
|
-
|
|
10715
|
-
|
|
10716
|
-
|
|
10717
|
-
|
|
10718
|
-
|
|
10719
|
-
|
|
10720
|
-
|
|
10721
|
-
|
|
10722
|
-
|
|
10723
|
-
|
|
10724
|
-
|
|
10725
|
-
|
|
10726
|
-
|
|
10727
|
-
|
|
10728
|
-
|
|
10729
|
-
|
|
10730
|
-
|
|
10731
|
-
|
|
10732
|
-
|
|
10733
|
-
|
|
10734
|
-
|
|
10735
|
-
|
|
10736
|
-
|
|
11037
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
11038
|
+
"div",
|
|
11039
|
+
{
|
|
11040
|
+
"data-cimplify-cart-subtotal": true,
|
|
11041
|
+
className: cn("flex items-baseline justify-between", classNames?.subtotal),
|
|
11042
|
+
children: [
|
|
11043
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground", children: [
|
|
11044
|
+
"Subtotal (",
|
|
11045
|
+
itemCount,
|
|
11046
|
+
" ",
|
|
11047
|
+
itemCount === 1 ? "item" : "items",
|
|
11048
|
+
")"
|
|
11049
|
+
] }),
|
|
11050
|
+
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: subtotal, currency: displayCurrency, className: "tabular-nums" })
|
|
11051
|
+
]
|
|
11052
|
+
}
|
|
11053
|
+
),
|
|
11054
|
+
totalDiscounts != null && chunkWMEC5JWN_js.parsePrice(totalDiscounts) > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11055
|
+
"div",
|
|
11056
|
+
{
|
|
11057
|
+
"data-cimplify-cart-discount": true,
|
|
11058
|
+
className: cn("flex items-baseline justify-between", classNames?.discount),
|
|
11059
|
+
children: [
|
|
11060
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Discount" }),
|
|
11061
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11062
|
+
Price,
|
|
11063
|
+
{
|
|
11064
|
+
amount: totalDiscounts,
|
|
11065
|
+
currency: displayCurrency,
|
|
11066
|
+
prefix: "-",
|
|
11067
|
+
className: "tabular-nums text-primary"
|
|
11068
|
+
}
|
|
11069
|
+
)
|
|
11070
|
+
]
|
|
11071
|
+
}
|
|
11072
|
+
),
|
|
11073
|
+
deliveryFee != null && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11074
|
+
"div",
|
|
11075
|
+
{
|
|
11076
|
+
"data-cimplify-cart-delivery-fee": true,
|
|
11077
|
+
className: cn("flex items-baseline justify-between", classNames?.deliveryFee),
|
|
11078
|
+
children: [
|
|
11079
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Delivery" }),
|
|
11080
|
+
chunkWMEC5JWN_js.parsePrice(deliveryFee) > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
11081
|
+
Price,
|
|
11082
|
+
{
|
|
11083
|
+
amount: deliveryFee,
|
|
11084
|
+
currency: displayCurrency,
|
|
11085
|
+
className: "tabular-nums"
|
|
11086
|
+
}
|
|
11087
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-primary", children: "Free" })
|
|
11088
|
+
]
|
|
11089
|
+
}
|
|
11090
|
+
),
|
|
11091
|
+
serviceCharge != null && chunkWMEC5JWN_js.parsePrice(serviceCharge) > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11092
|
+
"div",
|
|
11093
|
+
{
|
|
11094
|
+
"data-cimplify-cart-service-charge": true,
|
|
11095
|
+
className: cn("flex items-baseline justify-between", classNames?.serviceCharge),
|
|
11096
|
+
children: [
|
|
11097
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Service charge" }),
|
|
11098
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11099
|
+
Price,
|
|
11100
|
+
{
|
|
11101
|
+
amount: serviceCharge,
|
|
11102
|
+
currency: displayCurrency,
|
|
11103
|
+
className: "tabular-nums"
|
|
11104
|
+
}
|
|
11105
|
+
)
|
|
11106
|
+
]
|
|
11107
|
+
}
|
|
11108
|
+
),
|
|
11109
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
11110
|
+
"div",
|
|
11111
|
+
{
|
|
11112
|
+
"data-cimplify-cart-tax": true,
|
|
11113
|
+
className: cn("flex items-baseline justify-between", classNames?.tax),
|
|
11114
|
+
children: [
|
|
11115
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Tax" }),
|
|
11116
|
+
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: tax, currency: displayCurrency, className: "tabular-nums" })
|
|
11117
|
+
]
|
|
11118
|
+
}
|
|
11119
|
+
),
|
|
11120
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
11121
|
+
"div",
|
|
11122
|
+
{
|
|
11123
|
+
"data-cimplify-cart-total": true,
|
|
11124
|
+
className: cn(
|
|
11125
|
+
"flex items-baseline justify-between pt-3 mt-1 border-t border-border",
|
|
11126
|
+
classNames?.total
|
|
11127
|
+
),
|
|
11128
|
+
children: [
|
|
11129
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold", children: "Total" }),
|
|
11130
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11131
|
+
Price,
|
|
11132
|
+
{
|
|
11133
|
+
amount: total,
|
|
11134
|
+
currency: displayCurrency,
|
|
11135
|
+
className: "text-base font-bold tabular-nums"
|
|
11136
|
+
}
|
|
11137
|
+
)
|
|
11138
|
+
]
|
|
11139
|
+
}
|
|
11140
|
+
)
|
|
10737
11141
|
]
|
|
10738
11142
|
}
|
|
10739
11143
|
),
|
|
@@ -10812,18 +11216,20 @@ function SaleBadge({
|
|
|
10812
11216
|
className,
|
|
10813
11217
|
classNames
|
|
10814
11218
|
}) {
|
|
10815
|
-
const onSale =
|
|
11219
|
+
const onSale = chunkWMEC5JWN_js.isOnSale(product);
|
|
10816
11220
|
const hasDeal = dealInfo !== void 0;
|
|
10817
11221
|
if (!hasDeal && !onSale && !label) {
|
|
10818
11222
|
return null;
|
|
10819
11223
|
}
|
|
10820
11224
|
let percentage = null;
|
|
10821
|
-
if (
|
|
10822
|
-
percentage =
|
|
11225
|
+
if (product.sale) {
|
|
11226
|
+
percentage = chunkWMEC5JWN_js.parsePrice(product.sale.percent_off);
|
|
11227
|
+
} else if (hasDeal && dealInfo.benefit_type === "percentage") {
|
|
11228
|
+
percentage = chunkWMEC5JWN_js.parsePrice(dealInfo.value);
|
|
10823
11229
|
} else if (onSale) {
|
|
10824
|
-
percentage =
|
|
11230
|
+
percentage = chunkWMEC5JWN_js.getDiscountPercentage(product);
|
|
10825
11231
|
}
|
|
10826
|
-
const badgeText = label ?? dealInfo?.label ?? (percentage != null && percentage > 0 ? `${percentage}% off` : null);
|
|
11232
|
+
const badgeText = label ?? product.sale?.badge_text ?? dealInfo?.label ?? (percentage != null && percentage > 0 ? `${percentage}% off` : null);
|
|
10827
11233
|
if (!badgeText) {
|
|
10828
11234
|
return null;
|
|
10829
11235
|
}
|
|
@@ -10840,7 +11246,7 @@ function SaleBadge({
|
|
|
10840
11246
|
"%"
|
|
10841
11247
|
] }),
|
|
10842
11248
|
/* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-sale-label": true, className: classNames?.label, children: badgeText }),
|
|
10843
|
-
showOriginalPrice && onSale && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-sale-original-price": true, className: classNames?.originalPrice, children: /* @__PURE__ */ jsxRuntime.jsx(Price, { amount:
|
|
11249
|
+
showOriginalPrice && onSale && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-sale-original-price": true, className: classNames?.originalPrice, children: /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: chunkWMEC5JWN_js.getBasePrice(product), currency: chunkWMEC5JWN_js.getProductCurrency(product) }) })
|
|
10844
11250
|
]
|
|
10845
11251
|
}
|
|
10846
11252
|
);
|
|
@@ -10858,7 +11264,7 @@ function SalePrice({
|
|
|
10858
11264
|
if (!sale) {
|
|
10859
11265
|
return /* @__PURE__ */ jsxRuntime.jsx(Price, { amount, currency, className });
|
|
10860
11266
|
}
|
|
10861
|
-
const off = Math.round(
|
|
11267
|
+
const off = Math.round(chunkWMEC5JWN_js.parsePrice(sale.percent_off));
|
|
10862
11268
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
10863
11269
|
"span",
|
|
10864
11270
|
{
|
|
@@ -11234,7 +11640,7 @@ function ProductSheet({
|
|
|
11234
11640
|
Price,
|
|
11235
11641
|
{
|
|
11236
11642
|
amount: fullProduct.default_price,
|
|
11237
|
-
currency:
|
|
11643
|
+
currency: chunkWMEC5JWN_js.getProductCurrency(fullProduct),
|
|
11238
11644
|
className: classNames?.price
|
|
11239
11645
|
}
|
|
11240
11646
|
)
|
|
@@ -11420,10 +11826,10 @@ function SoldOutOverlay() {
|
|
|
11420
11826
|
function SaleBadge2({ product }) {
|
|
11421
11827
|
let label = null;
|
|
11422
11828
|
if (product.sale) {
|
|
11423
|
-
const off = Math.round(
|
|
11829
|
+
const off = Math.round(chunkWMEC5JWN_js.parsePrice(product.sale.percent_off));
|
|
11424
11830
|
label = product.sale.badge_text ?? (off > 0 ? `-${off}%` : null);
|
|
11425
|
-
} else if (
|
|
11426
|
-
const pct =
|
|
11831
|
+
} else if (chunkWMEC5JWN_js.isOnSale(product)) {
|
|
11832
|
+
const pct = chunkWMEC5JWN_js.getDiscountPercentage(product);
|
|
11427
11833
|
label = pct && pct > 0 ? `-${pct}%` : null;
|
|
11428
11834
|
}
|
|
11429
11835
|
if (!label) return null;
|
|
@@ -11464,7 +11870,7 @@ function FoodProductCard({
|
|
|
11464
11870
|
className
|
|
11465
11871
|
}) {
|
|
11466
11872
|
const image = product.image_url || product.images?.[0] || "";
|
|
11467
|
-
const currency =
|
|
11873
|
+
const currency = chunkWMEC5JWN_js.getProductCurrency(product);
|
|
11468
11874
|
const tags = product.tags || [];
|
|
11469
11875
|
const isSignature = product.metadata?.is_signature === true;
|
|
11470
11876
|
const isNew = product.metadata?.is_new === true;
|
|
@@ -11520,9 +11926,9 @@ function RetailProductCard({
|
|
|
11520
11926
|
className
|
|
11521
11927
|
}) {
|
|
11522
11928
|
const image = product.image_url || product.images?.[0] || "";
|
|
11523
|
-
const currency =
|
|
11929
|
+
const currency = chunkWMEC5JWN_js.getProductCurrency(product);
|
|
11524
11930
|
const outOfStock = product.inventory_status?.in_stock === false;
|
|
11525
|
-
const onSale =
|
|
11931
|
+
const onSale = chunkWMEC5JWN_js.isOnSale(product);
|
|
11526
11932
|
const swatches = getColorSwatches(product);
|
|
11527
11933
|
return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, disabled: outOfStock, className, children: [
|
|
11528
11934
|
outOfStock && /* @__PURE__ */ jsxRuntime.jsx(SoldOutOverlay, {}),
|
|
@@ -11543,7 +11949,7 @@ function RetailProductCard({
|
|
|
11543
11949
|
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.sale.original, currency, className: "text-xs text-muted-foreground line-through" })
|
|
11544
11950
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
11545
11951
|
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price, currency, className: "text-sm font-bold" }),
|
|
11546
|
-
onSale && /* @__PURE__ */ jsxRuntime.jsx(Price, { amount:
|
|
11952
|
+
onSale && /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: chunkWMEC5JWN_js.getBasePrice(product), currency, className: "text-xs text-muted-foreground line-through" })
|
|
11547
11953
|
] }) }),
|
|
11548
11954
|
swatches.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-1.5 mt-2.5", children: swatches.map((name) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
11549
11955
|
"span",
|
|
@@ -11558,10 +11964,10 @@ function RetailProductCard({
|
|
|
11558
11964
|
] });
|
|
11559
11965
|
}
|
|
11560
11966
|
function PriceRange({ product, currency, className }) {
|
|
11561
|
-
const resolvedCurrency = currency ??
|
|
11562
|
-
const range =
|
|
11967
|
+
const resolvedCurrency = currency ?? chunkWMEC5JWN_js.getProductCurrency(product);
|
|
11968
|
+
const range = chunkWMEC5JWN_js.getPriceRange(product);
|
|
11563
11969
|
if (!range) return null;
|
|
11564
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-price-range": true, className, children:
|
|
11970
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-price-range": true, className, children: chunkWMEC5JWN_js.formatPriceRange(range.min, range.max, resolvedCurrency) });
|
|
11565
11971
|
}
|
|
11566
11972
|
function WholesaleProductCard({
|
|
11567
11973
|
product,
|
|
@@ -11571,7 +11977,7 @@ function WholesaleProductCard({
|
|
|
11571
11977
|
className
|
|
11572
11978
|
}) {
|
|
11573
11979
|
const image = product.image_url || product.images?.[0] || "";
|
|
11574
|
-
const currency =
|
|
11980
|
+
const currency = chunkWMEC5JWN_js.getProductCurrency(product);
|
|
11575
11981
|
const hasTiers = product.quantity_pricing && product.quantity_pricing.length > 1;
|
|
11576
11982
|
const status = product.inventory_status;
|
|
11577
11983
|
return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, className, children: [
|
|
@@ -11619,7 +12025,7 @@ function DigitalProductCard({
|
|
|
11619
12025
|
className
|
|
11620
12026
|
}) {
|
|
11621
12027
|
const image = product.image_url || product.images?.[0] || "";
|
|
11622
|
-
const currency =
|
|
12028
|
+
const currency = chunkWMEC5JWN_js.getProductCurrency(product);
|
|
11623
12029
|
const typeBadge = product.digital_type ? TYPE_BADGES[product.digital_type] : null;
|
|
11624
12030
|
const isTicket = product.digital_type === "ticket";
|
|
11625
12031
|
return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, className, children: [
|
|
@@ -11650,11 +12056,11 @@ function BundleProductCard({
|
|
|
11650
12056
|
className
|
|
11651
12057
|
}) {
|
|
11652
12058
|
const image = product.image_url || product.images?.[0] || "";
|
|
11653
|
-
const currency =
|
|
12059
|
+
const currency = chunkWMEC5JWN_js.getProductCurrency(product);
|
|
11654
12060
|
const components = product.components || [];
|
|
11655
12061
|
const componentCount = components.length;
|
|
11656
|
-
const onSale =
|
|
11657
|
-
const discount =
|
|
12062
|
+
const onSale = chunkWMEC5JWN_js.isOnSale(product);
|
|
12063
|
+
const discount = chunkWMEC5JWN_js.getDiscountPercentage(product);
|
|
11658
12064
|
const hasVariantChoice = components.some((c) => c.allow_variant_choice);
|
|
11659
12065
|
return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, className, children: [
|
|
11660
12066
|
/* @__PURE__ */ jsxRuntime.jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "square", renderImage, children: [
|
|
@@ -11681,7 +12087,7 @@ function BundleProductCard({
|
|
|
11681
12087
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-2.5", children: [
|
|
11682
12088
|
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price, currency, className: "text-sm font-bold" }),
|
|
11683
12089
|
onSale && product.bundle_price && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
11684
|
-
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount:
|
|
12090
|
+
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: chunkWMEC5JWN_js.getBasePrice(product), currency, className: "text-xs text-muted-foreground line-through" }),
|
|
11685
12091
|
discount != null && discount > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] font-semibold text-emerald-600", children: [
|
|
11686
12092
|
"Save ",
|
|
11687
12093
|
discount,
|
|
@@ -11701,7 +12107,7 @@ function CompositeProductCard({
|
|
|
11701
12107
|
className
|
|
11702
12108
|
}) {
|
|
11703
12109
|
const image = product.image_url || product.images?.[0] || "";
|
|
11704
|
-
const currency =
|
|
12110
|
+
const currency = chunkWMEC5JWN_js.getProductCurrency(product);
|
|
11705
12111
|
const groups = product.groups || [];
|
|
11706
12112
|
const groupCount = groups.length;
|
|
11707
12113
|
groups.reduce((sum, g) => sum + g.components.length, 0);
|
|
@@ -11753,7 +12159,7 @@ function StandardServiceCard({
|
|
|
11753
12159
|
className
|
|
11754
12160
|
}) {
|
|
11755
12161
|
const image = product.image_url || product.images?.[0] || "";
|
|
11756
|
-
const currency =
|
|
12162
|
+
const currency = chunkWMEC5JWN_js.getProductCurrency(product);
|
|
11757
12163
|
const hasDeposit = product.deposit_type && product.deposit_type !== "none" && product.deposit_amount;
|
|
11758
12164
|
return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, className, children: [
|
|
11759
12165
|
/* @__PURE__ */ jsxRuntime.jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "16/9", renderImage, children: [
|
|
@@ -11808,7 +12214,7 @@ function CompactServiceCard({
|
|
|
11808
12214
|
className
|
|
11809
12215
|
}) {
|
|
11810
12216
|
const image = product.image_url || product.images?.[0] || "";
|
|
11811
|
-
const currency =
|
|
12217
|
+
const currency = chunkWMEC5JWN_js.getProductCurrency(product);
|
|
11812
12218
|
const hasDeposit = product.deposit_type && product.deposit_type !== "none" && product.deposit_amount;
|
|
11813
12219
|
const hasBillingPlans = product.billing_plans && product.billing_plans.length > 0;
|
|
11814
12220
|
const href = `/products/${product.slug}`;
|
|
@@ -11857,7 +12263,7 @@ function ScheduleServiceCard({
|
|
|
11857
12263
|
className
|
|
11858
12264
|
}) {
|
|
11859
12265
|
const image = product.image_url || product.images?.[0] || "";
|
|
11860
|
-
const currency =
|
|
12266
|
+
const currency = chunkWMEC5JWN_js.getProductCurrency(product);
|
|
11861
12267
|
const href = `/products/${product.slug}`;
|
|
11862
12268
|
const durationLabel = product.duration_minutes != null ? formatDuration2(product.duration_minutes, product.duration_unit) : null;
|
|
11863
12269
|
const displaySlots = (slots || []).slice(0, 3);
|
|
@@ -11929,7 +12335,7 @@ function RentalServiceCard({
|
|
|
11929
12335
|
className
|
|
11930
12336
|
}) {
|
|
11931
12337
|
const image = product.image_url || product.images?.[0] || "";
|
|
11932
|
-
const currency =
|
|
12338
|
+
const currency = chunkWMEC5JWN_js.getProductCurrency(product);
|
|
11933
12339
|
const hasDeposit = product.deposit_type && product.deposit_type !== "none" && product.deposit_amount;
|
|
11934
12340
|
const unit = product.duration_unit ? UNIT_LABELS2[product.duration_unit] || product.duration_unit : "day";
|
|
11935
12341
|
const priceUnit = product.price_basis === "per_person" ? "guest" : product.price_basis === "flat" ? "" : unit;
|
|
@@ -11999,7 +12405,7 @@ function AccommodationCard({
|
|
|
11999
12405
|
className
|
|
12000
12406
|
}) {
|
|
12001
12407
|
const image = product.image_url || product.images?.[0] || "";
|
|
12002
|
-
const currency =
|
|
12408
|
+
const currency = chunkWMEC5JWN_js.getProductCurrency(product);
|
|
12003
12409
|
const hasTiers = product.quantity_pricing && product.quantity_pricing.length > 1;
|
|
12004
12410
|
const cancellationHours = product.cancellation_window_minutes ? Math.floor(product.cancellation_window_minutes / 60) : null;
|
|
12005
12411
|
const tags = product.tags || [];
|
|
@@ -12065,7 +12471,7 @@ function LeaseServiceCard({
|
|
|
12065
12471
|
className
|
|
12066
12472
|
}) {
|
|
12067
12473
|
const image = product.image_url || product.images?.[0] || "";
|
|
12068
|
-
const currency =
|
|
12474
|
+
const currency = chunkWMEC5JWN_js.getProductCurrency(product);
|
|
12069
12475
|
const hasDeposit = product.deposit_type && product.deposit_type !== "none" && product.deposit_amount;
|
|
12070
12476
|
const hasTiers = product.quantity_pricing && product.quantity_pricing.length > 1;
|
|
12071
12477
|
const unit = product.duration_unit ? UNIT_LABELS3[product.duration_unit] || product.duration_unit : "mo";
|
|
@@ -12139,7 +12545,7 @@ function SubscriptionCard({
|
|
|
12139
12545
|
className
|
|
12140
12546
|
}) {
|
|
12141
12547
|
const image = product.image_url || product.images?.[0] || "";
|
|
12142
|
-
const currency =
|
|
12548
|
+
const currency = chunkWMEC5JWN_js.getProductCurrency(product);
|
|
12143
12549
|
const plans = product.billing_plans || [];
|
|
12144
12550
|
const primaryPlan = plans[0];
|
|
12145
12551
|
const frequency = primaryPlan?.frequency ? FREQUENCY_LABELS2[primaryPlan.frequency] || `/${primaryPlan.frequency}` : "/mo";
|
|
@@ -12370,7 +12776,7 @@ function ProductCard({
|
|
|
12370
12776
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-product-card-body": true, className: cn("p-4 flex flex-col gap-1", classNames?.body), children: [
|
|
12371
12777
|
/* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-product-card-name": true, className: cn("font-semibold text-foreground leading-tight", classNames?.name), children: product.name }),
|
|
12372
12778
|
descriptionPreview && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-product-card-description": true, className: cn("text-sm text-muted-foreground line-clamp-2", classNames?.description), children: descriptionPreview }),
|
|
12373
|
-
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price, currency:
|
|
12779
|
+
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price, currency: chunkWMEC5JWN_js.getProductCurrency(product), className: cn("text-sm font-medium text-foreground mt-1", classNames?.price) })
|
|
12374
12780
|
] })
|
|
12375
12781
|
] });
|
|
12376
12782
|
})();
|
|
@@ -12699,7 +13105,7 @@ function SearchInput({
|
|
|
12699
13105
|
}
|
|
12700
13106
|
),
|
|
12701
13107
|
/* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-search-result-name": true, className: classNames?.resultName, style: { flex: 1, textAlign: "left" }, children: product.name }),
|
|
12702
|
-
product.default_price !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-search-result-price": true, className: classNames?.resultPrice, style: { flexShrink: 0 }, children:
|
|
13108
|
+
product.default_price !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-search-result-price": true, className: classNames?.resultPrice, style: { flexShrink: 0 }, children: chunkWMEC5JWN_js.formatPrice(product.default_price) })
|
|
12703
13109
|
] })
|
|
12704
13110
|
},
|
|
12705
13111
|
product.id
|
|
@@ -13194,19 +13600,19 @@ function OrderSummary({
|
|
|
13194
13600
|
order.customer_notes.map((note, index) => /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-order-note": true, children: note }, index))
|
|
13195
13601
|
] }),
|
|
13196
13602
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-order-totals": true, className: classNames?.totals, children: [
|
|
13197
|
-
order.total_discount != null &&
|
|
13603
|
+
order.total_discount != null && chunkWMEC5JWN_js.parsePrice(order.total_discount) !== 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-order-discount": true, children: [
|
|
13198
13604
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Discount" }),
|
|
13199
13605
|
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: order.total_discount, prefix: "-" })
|
|
13200
13606
|
] }),
|
|
13201
|
-
order.delivery_fee != null &&
|
|
13607
|
+
order.delivery_fee != null && chunkWMEC5JWN_js.parsePrice(order.delivery_fee) > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-order-delivery-fee": true, children: [
|
|
13202
13608
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Delivery fee" }),
|
|
13203
13609
|
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: order.delivery_fee })
|
|
13204
13610
|
] }),
|
|
13205
|
-
order.service_charge != null &&
|
|
13611
|
+
order.service_charge != null && chunkWMEC5JWN_js.parsePrice(order.service_charge) !== 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-order-service-charge": true, children: [
|
|
13206
13612
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Service charge" }),
|
|
13207
13613
|
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: order.service_charge })
|
|
13208
13614
|
] }),
|
|
13209
|
-
order.tax != null &&
|
|
13615
|
+
order.tax != null && chunkWMEC5JWN_js.parsePrice(order.tax) !== 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-order-tax": true, children: [
|
|
13210
13616
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Tax" }),
|
|
13211
13617
|
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: order.tax })
|
|
13212
13618
|
] }),
|
|
@@ -13737,7 +14143,7 @@ function BookingPage({
|
|
|
13737
14143
|
const hasStaffStep = staff && staff.length > 0;
|
|
13738
14144
|
const depositType = product?.deposit_type;
|
|
13739
14145
|
const depositAmount = product?.deposit_amount;
|
|
13740
|
-
const hasDeposit = depositType !== void 0 && depositType !== "none" && depositAmount !== void 0 &&
|
|
14146
|
+
const hasDeposit = depositType !== void 0 && depositType !== "none" && depositAmount !== void 0 && chunkWMEC5JWN_js.parsePrice(depositAmount) !== 0;
|
|
13741
14147
|
const cancellationMinutes = product?.cancellation_window_minutes;
|
|
13742
14148
|
const noShowFee = product?.no_show_fee;
|
|
13743
14149
|
const handleSlotSelect = React14.useCallback(
|
|
@@ -13870,14 +14276,14 @@ function BookingPage({
|
|
|
13870
14276
|
service.price && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-booking-service-price": true, children: /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: service.price, currency }) }),
|
|
13871
14277
|
hasDeposit && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-booking-deposit-info": true, className: classNames?.depositInfo, children: [
|
|
13872
14278
|
"Deposit: ",
|
|
13873
|
-
depositType === "percentage" ? `${
|
|
14279
|
+
depositType === "percentage" ? `${chunkWMEC5JWN_js.parsePrice(depositAmount)}%` : /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: depositAmount, currency })
|
|
13874
14280
|
] }),
|
|
13875
14281
|
cancellationMinutes !== void 0 && cancellationMinutes > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-booking-cancellation-policy": true, className: classNames?.cancellationPolicy, children: [
|
|
13876
14282
|
"Free cancellation up to ",
|
|
13877
14283
|
cancellationMinutes >= 60 ? `${Math.floor(cancellationMinutes / 60)} hour${Math.floor(cancellationMinutes / 60) !== 1 ? "s" : ""}` : `${cancellationMinutes} minute${cancellationMinutes !== 1 ? "s" : ""}`,
|
|
13878
14284
|
" before"
|
|
13879
14285
|
] }),
|
|
13880
|
-
noShowFee !== void 0 &&
|
|
14286
|
+
noShowFee !== void 0 && chunkWMEC5JWN_js.parsePrice(noShowFee) !== 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-booking-no-show-fee": true, className: classNames?.cancellationPolicy, children: [
|
|
13881
14287
|
"No-show fee: ",
|
|
13882
14288
|
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: noShowFee, currency })
|
|
13883
14289
|
] })
|
|
@@ -13980,7 +14386,7 @@ function BookingPage({
|
|
|
13980
14386
|
] }),
|
|
13981
14387
|
hasDeposit && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary-row": true, className: cn(classNames?.summaryRow, classNames?.depositInfo), children: [
|
|
13982
14388
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Deposit" }),
|
|
13983
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: depositType === "percentage" ? `${
|
|
14389
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: depositType === "percentage" ? `${chunkWMEC5JWN_js.parsePrice(depositAmount)}%` : /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: depositAmount, currency }) })
|
|
13984
14390
|
] })
|
|
13985
14391
|
] }),
|
|
13986
14392
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -14654,9 +15060,9 @@ function DefaultProductLayout({
|
|
|
14654
15060
|
}) {
|
|
14655
15061
|
const [selectedVariantId, setSelectedVariantId] = React14__default.default.useState();
|
|
14656
15062
|
const images = chunkQPRI2NII_js.resolveGallery(product, selectedVariantId);
|
|
14657
|
-
const currency =
|
|
15063
|
+
const currency = chunkWMEC5JWN_js.getProductCurrency(product);
|
|
14658
15064
|
const hasRange = product.quantity_pricing && product.quantity_pricing.length > 1 || product.variants && product.variants.length > 1;
|
|
14659
|
-
const onSale =
|
|
15065
|
+
const onSale = chunkWMEC5JWN_js.isOnSale(product);
|
|
14660
15066
|
const hasPhysicalDetails = product.sku || product.vendor || product.material;
|
|
14661
15067
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-product-layout": "default", className: cn("space-y-8", className), children: [
|
|
14662
15068
|
renderBreadcrumb?.(product),
|
|
@@ -14679,13 +15085,13 @@ function DefaultProductLayout({
|
|
|
14679
15085
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-baseline gap-3", children: hasRange ? /* @__PURE__ */ jsxRuntime.jsx(PriceRange, { product, currency, className: "text-2xl font-extrabold" }) : product.sale ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
14680
15086
|
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.sale.price, currency, className: "text-2xl font-extrabold" }),
|
|
14681
15087
|
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.sale.original, currency, className: "text-lg text-muted-foreground line-through" }),
|
|
14682
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-bold text-destructive bg-destructive/10 px-2 py-0.5", children: product.sale.badge_text ?? `${Math.round(
|
|
15088
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-bold text-destructive bg-destructive/10 px-2 py-0.5", children: product.sale.badge_text ?? `${Math.round(chunkWMEC5JWN_js.parsePrice(product.sale.percent_off))}% OFF` })
|
|
14683
15089
|
] }) : onSale ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
14684
15090
|
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price, currency, className: "text-2xl font-extrabold" }),
|
|
14685
|
-
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount:
|
|
15091
|
+
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: chunkWMEC5JWN_js.getBasePrice(product), currency, className: "text-lg text-muted-foreground line-through" }),
|
|
14686
15092
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm font-bold text-destructive bg-destructive/10 px-2 py-0.5", children: [
|
|
14687
15093
|
"Save ",
|
|
14688
|
-
|
|
15094
|
+
chunkWMEC5JWN_js.getDiscountPercentage(product),
|
|
14689
15095
|
"%"
|
|
14690
15096
|
] })
|
|
14691
15097
|
] }) : /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price, currency, className: "text-2xl font-semibold" }) }),
|
|
@@ -14747,7 +15153,7 @@ function FoodProductLayout({
|
|
|
14747
15153
|
className
|
|
14748
15154
|
}) {
|
|
14749
15155
|
const images = product.images || (product.image_url ? [product.image_url] : []);
|
|
14750
|
-
const currency =
|
|
15156
|
+
const currency = chunkWMEC5JWN_js.getProductCurrency(product);
|
|
14751
15157
|
const tags = product.tags || [];
|
|
14752
15158
|
const ingredients = getMetadataStringList(product.metadata, "ingredients");
|
|
14753
15159
|
const pairings = getMetadataStringList(product.metadata, "pairings");
|
|
@@ -14822,7 +15228,7 @@ function WholesaleProductLayout({
|
|
|
14822
15228
|
className
|
|
14823
15229
|
}) {
|
|
14824
15230
|
const images = product.images || (product.image_url ? [product.image_url] : []);
|
|
14825
|
-
const currency =
|
|
15231
|
+
const currency = chunkWMEC5JWN_js.getProductCurrency(product);
|
|
14826
15232
|
const hasTiers = product.quantity_pricing && product.quantity_pricing.length > 1;
|
|
14827
15233
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-product-layout": "wholesale", className: cn("space-y-8", className), children: [
|
|
14828
15234
|
renderBreadcrumb?.(product),
|
|
@@ -14906,9 +15312,9 @@ function ServiceProductLayout({
|
|
|
14906
15312
|
className
|
|
14907
15313
|
}) {
|
|
14908
15314
|
const images = product.images || (product.image_url ? [product.image_url] : []);
|
|
14909
|
-
const currency =
|
|
15315
|
+
const currency = chunkWMEC5JWN_js.getProductCurrency(product);
|
|
14910
15316
|
const hasDeposit = product.deposit_type && product.deposit_type !== "none" && product.deposit_amount;
|
|
14911
|
-
const depositAmount = hasDeposit ?
|
|
15317
|
+
const depositAmount = hasDeposit ? chunkWMEC5JWN_js.parsePrice(product.deposit_amount) : 0;
|
|
14912
15318
|
const cancellationHours = product.cancellation_window_minutes ? Math.floor(product.cancellation_window_minutes / 60) : null;
|
|
14913
15319
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-product-layout": "service", className: cn("space-y-8", className), children: [
|
|
14914
15320
|
renderBreadcrumb?.(product),
|
|
@@ -14976,7 +15382,7 @@ function ServiceProductLayout({
|
|
|
14976
15382
|
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: depositAmount, currency, className: "font-medium text-foreground" }),
|
|
14977
15383
|
" deposit charged at booking"
|
|
14978
15384
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
14979
|
-
|
|
15385
|
+
chunkWMEC5JWN_js.parsePrice(product.deposit_amount),
|
|
14980
15386
|
"% deposit charged at booking"
|
|
14981
15387
|
] }) })
|
|
14982
15388
|
] })
|
|
@@ -15008,7 +15414,7 @@ function DigitalProductLayout({
|
|
|
15008
15414
|
className
|
|
15009
15415
|
}) {
|
|
15010
15416
|
const images = product.images || (product.image_url ? [product.image_url] : []);
|
|
15011
|
-
const currency =
|
|
15417
|
+
const currency = chunkWMEC5JWN_js.getProductCurrency(product);
|
|
15012
15418
|
const typeLabel = product.digital_type ? DIGITAL_TYPE_LABELS[product.digital_type] || product.digital_type : "Digital product";
|
|
15013
15419
|
const isTicket = product.digital_type === "ticket";
|
|
15014
15420
|
const isAccessPass = product.digital_type === "access_grant";
|
|
@@ -15135,15 +15541,15 @@ function BundleProductLayout({
|
|
|
15135
15541
|
className
|
|
15136
15542
|
}) {
|
|
15137
15543
|
const images = product.images || (product.image_url ? [product.image_url] : []);
|
|
15138
|
-
const currency =
|
|
15544
|
+
const currency = chunkWMEC5JWN_js.getProductCurrency(product);
|
|
15139
15545
|
const components = product.components || [];
|
|
15140
|
-
const onSale =
|
|
15141
|
-
const discount =
|
|
15546
|
+
const onSale = chunkWMEC5JWN_js.isOnSale(product);
|
|
15547
|
+
const discount = chunkWMEC5JWN_js.getDiscountPercentage(product);
|
|
15142
15548
|
const baseTotal = components.reduce(
|
|
15143
|
-
(sum, c) => sum +
|
|
15549
|
+
(sum, c) => sum + chunkWMEC5JWN_js.parsePrice(c.effective_price ?? 0) * (c.quantity ?? 1),
|
|
15144
15550
|
0
|
|
15145
15551
|
);
|
|
15146
|
-
const bundlePrice =
|
|
15552
|
+
const bundlePrice = chunkWMEC5JWN_js.parsePrice(product.default_price);
|
|
15147
15553
|
const savings = baseTotal > bundlePrice ? baseTotal - bundlePrice : 0;
|
|
15148
15554
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-product-layout": "bundle", className: cn("space-y-8", className), children: [
|
|
15149
15555
|
renderBreadcrumb?.(product),
|
|
@@ -15219,7 +15625,7 @@ function CompositeProductLayout({
|
|
|
15219
15625
|
className
|
|
15220
15626
|
}) {
|
|
15221
15627
|
const images = product.images || (product.image_url ? [product.image_url] : []);
|
|
15222
|
-
const currency =
|
|
15628
|
+
const currency = chunkWMEC5JWN_js.getProductCurrency(product);
|
|
15223
15629
|
const groups = product.groups || [];
|
|
15224
15630
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-product-layout": "composite", className: cn("space-y-8", className), children: [
|
|
15225
15631
|
renderBreadcrumb?.(product),
|
|
@@ -15642,7 +16048,7 @@ function CartDrawer({
|
|
|
15642
16048
|
}) {
|
|
15643
16049
|
const { isOpen, close } = useCartDrawer();
|
|
15644
16050
|
const cart = useCart();
|
|
15645
|
-
const subtotalNum =
|
|
16051
|
+
const subtotalNum = chunkWMEC5JWN_js.parsePrice(cart.subtotal);
|
|
15646
16052
|
const animatedSubtotal = useAnimatedNumber(subtotalNum);
|
|
15647
16053
|
React14.useEffect(() => {
|
|
15648
16054
|
if (!isOpen) return;
|
|
@@ -16036,9 +16442,9 @@ function CatalogueCollectionLayout({
|
|
|
16036
16442
|
result = result.filter((p) => p.tags?.includes(activeCategory));
|
|
16037
16443
|
}
|
|
16038
16444
|
if (sortBy === "price-asc") {
|
|
16039
|
-
result = [...result].sort((a, b) =>
|
|
16445
|
+
result = [...result].sort((a, b) => chunkWMEC5JWN_js.parsePrice(a.default_price) - chunkWMEC5JWN_js.parsePrice(b.default_price));
|
|
16040
16446
|
} else if (sortBy === "price-desc") {
|
|
16041
|
-
result = [...result].sort((a, b) =>
|
|
16447
|
+
result = [...result].sort((a, b) => chunkWMEC5JWN_js.parsePrice(b.default_price) - chunkWMEC5JWN_js.parsePrice(a.default_price));
|
|
16042
16448
|
} else if (sortBy === "name") {
|
|
16043
16449
|
result = [...result].sort((a, b) => a.name.localeCompare(b.name));
|
|
16044
16450
|
}
|
|
@@ -19567,7 +19973,7 @@ function toneChip(value) {
|
|
|
19567
19973
|
}
|
|
19568
19974
|
}
|
|
19569
19975
|
function money(amount, currency) {
|
|
19570
|
-
return
|
|
19976
|
+
return chunkWMEC5JWN_js.formatPrice(chunkWMEC5JWN_js.parsePrice(num(amount) ?? 0), text(currency));
|
|
19571
19977
|
}
|
|
19572
19978
|
var CHAT_GENUI_COMPONENTS = {
|
|
19573
19979
|
Stack: ({ node, ctx }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -19815,7 +20221,7 @@ function ReplyCardView({
|
|
|
19815
20221
|
card.image_url && /* @__PURE__ */ jsxRuntime.jsx("img", { src: card.image_url, alt: "", className: "size-12 shrink-0 rounded-xl object-cover" }),
|
|
19816
20222
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-col gap-0.5", children: [
|
|
19817
20223
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-sm font-semibold text-foreground", children: card.name }),
|
|
19818
|
-
card.price !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[13px] font-semibold text-foreground tabular-nums", children:
|
|
20224
|
+
card.price !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[13px] font-semibold text-foreground tabular-nums", children: chunkWMEC5JWN_js.formatPrice(chunkWMEC5JWN_js.parsePrice(card.price), currency ?? void 0) }),
|
|
19819
20225
|
fire2 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-semibold text-primary", children: "View" })
|
|
19820
20226
|
] })
|
|
19821
20227
|
]
|
|
@@ -19898,11 +20304,11 @@ function ChatWidget({
|
|
|
19898
20304
|
if (!client) return;
|
|
19899
20305
|
setAttachError(null);
|
|
19900
20306
|
if (!file.type.startsWith("image/")) {
|
|
19901
|
-
setAttachError(new
|
|
20307
|
+
setAttachError(new chunkNIOUSKQQ_js.CimplifyError("invalid_attachment", "Only photos can be attached."));
|
|
19902
20308
|
return;
|
|
19903
20309
|
}
|
|
19904
20310
|
if (file.size > MAX_ATTACHMENT_BYTES) {
|
|
19905
|
-
setAttachError(new
|
|
20311
|
+
setAttachError(new chunkNIOUSKQQ_js.CimplifyError("attachment_too_large", "Photos must be under 5MB."));
|
|
19906
20312
|
return;
|
|
19907
20313
|
}
|
|
19908
20314
|
const uploaded = await client.uploads.upload(file);
|