@cimplify/sdk 0.27.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.js CHANGED
@@ -1,10 +1,10 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunk4JSRPSNA_js = require('./chunk-4JSRPSNA.js');
4
+ var chunkR4AKAGZQ_js = require('./chunk-R4AKAGZQ.js');
5
5
  var chunk2CGA3MUW_js = require('./chunk-2CGA3MUW.js');
6
6
  var chunkPEDLCL72_js = require('./chunk-PEDLCL72.js');
7
- var React3 = require('react');
7
+ var React10 = require('react');
8
8
  var jsxRuntime = require('react/jsx-runtime');
9
9
  var clsx = require('clsx');
10
10
  var tailwindMerge = require('tailwind-merge');
@@ -20,7 +20,7 @@ var tabs = require('@base-ui/react/tabs');
20
20
 
21
21
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
22
22
 
23
- var React3__default = /*#__PURE__*/_interopDefault(React3);
23
+ var React10__default = /*#__PURE__*/_interopDefault(React10);
24
24
 
25
25
  // src/ads/identity.ts
26
26
  var COOKIE_NAME = "_cimplify_uid";
@@ -197,7 +197,7 @@ function deriveAdsApiUrl() {
197
197
  }
198
198
  return "https://api.cimplify.io";
199
199
  }
200
- var AdContext = React3.createContext({
200
+ var AdContext = React10.createContext({
201
201
  siteId: null,
202
202
  config: null,
203
203
  isLoading: true,
@@ -205,7 +205,7 @@ var AdContext = React3.createContext({
205
205
  apiBase: "https://api.cimplify.io"
206
206
  });
207
207
  function useAds() {
208
- return React3.useContext(AdContext);
208
+ return React10.useContext(AdContext);
209
209
  }
210
210
  function AdProvider({
211
211
  siteId,
@@ -214,10 +214,10 @@ function AdProvider({
214
214
  children
215
215
  }) {
216
216
  const resolvedApiBase = apiBase || deriveAdsApiUrl();
217
- const [config, setConfig] = React3.useState(null);
218
- const [isLoading, setIsLoading] = React3.useState(true);
219
- const [identity, setIdentity] = React3.useState(null);
220
- React3.useEffect(() => {
217
+ const [config, setConfig] = React10.useState(null);
218
+ const [isLoading, setIsLoading] = React10.useState(true);
219
+ const [identity, setIdentity] = React10.useState(null);
220
+ React10.useEffect(() => {
221
221
  const userIdentity = getUserIdentity(authenticatedAccountId);
222
222
  setIdentity(userIdentity);
223
223
  fetch(`${resolvedApiBase}/ads/config/${siteId}`).then((r) => r.json()).then((data) => {
@@ -240,11 +240,11 @@ function Ad({
240
240
  onClick
241
241
  }) {
242
242
  const { siteId, config, isLoading, identity, apiBase } = useAds();
243
- const [ad, setAd] = React3.useState(null);
244
- const [error, setError] = React3.useState(false);
245
- const impressionTracked = React3.useRef(false);
246
- const containerRef = React3.useRef(null);
247
- React3.useEffect(() => {
243
+ const [ad, setAd] = React10.useState(null);
244
+ const [error, setError] = React10.useState(false);
245
+ const impressionTracked = React10.useRef(false);
246
+ const containerRef = React10.useRef(null);
247
+ React10.useEffect(() => {
248
248
  if (isLoading || !config?.enabled || !siteId || !identity) return;
249
249
  const path = typeof window !== "undefined" ? window.location.pathname : "/";
250
250
  const referrer = typeof document !== "undefined" ? document.referrer : "";
@@ -287,7 +287,7 @@ function Ad({
287
287
  }
288
288
  }).catch(() => setError(true));
289
289
  }, [siteId, config, isLoading, slot, identity, apiBase]);
290
- React3.useEffect(() => {
290
+ React10.useEffect(() => {
291
291
  if (!ad || impressionTracked.current || typeof window === "undefined" || !identity) return;
292
292
  const observer = new IntersectionObserver(
293
293
  ([entry]) => {
@@ -570,7 +570,8 @@ function mapServerCart(serverCart) {
570
570
  confirmationCode: item.confirmation_code || void 0,
571
571
  serviceStatus: item.service_status || void 0,
572
572
  bundleResolved: item.bundle_resolved || void 0,
573
- compositeResolved: item.composite_resolved || void 0
573
+ compositeResolved: item.composite_resolved || void 0,
574
+ customerInputs: item.customer_inputs || void 0
574
575
  });
575
576
  });
576
577
  return {
@@ -790,7 +791,8 @@ function createCartStore(params) {
790
791
  scheduled_start: normalizedOptions.scheduledStart,
791
792
  scheduled_end: normalizedOptions.scheduledEnd,
792
793
  staff_id: normalizedOptions.staffId,
793
- resource_id: normalizedOptions.resourceId
794
+ resource_id: normalizedOptions.resourceId,
795
+ customer_inputs: normalizedOptions.customerInputs
794
796
  });
795
797
  if (!result.ok) {
796
798
  throw result.error;
@@ -981,7 +983,7 @@ function useCart(options = {}) {
981
983
  const locationId = options.locationId ?? client.getLocationId();
982
984
  const isDemoMode = options.demoMode ?? context?.isDemoMode ?? client.getPublicKey().trim().length === 0;
983
985
  const currency = options.currency ?? context?.currency ?? "USD";
984
- const store = React3.useMemo(
986
+ const store = React10.useMemo(
985
987
  () => getOrCreateStore({
986
988
  client,
987
989
  locationId,
@@ -990,53 +992,53 @@ function useCart(options = {}) {
990
992
  }),
991
993
  [client, currency, isDemoMode, locationId]
992
994
  );
993
- const snapshot = React3.useSyncExternalStore(
995
+ const snapshot = React10.useSyncExternalStore(
994
996
  store.subscribe,
995
997
  store.getSnapshot,
996
998
  store.getSnapshot
997
999
  );
998
- React3.useEffect(() => {
1000
+ React10.useEffect(() => {
999
1001
  void store.initialize();
1000
1002
  }, [store]);
1001
- const addItem = React3.useCallback(
1003
+ const addItem = React10.useCallback(
1002
1004
  async (product, quantity, addOptions) => {
1003
1005
  await store.addItem(product, quantity, addOptions);
1004
1006
  },
1005
1007
  [store]
1006
1008
  );
1007
- const removeItem = React3.useCallback(
1009
+ const removeItem = React10.useCallback(
1008
1010
  async (itemId) => {
1009
1011
  await store.removeItem(itemId);
1010
1012
  },
1011
1013
  [store]
1012
1014
  );
1013
- const updateQuantity = React3.useCallback(
1015
+ const updateQuantity = React10.useCallback(
1014
1016
  async (itemId, quantity) => {
1015
1017
  await store.updateQuantity(itemId, quantity);
1016
1018
  },
1017
1019
  [store]
1018
1020
  );
1019
- const clearCart = React3.useCallback(async () => {
1021
+ const clearCart = React10.useCallback(async () => {
1020
1022
  await store.clearCart();
1021
1023
  }, [store]);
1022
- const sync = React3.useCallback(async () => {
1024
+ const sync = React10.useCallback(async () => {
1023
1025
  try {
1024
1026
  await store.sync();
1025
1027
  } catch (syncError) {
1026
1028
  throw syncError;
1027
1029
  }
1028
1030
  }, [store]);
1029
- const reorder = React3.useCallback(
1031
+ const reorder = React10.useCallback(
1030
1032
  async (orderId) => {
1031
1033
  return store.reorder(orderId);
1032
1034
  },
1033
1035
  [store]
1034
1036
  );
1035
- const itemCount = React3.useMemo(
1037
+ const itemCount = React10.useMemo(
1036
1038
  () => snapshot.items.reduce((sum, item) => sum + item.quantity, 0),
1037
1039
  [snapshot.items]
1038
1040
  );
1039
- return React3.useMemo(() => ({
1041
+ return React10.useMemo(() => ({
1040
1042
  items: snapshot.items,
1041
1043
  itemCount,
1042
1044
  subtotal: snapshot.subtotal,
@@ -1061,7 +1063,7 @@ var DEFAULT_COUNTRY = "US";
1061
1063
  function createDefaultClient() {
1062
1064
  const processRef = globalThis.process;
1063
1065
  const envPublicKey = processRef?.env?.NEXT_PUBLIC_CIMPLIFY_PUBLIC_KEY || "";
1064
- return chunk4JSRPSNA_js.createCimplifyClient({ publicKey: envPublicKey });
1066
+ return chunkR4AKAGZQ_js.createCimplifyClient({ publicKey: envPublicKey });
1065
1067
  }
1066
1068
  function getStoredLocationId() {
1067
1069
  if (typeof window === "undefined" || !window.localStorage) {
@@ -1118,30 +1120,30 @@ function resolveInitialLocation(locations) {
1118
1120
  }
1119
1121
  return locations[0];
1120
1122
  }
1121
- var CimplifyClientContext = React3.createContext(null);
1122
- var CimplifyStateContext = React3.createContext(null);
1123
+ var CimplifyClientContext = React10.createContext(null);
1124
+ var CimplifyStateContext = React10.createContext(null);
1123
1125
  function CimplifyProvider({
1124
1126
  client,
1125
1127
  children,
1126
1128
  onLocationChange
1127
1129
  }) {
1128
- const resolvedClient = React3.useMemo(() => client ?? createDefaultClient(), [client]);
1129
- const onLocationChangeRef = React3.useRef(onLocationChange);
1130
- const [business, setBusiness] = React3.useState(null);
1131
- const [locations, setLocations] = React3.useState([]);
1132
- const [currentLocation, setCurrentLocationState] = React3.useState(null);
1133
- const [isReady, setIsReady] = React3.useState(false);
1134
- React3.useEffect(() => {
1130
+ const resolvedClient = React10.useMemo(() => client ?? createDefaultClient(), [client]);
1131
+ const onLocationChangeRef = React10.useRef(onLocationChange);
1132
+ const [business, setBusiness] = React10.useState(null);
1133
+ const [locations, setLocations] = React10.useState([]);
1134
+ const [currentLocation, setCurrentLocationState] = React10.useState(null);
1135
+ const [isReady, setIsReady] = React10.useState(false);
1136
+ React10.useEffect(() => {
1135
1137
  onLocationChangeRef.current = onLocationChange;
1136
1138
  }, [onLocationChange]);
1137
1139
  const isDemoMode = resolvedClient.getPublicKey().trim().length === 0;
1138
1140
  const baseCurrency = business?.default_currency || DEFAULT_CURRENCY;
1139
- const [displayCurrencyOverride, setDisplayCurrencyOverride] = React3.useState(
1141
+ const [displayCurrencyOverride, setDisplayCurrencyOverride] = React10.useState(
1140
1142
  () => getStoredDisplayCurrency()
1141
1143
  );
1142
- const [fxRate, setFxRate] = React3.useState(null);
1144
+ const [fxRate, setFxRate] = React10.useState(null);
1143
1145
  const displayCurrency = displayCurrencyOverride && displayCurrencyOverride !== baseCurrency ? displayCurrencyOverride : baseCurrency;
1144
- const setDisplayCurrency = React3.useCallback(
1146
+ const setDisplayCurrency = React10.useCallback(
1145
1147
  (currency) => {
1146
1148
  const normalized = currency?.trim().toUpperCase() || null;
1147
1149
  if (normalized && !chunkPEDLCL72_js.isSupportedCurrency(normalized)) {
@@ -1155,7 +1157,7 @@ function CimplifyProvider({
1155
1157
  },
1156
1158
  [baseCurrency]
1157
1159
  );
1158
- React3.useEffect(() => {
1160
+ React10.useEffect(() => {
1159
1161
  if (displayCurrency === baseCurrency || isDemoMode) {
1160
1162
  setFxRate(null);
1161
1163
  return;
@@ -1180,7 +1182,7 @@ function CimplifyProvider({
1180
1182
  clearInterval(intervalId);
1181
1183
  };
1182
1184
  }, [resolvedClient, baseCurrency, displayCurrency, isDemoMode]);
1183
- const convertPrice = React3.useCallback(
1185
+ const convertPrice = React10.useCallback(
1184
1186
  (amount) => {
1185
1187
  const num = typeof amount === "string" ? parseFloat(amount) : amount;
1186
1188
  if (isNaN(num)) return 0;
@@ -1189,7 +1191,7 @@ function CimplifyProvider({
1189
1191
  },
1190
1192
  [fxRate, displayCurrency, baseCurrency]
1191
1193
  );
1192
- const setCurrentLocation = React3.useCallback(
1194
+ const setCurrentLocation = React10.useCallback(
1193
1195
  (location) => {
1194
1196
  const previousLocationId = resolvedClient.getLocationId();
1195
1197
  if (previousLocationId && previousLocationId !== location.id) {
@@ -1202,7 +1204,7 @@ function CimplifyProvider({
1202
1204
  },
1203
1205
  [resolvedClient]
1204
1206
  );
1205
- React3.useEffect(() => {
1207
+ React10.useEffect(() => {
1206
1208
  let cancelled = false;
1207
1209
  async function bootstrap() {
1208
1210
  setIsReady(false);
@@ -1258,7 +1260,7 @@ function CimplifyProvider({
1258
1260
  cancelled = true;
1259
1261
  };
1260
1262
  }, [resolvedClient, isDemoMode]);
1261
- const clientContextValue = React3.useMemo(
1263
+ const clientContextValue = React10.useMemo(
1262
1264
  () => ({
1263
1265
  client: resolvedClient,
1264
1266
  business,
@@ -1278,7 +1280,7 @@ function CimplifyProvider({
1278
1280
  isDemoMode
1279
1281
  ]
1280
1282
  );
1281
- const stateContextValue = React3.useMemo(
1283
+ const stateContextValue = React10.useMemo(
1282
1284
  () => ({
1283
1285
  currentLocation,
1284
1286
  setCurrentLocation,
@@ -1299,20 +1301,20 @@ function CimplifyProvider({
1299
1301
  return /* @__PURE__ */ jsxRuntime.jsx(CimplifyClientContext.Provider, { value: clientContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(CimplifyStateContext.Provider, { value: stateContextValue, children }) });
1300
1302
  }
1301
1303
  function useCimplify() {
1302
- const clientContext = React3.useContext(CimplifyClientContext);
1303
- const stateContext = React3.useContext(CimplifyStateContext);
1304
+ const clientContext = React10.useContext(CimplifyClientContext);
1305
+ const stateContext = React10.useContext(CimplifyStateContext);
1304
1306
  if (!clientContext || !stateContext) {
1305
1307
  throw new Error("useCimplify must be used within CimplifyProvider");
1306
1308
  }
1307
- return React3.useMemo(
1309
+ return React10.useMemo(
1308
1310
  () => ({ ...clientContext, ...stateContext }),
1309
1311
  [clientContext, stateContext]
1310
1312
  );
1311
1313
  }
1312
1314
  function useOptionalCimplify() {
1313
- const clientContext = React3.useContext(CimplifyClientContext);
1314
- const stateContext = React3.useContext(CimplifyStateContext);
1315
- return React3.useMemo(() => {
1315
+ const clientContext = React10.useContext(CimplifyClientContext);
1316
+ const stateContext = React10.useContext(CimplifyStateContext);
1317
+ return React10.useMemo(() => {
1316
1318
  if (!clientContext || !stateContext) {
1317
1319
  return null;
1318
1320
  }
@@ -1320,14 +1322,14 @@ function useOptionalCimplify() {
1320
1322
  }, [clientContext, stateContext]);
1321
1323
  }
1322
1324
  function useCimplifyClient() {
1323
- const context = React3.useContext(CimplifyClientContext);
1325
+ const context = React10.useContext(CimplifyClientContext);
1324
1326
  if (!context) {
1325
1327
  throw new Error("useCimplifyClient must be used within CimplifyProvider");
1326
1328
  }
1327
1329
  return context;
1328
1330
  }
1329
1331
  function useOptionalCimplifyClient() {
1330
- return React3.useContext(CimplifyClientContext);
1332
+ return React10.useContext(CimplifyClientContext);
1331
1333
  }
1332
1334
  var SPACE = { sm: 8};
1333
1335
  function shellColors(isDark, primaryColor) {
@@ -1385,36 +1387,36 @@ function CimplifyCheckout({
1385
1387
  demoMode,
1386
1388
  className
1387
1389
  }) {
1388
- const resolvedOrderTypes = React3.useMemo(
1390
+ const resolvedOrderTypes = React10.useMemo(
1389
1391
  () => orderTypes && orderTypes.length > 0 ? orderTypes : ["pickup", "delivery"],
1390
1392
  [orderTypes]
1391
1393
  );
1392
- const resolvedDefaultOrderType = React3.useMemo(() => {
1394
+ const resolvedDefaultOrderType = React10.useMemo(() => {
1393
1395
  if (defaultOrderType && resolvedOrderTypes.includes(defaultOrderType)) {
1394
1396
  return defaultOrderType;
1395
1397
  }
1396
1398
  return resolvedOrderTypes[0] || "pickup";
1397
1399
  }, [defaultOrderType, resolvedOrderTypes]);
1398
- const [orderType, setOrderType] = React3.useState(resolvedDefaultOrderType);
1399
- const [status, setStatus] = React3.useState(null);
1400
- const [statusText, setStatusText] = React3.useState("");
1401
- const [isSubmitting, setIsSubmitting] = React3.useState(false);
1402
- const [isInitializing, setIsInitializing] = React3.useState(false);
1403
- const [errorMessage, setErrorMessage] = React3.useState(null);
1404
- const [resolvedBusinessId, setResolvedBusinessId] = React3.useState(businessId ?? null);
1405
- const [resolvedCartId, setResolvedCartId] = React3.useState(cartId ?? null);
1406
- const [resolvedCart, setResolvedCart] = React3.useState(null);
1407
- const checkoutMountRef = React3.useRef(null);
1408
- const elementsRef = React3.useRef(null);
1409
- const activeCheckoutRef = React3.useRef(null);
1410
- const initialAppearanceRef = React3.useRef(appearance);
1411
- const hasWarnedInlineAppearanceRef = React3.useRef(false);
1412
- const isMountedRef = React3.useRef(true);
1413
- const demoRunRef = React3.useRef(0);
1400
+ const [orderType, setOrderType] = React10.useState(resolvedDefaultOrderType);
1401
+ const [status, setStatus] = React10.useState(null);
1402
+ const [statusText, setStatusText] = React10.useState("");
1403
+ const [isSubmitting, setIsSubmitting] = React10.useState(false);
1404
+ const [isInitializing, setIsInitializing] = React10.useState(false);
1405
+ const [errorMessage, setErrorMessage] = React10.useState(null);
1406
+ const [resolvedBusinessId, setResolvedBusinessId] = React10.useState(businessId ?? null);
1407
+ const [resolvedCartId, setResolvedCartId] = React10.useState(cartId ?? null);
1408
+ const [resolvedCart, setResolvedCart] = React10.useState(null);
1409
+ const checkoutMountRef = React10.useRef(null);
1410
+ const elementsRef = React10.useRef(null);
1411
+ const activeCheckoutRef = React10.useRef(null);
1412
+ const initialAppearanceRef = React10.useRef(appearance);
1413
+ const hasWarnedInlineAppearanceRef = React10.useRef(false);
1414
+ const isMountedRef = React10.useRef(true);
1415
+ const demoRunRef = React10.useRef(0);
1414
1416
  const isDemoCheckout = demoMode ?? client.getPublicKey().trim().length === 0;
1415
1417
  const isTestMode = client.isTestMode();
1416
1418
  const cimplifyCtx = useOptionalCimplify();
1417
- const fxOptions = React3.useMemo(() => {
1419
+ const fxOptions = React10.useMemo(() => {
1418
1420
  if (!cimplifyCtx?.fxRate) return void 0;
1419
1421
  if (cimplifyCtx.displayCurrency === cimplifyCtx.baseCurrency) return void 0;
1420
1422
  return {
@@ -1422,30 +1424,30 @@ function CimplifyCheckout({
1422
1424
  convertPrice: cimplifyCtx.convertPrice
1423
1425
  };
1424
1426
  }, [cimplifyCtx?.fxRate, cimplifyCtx?.displayCurrency, cimplifyCtx?.baseCurrency, cimplifyCtx?.convertPrice]);
1425
- const fxOptionsRef = React3.useRef(fxOptions);
1427
+ const fxOptionsRef = React10.useRef(fxOptions);
1426
1428
  fxOptionsRef.current = fxOptions;
1427
- const resolvedCartRef = React3.useRef(resolvedCart);
1429
+ const resolvedCartRef = React10.useRef(resolvedCart);
1428
1430
  resolvedCartRef.current = resolvedCart;
1429
1431
  const primaryColor = appearance?.variables?.primaryColor || "#0a2540";
1430
1432
  const isDark = appearance?.theme === "dark";
1431
- const emitStatus = React3__default.default.useEffectEvent(
1433
+ const emitStatus = React10__default.default.useEffectEvent(
1432
1434
  (nextStatus, context = {}) => {
1433
1435
  setStatus(nextStatus);
1434
1436
  setStatusText(context.display_text || "");
1435
1437
  onStatusChange?.(nextStatus, context);
1436
1438
  }
1437
1439
  );
1438
- const fireError = React3__default.default.useEffectEvent(
1440
+ const fireError = React10__default.default.useEffectEvent(
1439
1441
  (error) => {
1440
1442
  onError?.(error);
1441
1443
  }
1442
1444
  );
1443
- React3.useEffect(() => {
1445
+ React10.useEffect(() => {
1444
1446
  if (!resolvedOrderTypes.includes(orderType)) {
1445
1447
  setOrderType(resolvedDefaultOrderType);
1446
1448
  }
1447
1449
  }, [resolvedOrderTypes, resolvedDefaultOrderType, orderType]);
1448
- React3.useEffect(() => {
1450
+ React10.useEffect(() => {
1449
1451
  if (appearance && appearance !== initialAppearanceRef.current && !hasWarnedInlineAppearanceRef.current) {
1450
1452
  hasWarnedInlineAppearanceRef.current = true;
1451
1453
  console.warn(
@@ -1453,7 +1455,7 @@ function CimplifyCheckout({
1453
1455
  );
1454
1456
  }
1455
1457
  }, [appearance]);
1456
- React3.useEffect(() => {
1458
+ React10.useEffect(() => {
1457
1459
  let cancelled = false;
1458
1460
  async function bootstrap() {
1459
1461
  if (isDemoCheckout) {
@@ -1533,7 +1535,7 @@ function CimplifyCheckout({
1533
1535
  cancelled = true;
1534
1536
  };
1535
1537
  }, [businessId, cartId, client, isDemoCheckout]);
1536
- React3.useEffect(() => {
1538
+ React10.useEffect(() => {
1537
1539
  return () => {
1538
1540
  isMountedRef.current = false;
1539
1541
  demoRunRef.current += 1;
@@ -1541,7 +1543,7 @@ function CimplifyCheckout({
1541
1543
  activeCheckoutRef.current = null;
1542
1544
  };
1543
1545
  }, []);
1544
- const handleSubmit = React3__default.default.useEffectEvent(async () => {
1546
+ const handleSubmit = React10__default.default.useEffectEvent(async () => {
1545
1547
  if (isSubmitting || isInitializing || !resolvedCartId) {
1546
1548
  if (!resolvedCartId && !isInitializing) {
1547
1549
  const message = "Your cart is empty. Add items before checkout.";
@@ -1622,7 +1624,7 @@ function CimplifyCheckout({
1622
1624
  }
1623
1625
  }
1624
1626
  });
1625
- React3.useEffect(() => {
1627
+ React10.useEffect(() => {
1626
1628
  if (isDemoCheckout || !resolvedBusinessId) {
1627
1629
  elementsRef.current = null;
1628
1630
  return;
@@ -1669,7 +1671,7 @@ function CimplifyCheckout({
1669
1671
  resolvedDefaultOrderType,
1670
1672
  submitLabel
1671
1673
  ]);
1672
- React3.useEffect(() => {
1674
+ React10.useEffect(() => {
1673
1675
  if (!resolvedCart || !elementsRef.current) return;
1674
1676
  const checkoutElement = elementsRef.current.getElement("checkout");
1675
1677
  if (checkoutElement) {
@@ -1717,10 +1719,10 @@ function CimplifyAccount({
1717
1719
  const context = useOptionalCimplify();
1718
1720
  const client = clientProp ?? context?.client;
1719
1721
  const resolvedLinkUrl = linkUrl || DEFAULT_LINK_URL;
1720
- const iframeRef = React3.useRef(null);
1721
- const [height, setHeight] = React3.useState(400);
1722
- const [isReady, setIsReady] = React3.useState(false);
1723
- const iframeSrc = React3.useMemo(() => {
1722
+ const iframeRef = React10.useRef(null);
1723
+ const [height, setHeight] = React10.useState(400);
1724
+ const [isReady, setIsReady] = React10.useState(false);
1725
+ const iframeSrc = React10.useMemo(() => {
1724
1726
  const path = section ? `/elements/account/${section}` : "/elements/account";
1725
1727
  const url = new URL(path, resolvedLinkUrl);
1726
1728
  if (client) {
@@ -1729,7 +1731,7 @@ function CimplifyAccount({
1729
1731
  }
1730
1732
  return url.toString();
1731
1733
  }, [resolvedLinkUrl, section, client]);
1732
- React3.useEffect(() => {
1734
+ React10.useEffect(() => {
1733
1735
  function handleMessage(event) {
1734
1736
  if (!event.data || typeof event.data !== "object") return;
1735
1737
  if (iframeRef.current?.contentWindow && event.source !== iframeRef.current.contentWindow) {
@@ -1831,9 +1833,9 @@ function createCachedQuery(config) {
1831
1833
  }
1832
1834
  const enabled = options.enabled ?? true;
1833
1835
  const locationId = client.getLocationId();
1834
- const previousLocationRef = React3.useRef(locationId);
1835
- const requestIdRef = React3.useRef(0);
1836
- const optionsRef = React3.useRef(options);
1836
+ const previousLocationRef = React10.useRef(locationId);
1837
+ const requestIdRef = React10.useRef(0);
1838
+ const optionsRef = React10.useRef(options);
1837
1839
  optionsRef.current = options;
1838
1840
  if (config.locationSensitive && previousLocationRef.current !== locationId) {
1839
1841
  cache.clear();
@@ -1843,10 +1845,10 @@ function createCachedQuery(config) {
1843
1845
  sweep();
1844
1846
  const cacheKey2 = config.key(client, options);
1845
1847
  const cached = cache.get(cacheKey2);
1846
- const [data, setData] = React3.useState(cached?.data ?? null);
1847
- const [isLoading, setIsLoading] = React3.useState(enabled && !cached);
1848
- const [error, setError] = React3.useState(null);
1849
- const load = React3.useCallback(
1848
+ const [data, setData] = React10.useState(cached?.data ?? null);
1849
+ const [isLoading, setIsLoading] = React10.useState(enabled && !cached);
1850
+ const [error, setError] = React10.useState(null);
1851
+ const load = React10.useCallback(
1850
1852
  async (force = false) => {
1851
1853
  if (!enabled) {
1852
1854
  setIsLoading(false);
@@ -1889,10 +1891,10 @@ function createCachedQuery(config) {
1889
1891
  },
1890
1892
  [cacheKey2, client, enabled]
1891
1893
  );
1892
- React3.useEffect(() => {
1894
+ React10.useEffect(() => {
1893
1895
  void load(false);
1894
1896
  }, [load]);
1895
- const refetch = React3.useCallback(async () => {
1897
+ const refetch = React10.useCallback(async () => {
1896
1898
  cache.delete(cacheKey2);
1897
1899
  await load(true);
1898
1900
  }, [cacheKey2, load]);
@@ -2022,25 +2024,25 @@ function useOrder(orderId, options = {}) {
2022
2024
  if (!client) {
2023
2025
  throw new Error("useOrder must be used within CimplifyProvider or passed { client }.");
2024
2026
  }
2025
- const normalizedOrderId = React3.useMemo(() => (orderId || "").trim(), [orderId]);
2027
+ const normalizedOrderId = React10.useMemo(() => (orderId || "").trim(), [orderId]);
2026
2028
  const enabled = options.enabled ?? true;
2027
2029
  const poll = options.poll ?? false;
2028
2030
  const pollInterval = options.pollInterval ?? 5e3;
2029
- const requestIdRef = React3.useRef(0);
2030
- const previousStatusRef = React3.useRef(null);
2031
- const onStatusChangeRef = React3.useRef(options.onStatusChange);
2031
+ const requestIdRef = React10.useRef(0);
2032
+ const previousStatusRef = React10.useRef(null);
2033
+ const onStatusChangeRef = React10.useRef(options.onStatusChange);
2032
2034
  onStatusChangeRef.current = options.onStatusChange;
2033
- const cacheKey2 = React3.useMemo(
2035
+ const cacheKey2 = React10.useMemo(
2034
2036
  () => buildOrderCacheKey(client, normalizedOrderId),
2035
2037
  [client, normalizedOrderId]
2036
2038
  );
2037
2039
  const cached = orderCache.get(cacheKey2);
2038
- const [order, setOrder] = React3.useState(cached?.order ?? null);
2039
- const [isLoading, setIsLoading] = React3.useState(
2040
+ const [order, setOrder] = React10.useState(cached?.order ?? null);
2041
+ const [isLoading, setIsLoading] = React10.useState(
2040
2042
  enabled && normalizedOrderId.length > 0 && !cached
2041
2043
  );
2042
- const [error, setError] = React3.useState(null);
2043
- const load = React3.useCallback(
2044
+ const [error, setError] = React10.useState(null);
2045
+ const load = React10.useCallback(
2044
2046
  async (force = false) => {
2045
2047
  if (!enabled || normalizedOrderId.length === 0) {
2046
2048
  setOrder(null);
@@ -2099,11 +2101,11 @@ function useOrder(orderId, options = {}) {
2099
2101
  },
2100
2102
  [cacheKey2, client, enabled, normalizedOrderId]
2101
2103
  );
2102
- React3.useEffect(() => {
2104
+ React10.useEffect(() => {
2103
2105
  void load(false);
2104
2106
  }, [load]);
2105
2107
  const isTerminal = order ? TERMINAL_STATUSES.has(order.status) : false;
2106
- React3.useEffect(() => {
2108
+ React10.useEffect(() => {
2107
2109
  if (!poll || !enabled || normalizedOrderId.length === 0 || isTerminal) {
2108
2110
  return;
2109
2111
  }
@@ -2114,7 +2116,7 @@ function useOrder(orderId, options = {}) {
2114
2116
  window.clearInterval(timer);
2115
2117
  };
2116
2118
  }, [enabled, isTerminal, load, normalizedOrderId, poll, pollInterval]);
2117
- const refetch = React3.useCallback(async () => {
2119
+ const refetch = React10.useCallback(async () => {
2118
2120
  orderCache.delete(cacheKey2);
2119
2121
  await load(true);
2120
2122
  }, [cacheKey2, load]);
@@ -2165,10 +2167,10 @@ function useLocations(options = {}) {
2165
2167
  };
2166
2168
  }
2167
2169
  const client = options.client;
2168
- const [locations, setLocations] = React3.useState([]);
2169
- const [currentLocation, setCurrentLocationState] = React3.useState(null);
2170
- const [isLoading, setIsLoading] = React3.useState(true);
2171
- const setCurrentLocation = React3.useCallback(
2170
+ const [locations, setLocations] = React10.useState([]);
2171
+ const [currentLocation, setCurrentLocationState] = React10.useState(null);
2172
+ const [isLoading, setIsLoading] = React10.useState(true);
2173
+ const setCurrentLocation = React10.useCallback(
2172
2174
  (location) => {
2173
2175
  setCurrentLocationState(location);
2174
2176
  if (client) {
@@ -2178,7 +2180,7 @@ function useLocations(options = {}) {
2178
2180
  },
2179
2181
  [client]
2180
2182
  );
2181
- React3.useEffect(() => {
2183
+ React10.useEffect(() => {
2182
2184
  if (!client) {
2183
2185
  setLocations([]);
2184
2186
  setCurrentLocationState(null);
@@ -2282,14 +2284,14 @@ function useSearch(options = {}) {
2282
2284
  const minLength = Math.max(0, options.minLength ?? 2);
2283
2285
  const debounceMs = Math.max(0, options.debounceMs ?? 300);
2284
2286
  const limit = Math.max(1, options.limit ?? 20);
2285
- const [query, setQueryState] = React3.useState("");
2286
- const [results, setResults] = React3.useState([]);
2287
- const [isLoading, setIsLoading] = React3.useState(false);
2288
- const [error, setError] = React3.useState(null);
2289
- const requestIdRef = React3.useRef(0);
2290
- const timerRef = React3.useRef(null);
2287
+ const [query, setQueryState] = React10.useState("");
2288
+ const [results, setResults] = React10.useState([]);
2289
+ const [isLoading, setIsLoading] = React10.useState(false);
2290
+ const [error, setError] = React10.useState(null);
2291
+ const requestIdRef = React10.useRef(0);
2292
+ const timerRef = React10.useRef(null);
2291
2293
  const tagsSignature = options.tags?.join(",") ?? "";
2292
- React3.useEffect(() => {
2294
+ React10.useEffect(() => {
2293
2295
  if (timerRef.current) {
2294
2296
  clearTimeout(timerRef.current);
2295
2297
  timerRef.current = null;
@@ -2344,10 +2346,10 @@ function useSearch(options = {}) {
2344
2346
  }
2345
2347
  };
2346
2348
  }, [client, debounceMs, limit, minLength, options.category, options.taxonomy, tagsSignature, options.featured, options.in_stock, options.min_price, options.max_price, options.sort_by, options.sort_order, query]);
2347
- const setQuery = React3.useCallback((nextQuery) => {
2349
+ const setQuery = React10.useCallback((nextQuery) => {
2348
2350
  setQueryState(nextQuery);
2349
2351
  }, []);
2350
- const clear = React3.useCallback(() => {
2352
+ const clear = React10.useCallback(() => {
2351
2353
  requestIdRef.current += 1;
2352
2354
  if (timerRef.current) {
2353
2355
  clearTimeout(timerRef.current);
@@ -2438,34 +2440,34 @@ function useQuote(input, options = {}) {
2438
2440
  const autoRefresh = options.autoRefresh ?? true;
2439
2441
  const refreshBeforeExpiryMs = Math.max(0, options.refreshBeforeExpiryMs ?? 3e4);
2440
2442
  const locationId = client.getLocationId();
2441
- const requestIdRef = React3.useRef(0);
2442
- const debounceTimerRef = React3.useRef(null);
2443
+ const requestIdRef = React10.useRef(0);
2444
+ const debounceTimerRef = React10.useRef(null);
2443
2445
  const inputSignature = buildQuoteInputSignature(input);
2444
- const normalizedInput = React3.useMemo(() => {
2446
+ const normalizedInput = React10.useMemo(() => {
2445
2447
  if (!input) {
2446
2448
  return null;
2447
2449
  }
2448
2450
  const normalized = normalizeInput(input, locationId);
2449
2451
  return normalized.product_id.length > 0 ? normalized : null;
2450
2452
  }, [inputSignature, locationId]);
2451
- const cacheKey2 = React3.useMemo(
2453
+ const cacheKey2 = React10.useMemo(
2452
2454
  () => buildQuoteCacheKey(client, locationId, inputSignature),
2453
2455
  [client, inputSignature, locationId]
2454
2456
  );
2455
2457
  const cached = quoteCache.get(cacheKey2);
2456
- const [quote, setQuote] = React3.useState(cached?.quote ?? null);
2457
- const [isLoading, setIsLoading] = React3.useState(enabled && normalizedInput !== null && !cached);
2458
- const [error, setError] = React3.useState(null);
2459
- const [isExpired, setIsExpired] = React3.useState(isQuoteExpired(cached?.quote ?? null));
2460
- const [messages, setMessages] = React3.useState(cached?.quote?.ui_messages ?? []);
2461
- const quoteExpiryTimestamp = React3.useMemo(() => {
2458
+ const [quote, setQuote] = React10.useState(cached?.quote ?? null);
2459
+ const [isLoading, setIsLoading] = React10.useState(enabled && normalizedInput !== null && !cached);
2460
+ const [error, setError] = React10.useState(null);
2461
+ const [isExpired, setIsExpired] = React10.useState(isQuoteExpired(cached?.quote ?? null));
2462
+ const [messages, setMessages] = React10.useState(cached?.quote?.ui_messages ?? []);
2463
+ const quoteExpiryTimestamp = React10.useMemo(() => {
2462
2464
  if (!quote?.expires_at) {
2463
2465
  return Number.NaN;
2464
2466
  }
2465
2467
  const expiresAt = Date.parse(quote.expires_at);
2466
2468
  return Number.isFinite(expiresAt) ? expiresAt : Number.NaN;
2467
2469
  }, [quote?.expires_at]);
2468
- const load = React3.useCallback(
2470
+ const load = React10.useCallback(
2469
2471
  async (force = false) => {
2470
2472
  if (!enabled || !normalizedInput) {
2471
2473
  setQuote(null);
@@ -2525,7 +2527,7 @@ function useQuote(input, options = {}) {
2525
2527
  },
2526
2528
  [cacheKey2, client, enabled, normalizedInput]
2527
2529
  );
2528
- React3.useEffect(() => {
2530
+ React10.useEffect(() => {
2529
2531
  if (debounceTimerRef.current) {
2530
2532
  clearTimeout(debounceTimerRef.current);
2531
2533
  }
@@ -2544,7 +2546,7 @@ function useQuote(input, options = {}) {
2544
2546
  }
2545
2547
  };
2546
2548
  }, [load, cacheKey2, enabled, normalizedInput]);
2547
- const refresh = React3.useCallback(async () => {
2549
+ const refresh = React10.useCallback(async () => {
2548
2550
  if (!enabled || !normalizedInput) {
2549
2551
  return;
2550
2552
  }
@@ -2581,7 +2583,7 @@ function useQuote(input, options = {}) {
2581
2583
  }
2582
2584
  }
2583
2585
  }, [cacheKey2, client, enabled, load, normalizedInput, quote]);
2584
- React3.useEffect(() => {
2586
+ React10.useEffect(() => {
2585
2587
  if (!Number.isFinite(quoteExpiryTimestamp)) {
2586
2588
  setIsExpired(false);
2587
2589
  return;
@@ -2757,9 +2759,9 @@ function useValidateDiscount(options = {}) {
2757
2759
  if (!client) {
2758
2760
  throw new Error("useValidateDiscount must be used within CimplifyProvider or passed { client }.");
2759
2761
  }
2760
- const [isValidating, setIsValidating] = React3.useState(false);
2761
- const [error, setError] = React3.useState(null);
2762
- const validate = React3.useCallback(
2762
+ const [isValidating, setIsValidating] = React10.useState(false);
2763
+ const [error, setError] = React10.useState(null);
2764
+ const validate = React10.useCallback(
2763
2765
  async (code, orderSubtotal, locationId) => {
2764
2766
  setError(null);
2765
2767
  setIsValidating(true);
@@ -2806,7 +2808,7 @@ function useProductPrice(input) {
2806
2808
  compositePrice,
2807
2809
  bundleTotalPrice
2808
2810
  } = input;
2809
- return React3.useMemo(() => {
2811
+ return React10.useMemo(() => {
2810
2812
  let unitPrice;
2811
2813
  if (bundleTotalPrice != null) {
2812
2814
  unitPrice = bundleTotalPrice;
@@ -2852,6 +2854,84 @@ function useOrders(options = {}) {
2852
2854
  const { data, isLoading, error, refetch } = ordersQuery(options);
2853
2855
  return { orders: data ?? [], isLoading, error, refetch };
2854
2856
  }
2857
+ function useSubscriptions(options = {}) {
2858
+ const { client } = useCimplifyClient();
2859
+ const { status, enabled = true } = options;
2860
+ const [subscriptions, setSubscriptions] = React10.useState([]);
2861
+ const [isLoading, setIsLoading] = React10.useState(false);
2862
+ const [error, setError] = React10.useState(null);
2863
+ const fetch2 = React10.useCallback(async () => {
2864
+ if (!enabled) return;
2865
+ setIsLoading(true);
2866
+ setError(null);
2867
+ try {
2868
+ const result = await client.subscriptions.list();
2869
+ if (result.ok) {
2870
+ const filtered = status ? result.value.filter((s) => s.status === status) : result.value;
2871
+ setSubscriptions(filtered);
2872
+ } else {
2873
+ setError(result.error);
2874
+ }
2875
+ } catch (e) {
2876
+ setError(e);
2877
+ } finally {
2878
+ setIsLoading(false);
2879
+ }
2880
+ }, [client, enabled, status]);
2881
+ React10.useEffect(() => {
2882
+ void fetch2();
2883
+ }, [fetch2]);
2884
+ return { subscriptions, isLoading, error, refetch: fetch2 };
2885
+ }
2886
+ function useSubscription(id, options = {}) {
2887
+ const { client } = useCimplifyClient();
2888
+ const { enabled = true } = options;
2889
+ const normalizedId = (id || "").trim();
2890
+ const [subscription, setSubscription] = React10.useState(null);
2891
+ const [isLoading, setIsLoading] = React10.useState(false);
2892
+ const [error, setError] = React10.useState(null);
2893
+ const fetch2 = React10.useCallback(async () => {
2894
+ if (!enabled || !normalizedId) return;
2895
+ setIsLoading(true);
2896
+ setError(null);
2897
+ try {
2898
+ const result = await client.subscriptions.get(normalizedId);
2899
+ if (result.ok) {
2900
+ setSubscription(result.value);
2901
+ } else {
2902
+ setError(result.error);
2903
+ }
2904
+ } catch (e) {
2905
+ setError(e);
2906
+ } finally {
2907
+ setIsLoading(false);
2908
+ }
2909
+ }, [client, enabled, normalizedId]);
2910
+ React10.useEffect(() => {
2911
+ void fetch2();
2912
+ }, [fetch2]);
2913
+ const cancel = React10.useCallback(async (reason) => {
2914
+ if (!normalizedId) return;
2915
+ await client.subscriptions.cancel(normalizedId, reason);
2916
+ void fetch2();
2917
+ }, [client, normalizedId, fetch2]);
2918
+ const pause = React10.useCallback(async () => {
2919
+ if (!normalizedId) return;
2920
+ await client.subscriptions.pause(normalizedId);
2921
+ void fetch2();
2922
+ }, [client, normalizedId, fetch2]);
2923
+ const resume = React10.useCallback(async () => {
2924
+ if (!normalizedId) return;
2925
+ await client.subscriptions.resume(normalizedId);
2926
+ void fetch2();
2927
+ }, [client, normalizedId, fetch2]);
2928
+ const skipNext = React10.useCallback(async () => {
2929
+ if (!normalizedId) return;
2930
+ await client.subscriptions.skipNextRenewal(normalizedId);
2931
+ void fetch2();
2932
+ }, [client, normalizedId, fetch2]);
2933
+ return { subscription, isLoading, error, cancel, pause, resume, skipNext, refetch: fetch2 };
2934
+ }
2855
2935
 
2856
2936
  // src/react/hooks/use-services.ts
2857
2937
  var servicesQuery = createCachedQuery({
@@ -2949,7 +3029,7 @@ function useBookings(options = {}) {
2949
3029
  const context = useOptionalCimplifyClient();
2950
3030
  const client = options.client ?? context?.client;
2951
3031
  const { data, isLoading, error, refetch } = bookingsQuery(options);
2952
- const cancelBooking = React3.useCallback(
3032
+ const cancelBooking = React10.useCallback(
2953
3033
  async (bookingId, reason) => {
2954
3034
  if (!client) throw new Error("useBookings must be used within CimplifyProvider or passed { client }.");
2955
3035
  const result = await client.scheduling.cancelBooking({
@@ -3005,14 +3085,14 @@ function useBillingPlans(productId, options = {}) {
3005
3085
  throw new Error("useBillingPlans must be used within CimplifyProvider or passed { client }.");
3006
3086
  }
3007
3087
  const enabled = options.enabled ?? true;
3008
- const requestIdRef = React3.useRef(0);
3009
- const [plans, setPlans] = React3.useState([]);
3010
- const [isLoading, setIsLoading] = React3.useState(enabled && !!productId);
3011
- const [error, setError] = React3.useState(null);
3088
+ const requestIdRef = React10.useRef(0);
3089
+ const [plans, setPlans] = React10.useState([]);
3090
+ const [isLoading, setIsLoading] = React10.useState(enabled && !!productId);
3091
+ const [error, setError] = React10.useState(null);
3012
3092
  const customerId = options.customerId;
3013
3093
  const quantity = options.quantity;
3014
3094
  const orderValue = options.orderValue;
3015
- const load = React3.useCallback(
3095
+ const load = React10.useCallback(
3016
3096
  async (force = false) => {
3017
3097
  if (!enabled || !productId) {
3018
3098
  setPlans([]);
@@ -3047,17 +3127,17 @@ function useBillingPlans(productId, options = {}) {
3047
3127
  },
3048
3128
  [client, enabled, productId, customerId, quantity, orderValue]
3049
3129
  );
3050
- React3.useEffect(() => {
3130
+ React10.useEffect(() => {
3051
3131
  void load(false);
3052
3132
  }, [load]);
3053
- const refetch = React3.useCallback(async () => {
3133
+ const refetch = React10.useCallback(async () => {
3054
3134
  await load(true);
3055
3135
  }, [load]);
3056
- const subscriptionPlans = React3.useMemo(
3136
+ const subscriptionPlans = React10.useMemo(
3057
3137
  () => plans.filter((p) => p.plan_type === "subscription"),
3058
3138
  [plans]
3059
3139
  );
3060
- const installmentPlans = React3.useMemo(
3140
+ const installmentPlans = React10.useMemo(
3061
3141
  () => plans.filter((p) => p.plan_type === "installment"),
3062
3142
  [plans]
3063
3143
  );
@@ -3092,8 +3172,8 @@ function computeAvailableValues(variants, axes, selections) {
3092
3172
  }
3093
3173
  function useVariantSelector(options) {
3094
3174
  const { variants, axes } = options;
3095
- const [selectedValues, setSelectedValues] = React3.useState({});
3096
- const selectValue = React3.useCallback(
3175
+ const [selectedValues, setSelectedValues] = React10.useState({});
3176
+ const selectValue = React10.useCallback(
3097
3177
  (axisId, valueId) => {
3098
3178
  setSelectedValues((prev) => {
3099
3179
  if (prev[axisId] === valueId) {
@@ -3106,16 +3186,16 @@ function useVariantSelector(options) {
3106
3186
  },
3107
3187
  []
3108
3188
  );
3109
- const reset = React3.useCallback(() => setSelectedValues({}), []);
3110
- const selectedVariant = React3.useMemo(
3189
+ const reset = React10.useCallback(() => setSelectedValues({}), []);
3190
+ const selectedVariant = React10.useMemo(
3111
3191
  () => findMatchingVariant(variants, selectedValues),
3112
3192
  [variants, selectedValues]
3113
3193
  );
3114
- const variantImage = React3.useMemo(
3194
+ const variantImage = React10.useMemo(
3115
3195
  () => selectedVariant?.images?.[0] ?? null,
3116
3196
  [selectedVariant]
3117
3197
  );
3118
- const availableValues = React3.useMemo(
3198
+ const availableValues = React10.useMemo(
3119
3199
  () => computeAvailableValues(variants, axes, selectedValues),
3120
3200
  [variants, axes, selectedValues]
3121
3201
  );
@@ -3141,7 +3221,7 @@ function useActivityState(options = {}) {
3141
3221
  const context = useOptionalCimplifyClient();
3142
3222
  const client = options.client ?? context?.client;
3143
3223
  const { data, isLoading, error, refetch } = activityStateQuery(options);
3144
- const dismissMessage = React3.useCallback(
3224
+ const dismissMessage = React10.useCallback(
3145
3225
  async (code) => {
3146
3226
  if (!client) return;
3147
3227
  const result = await client.activity.dismissMessage(code);
@@ -3235,15 +3315,15 @@ function useBootstrap(options = {}) {
3235
3315
  const { data, isLoading, error, refetch } = bootstrapQuery(options);
3236
3316
  return { bootstrap: data, isLoading, error, refetch };
3237
3317
  }
3238
- var ElementsContext = React3.createContext({
3318
+ var ElementsContext = React10.createContext({
3239
3319
  elements: null,
3240
3320
  isReady: false
3241
3321
  });
3242
3322
  function useElements() {
3243
- return React3.useContext(ElementsContext).elements;
3323
+ return React10.useContext(ElementsContext).elements;
3244
3324
  }
3245
3325
  function useElementsReady() {
3246
- return React3.useContext(ElementsContext).isReady;
3326
+ return React10.useContext(ElementsContext).isReady;
3247
3327
  }
3248
3328
  function ElementsProvider({
3249
3329
  client,
@@ -3251,10 +3331,10 @@ function ElementsProvider({
3251
3331
  options,
3252
3332
  children
3253
3333
  }) {
3254
- const [elements, setElements] = React3.useState(null);
3255
- const [isReady, setIsReady] = React3.useState(false);
3256
- const initialOptionsRef = React3.useRef(options);
3257
- React3.useEffect(() => {
3334
+ const [elements, setElements] = React10.useState(null);
3335
+ const [isReady, setIsReady] = React10.useState(false);
3336
+ const initialOptionsRef = React10.useRef(options);
3337
+ React10.useEffect(() => {
3258
3338
  let cancelled = false;
3259
3339
  let instance = null;
3260
3340
  setIsReady(false);
@@ -3295,20 +3375,20 @@ function AuthElement({
3295
3375
  onRequiresOtp,
3296
3376
  onError
3297
3377
  }) {
3298
- const containerRef = React3.useRef(null);
3299
- const elementRef = React3.useRef(null);
3378
+ const containerRef = React10.useRef(null);
3379
+ const elementRef = React10.useRef(null);
3300
3380
  const elements = useElements();
3301
- const onReadyRef = React3.useRef(onReady);
3302
- const onAuthenticatedRef = React3.useRef(onAuthenticated);
3303
- const onRequiresOtpRef = React3.useRef(onRequiresOtp);
3304
- const onErrorRef = React3.useRef(onError);
3305
- React3.useEffect(() => {
3381
+ const onReadyRef = React10.useRef(onReady);
3382
+ const onAuthenticatedRef = React10.useRef(onAuthenticated);
3383
+ const onRequiresOtpRef = React10.useRef(onRequiresOtp);
3384
+ const onErrorRef = React10.useRef(onError);
3385
+ React10.useEffect(() => {
3306
3386
  onReadyRef.current = onReady;
3307
3387
  onAuthenticatedRef.current = onAuthenticated;
3308
3388
  onRequiresOtpRef.current = onRequiresOtp;
3309
3389
  onErrorRef.current = onError;
3310
3390
  }, [onReady, onAuthenticated, onRequiresOtp, onError]);
3311
- React3.useEffect(() => {
3391
+ React10.useEffect(() => {
3312
3392
  if (!elements || !containerRef.current) return;
3313
3393
  const element = elements.create(chunk2CGA3MUW_js.ELEMENT_TYPES.AUTH, { prefillEmail });
3314
3394
  elementRef.current = element;
@@ -3338,18 +3418,18 @@ function AddressElement({
3338
3418
  onChange,
3339
3419
  onError
3340
3420
  }) {
3341
- const containerRef = React3.useRef(null);
3342
- const elementRef = React3.useRef(null);
3421
+ const containerRef = React10.useRef(null);
3422
+ const elementRef = React10.useRef(null);
3343
3423
  const elements = useElements();
3344
- const onReadyRef = React3.useRef(onReady);
3345
- const onChangeRef = React3.useRef(onChange);
3346
- const onErrorRef = React3.useRef(onError);
3347
- React3.useEffect(() => {
3424
+ const onReadyRef = React10.useRef(onReady);
3425
+ const onChangeRef = React10.useRef(onChange);
3426
+ const onErrorRef = React10.useRef(onError);
3427
+ React10.useEffect(() => {
3348
3428
  onReadyRef.current = onReady;
3349
3429
  onChangeRef.current = onChange;
3350
3430
  onErrorRef.current = onError;
3351
3431
  }, [onReady, onChange, onError]);
3352
- React3.useEffect(() => {
3432
+ React10.useEffect(() => {
3353
3433
  if (!elements || !containerRef.current) return;
3354
3434
  const element = elements.create(chunk2CGA3MUW_js.ELEMENT_TYPES.ADDRESS, { mode });
3355
3435
  elementRef.current = element;
@@ -3376,18 +3456,18 @@ function PaymentElement({
3376
3456
  onChange,
3377
3457
  onError
3378
3458
  }) {
3379
- const containerRef = React3.useRef(null);
3380
- const elementRef = React3.useRef(null);
3459
+ const containerRef = React10.useRef(null);
3460
+ const elementRef = React10.useRef(null);
3381
3461
  const elements = useElements();
3382
- const onReadyRef = React3.useRef(onReady);
3383
- const onChangeRef = React3.useRef(onChange);
3384
- const onErrorRef = React3.useRef(onError);
3385
- React3.useEffect(() => {
3462
+ const onReadyRef = React10.useRef(onReady);
3463
+ const onChangeRef = React10.useRef(onChange);
3464
+ const onErrorRef = React10.useRef(onError);
3465
+ React10.useEffect(() => {
3386
3466
  onReadyRef.current = onReady;
3387
3467
  onChangeRef.current = onChange;
3388
3468
  onErrorRef.current = onError;
3389
3469
  }, [onReady, onChange, onError]);
3390
- React3.useEffect(() => {
3470
+ React10.useEffect(() => {
3391
3471
  if (!elements || !containerRef.current) return;
3392
3472
  const element = elements.create(chunk2CGA3MUW_js.ELEMENT_TYPES.PAYMENT, { amount, currency });
3393
3473
  elementRef.current = element;
@@ -3407,8 +3487,8 @@ function PaymentElement({
3407
3487
  }
3408
3488
  function useCheckout() {
3409
3489
  const elements = useElements();
3410
- const [isLoading, setIsLoading] = React3.useState(false);
3411
- const submit = React3.useCallback(
3490
+ const [isLoading, setIsLoading] = React10.useState(false);
3491
+ const submit = React10.useCallback(
3412
3492
  async (data) => {
3413
3493
  if (!elements) {
3414
3494
  return { success: false, error: { code: "NO_ELEMENTS", message: "Elements not initialized" } };
@@ -3422,7 +3502,7 @@ function useCheckout() {
3422
3502
  },
3423
3503
  [elements]
3424
3504
  );
3425
- const process = React3.useCallback(
3505
+ const process = React10.useCallback(
3426
3506
  async (options) => {
3427
3507
  if (!elements) {
3428
3508
  return {
@@ -3516,13 +3596,13 @@ function VariantSelector({
3516
3596
  className,
3517
3597
  classNames
3518
3598
  }) {
3519
- const [axisSelections, setAxisSelections] = React3.useState({});
3520
- const initialized = React3.useRef(false);
3521
- const idPrefix = React3.useId();
3522
- React3.useEffect(() => {
3599
+ const [axisSelections, setAxisSelections] = React10.useState({});
3600
+ const initialized = React10.useRef(false);
3601
+ const idPrefix = React10.useId();
3602
+ React10.useEffect(() => {
3523
3603
  initialized.current = false;
3524
3604
  }, [variants]);
3525
- React3.useEffect(() => {
3605
+ React10.useEffect(() => {
3526
3606
  if (initialized.current) return;
3527
3607
  if (!variants || variants.length === 0) return;
3528
3608
  const defaultVariant = variants.find((v) => v.is_default) || variants[0];
@@ -3537,7 +3617,7 @@ function VariantSelector({
3537
3617
  setAxisSelections(initial);
3538
3618
  }
3539
3619
  }, [variants, onVariantChange]);
3540
- React3.useEffect(() => {
3620
+ React10.useEffect(() => {
3541
3621
  if (!initialized.current) return;
3542
3622
  if (!variantAxes || variantAxes.length === 0) return;
3543
3623
  const match = variants.find((v) => {
@@ -3657,7 +3737,7 @@ function VariantSelector({
3657
3737
  {
3658
3738
  "data-cimplify-variant-name": true,
3659
3739
  className: cn("flex-1 min-w-0 text-sm", classNames?.name),
3660
- children: chunk4JSRPSNA_js.getVariantDisplayName(variant, productName)
3740
+ children: chunkR4AKAGZQ_js.getVariantDisplayName(variant, productName)
3661
3741
  }
3662
3742
  ),
3663
3743
  /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-variant-pricing": true, className: cn("text-sm text-muted-foreground", classNames?.pricing), children: [
@@ -3680,12 +3760,12 @@ function AddOnSelector({
3680
3760
  className,
3681
3761
  classNames
3682
3762
  }) {
3683
- const selectedSet = React3.useMemo(() => new Set(selectedOptions), [selectedOptions]);
3684
- const isOptionSelected = React3.useCallback(
3763
+ const selectedSet = React10.useMemo(() => new Set(selectedOptions), [selectedOptions]);
3764
+ const isOptionSelected = React10.useCallback(
3685
3765
  (optionId) => selectedSet.has(optionId),
3686
3766
  [selectedSet]
3687
3767
  );
3688
- const handleCheckedChange = React3.useCallback(
3768
+ const handleCheckedChange = React10.useCallback(
3689
3769
  (addOn, optionId, checked) => {
3690
3770
  const isSelected = selectedSet.has(optionId);
3691
3771
  if (addOn.is_mutually_exclusive || !addOn.is_multiple_allowed) {
@@ -3861,9 +3941,9 @@ function BundleSelector({
3861
3941
  className,
3862
3942
  classNames
3863
3943
  }) {
3864
- const [variantChoices, setVariantChoices] = React3.useState({});
3865
- const lastComponentIds = React3.useRef("");
3866
- React3.useEffect(() => {
3944
+ const [variantChoices, setVariantChoices] = React10.useState({});
3945
+ const lastComponentIds = React10.useRef("");
3946
+ React10.useEffect(() => {
3867
3947
  const ids = components.map((c) => c.id).sort().join();
3868
3948
  if (ids === lastComponentIds.current) return;
3869
3949
  lastComponentIds.current = ids;
@@ -3880,20 +3960,20 @@ function BundleSelector({
3880
3960
  }
3881
3961
  setVariantChoices(defaults);
3882
3962
  }, [components]);
3883
- const selections = React3.useMemo(() => {
3963
+ const selections = React10.useMemo(() => {
3884
3964
  return components.map((comp) => ({
3885
3965
  component_id: comp.id,
3886
3966
  variant_id: variantChoices[comp.id],
3887
3967
  quantity: comp.quantity
3888
3968
  }));
3889
3969
  }, [components, variantChoices]);
3890
- React3.useEffect(() => {
3970
+ React10.useEffect(() => {
3891
3971
  onSelectionsChange(selections);
3892
3972
  }, [selections, onSelectionsChange]);
3893
- React3.useEffect(() => {
3973
+ React10.useEffect(() => {
3894
3974
  onReady?.(components.length > 0 && selections.length > 0);
3895
3975
  }, [components, selections, onReady]);
3896
- const totalPrice = React3.useMemo(() => {
3976
+ const totalPrice = React10.useMemo(() => {
3897
3977
  if (pricingType === "fixed" && bundlePrice) {
3898
3978
  return chunkPEDLCL72_js.parsePrice(bundlePrice);
3899
3979
  }
@@ -3908,10 +3988,10 @@ function BundleSelector({
3908
3988
  }
3909
3989
  return componentsTotal;
3910
3990
  }, [components, variantChoices, pricingType, bundlePrice, discountValue]);
3911
- React3.useEffect(() => {
3991
+ React10.useEffect(() => {
3912
3992
  onPriceChange?.(totalPrice);
3913
3993
  }, [totalPrice, onPriceChange]);
3914
- const handleVariantChange = React3.useCallback(
3994
+ const handleVariantChange = React10.useCallback(
3915
3995
  (componentId, variantId) => {
3916
3996
  setVariantChoices((prev) => ({ ...prev, [componentId]: variantId }));
3917
3997
  },
@@ -3992,9 +4072,9 @@ function BundleComponentCard({
3992
4072
  onVariantChange,
3993
4073
  classNames
3994
4074
  }) {
3995
- const idPrefix = React3.useId();
4075
+ const idPrefix = React10.useId();
3996
4076
  const showVariantPicker = component.allow_variant_choice && component.available_variants.length > 1;
3997
- const displayPrice = React3.useMemo(
4077
+ const displayPrice = React10.useMemo(
3998
4078
  () => getComponentPrice(component, selectedVariantId),
3999
4079
  [component, selectedVariantId]
4000
4080
  );
@@ -4142,11 +4222,11 @@ function CompositeSelector({
4142
4222
  classNames
4143
4223
  }) {
4144
4224
  const { client } = useCimplifyClient();
4145
- const [groupSelections, setGroupSelections] = React3.useState({});
4146
- const [priceResult, setPriceResult] = React3.useState(null);
4147
- const [isPriceLoading, setIsPriceLoading] = React3.useState(false);
4148
- const [priceError, setPriceError] = React3.useState(false);
4149
- const selections = React3.useMemo(() => {
4225
+ const [groupSelections, setGroupSelections] = React10.useState({});
4226
+ const [priceResult, setPriceResult] = React10.useState(null);
4227
+ const [isPriceLoading, setIsPriceLoading] = React10.useState(false);
4228
+ const [priceError, setPriceError] = React10.useState(false);
4229
+ const selections = React10.useMemo(() => {
4150
4230
  const result = [];
4151
4231
  for (const groupSels of Object.values(groupSelections)) {
4152
4232
  for (const [componentId, qty] of Object.entries(groupSels)) {
@@ -4157,13 +4237,13 @@ function CompositeSelector({
4157
4237
  }
4158
4238
  return result;
4159
4239
  }, [groupSelections]);
4160
- React3.useEffect(() => {
4240
+ React10.useEffect(() => {
4161
4241
  onSelectionsChange(selections);
4162
4242
  }, [selections, onSelectionsChange]);
4163
- React3.useEffect(() => {
4243
+ React10.useEffect(() => {
4164
4244
  onPriceChange?.(priceResult);
4165
4245
  }, [priceResult, onPriceChange]);
4166
- const allGroupsSatisfied = React3.useMemo(() => {
4246
+ const allGroupsSatisfied = React10.useMemo(() => {
4167
4247
  for (const group of groups) {
4168
4248
  const groupSels = groupSelections[group.id] || {};
4169
4249
  const totalSelected = Object.values(groupSels).reduce((sum, q) => sum + q, 0);
@@ -4171,17 +4251,17 @@ function CompositeSelector({
4171
4251
  }
4172
4252
  return true;
4173
4253
  }, [groups, groupSelections]);
4174
- const sortedGroups = React3.useMemo(
4254
+ const sortedGroups = React10.useMemo(
4175
4255
  () => [...groups].sort((a, b) => a.display_order - b.display_order).map((group) => ({
4176
4256
  ...group,
4177
4257
  _sortedComponents: group.components.filter((component) => component.is_available && !component.is_archived).sort((a, b) => a.display_order - b.display_order)
4178
4258
  })),
4179
4259
  [groups]
4180
4260
  );
4181
- React3.useEffect(() => {
4261
+ React10.useEffect(() => {
4182
4262
  onReady?.(allGroupsSatisfied);
4183
4263
  }, [allGroupsSatisfied, onReady]);
4184
- React3.useEffect(() => {
4264
+ React10.useEffect(() => {
4185
4265
  if (skipPriceFetch || !allGroupsSatisfied || selections.length === 0) return;
4186
4266
  let cancelled = false;
4187
4267
  const timer = setTimeout(() => {
@@ -4208,7 +4288,7 @@ function CompositeSelector({
4208
4288
  clearTimeout(timer);
4209
4289
  };
4210
4290
  }, [selections, allGroupsSatisfied, compositeId, client, skipPriceFetch]);
4211
- const toggleComponent = React3.useCallback(
4291
+ const toggleComponent = React10.useCallback(
4212
4292
  (group, component) => {
4213
4293
  setGroupSelections((prev) => {
4214
4294
  const groupSels = { ...prev[group.id] || {} };
@@ -4236,7 +4316,7 @@ function CompositeSelector({
4236
4316
  },
4237
4317
  []
4238
4318
  );
4239
- const updateQuantity = React3.useCallback(
4319
+ const updateQuantity = React10.useCallback(
4240
4320
  (group, componentId, newValue) => {
4241
4321
  setGroupSelections((prev) => {
4242
4322
  const groupSels = { ...prev[group.id] || {} };
@@ -4775,6 +4855,880 @@ function VolumePricing({
4775
4855
  }
4776
4856
  );
4777
4857
  }
4858
+ function CustomerInputFields({
4859
+ fields,
4860
+ values,
4861
+ onChange,
4862
+ onFileUpload,
4863
+ className,
4864
+ classNames
4865
+ }) {
4866
+ const clientContext = useOptionalCimplifyClient();
4867
+ if (fields.length === 0) return null;
4868
+ const sorted = [...fields].sort((a, b) => a.display_order - b.display_order);
4869
+ const setValue = React10.useCallback(
4870
+ (fieldId, value) => {
4871
+ onChange({ ...values, [fieldId]: value });
4872
+ },
4873
+ [values, onChange]
4874
+ );
4875
+ const defaultFileUpload = React10.useCallback(
4876
+ async (file) => {
4877
+ if (onFileUpload) return onFileUpload(file, {});
4878
+ if (!clientContext?.client) throw new Error("No upload provider available");
4879
+ const result = await clientContext.client.uploads.upload(file);
4880
+ if (!result.ok) throw new Error(result.error.message);
4881
+ return result.value.url;
4882
+ },
4883
+ [onFileUpload, clientContext]
4884
+ );
4885
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-customer-inputs": true, className: cn("space-y-4", className, classNames?.root), children: sorted.map((field) => /* @__PURE__ */ jsxRuntime.jsx(
4886
+ InputField,
4887
+ {
4888
+ field,
4889
+ value: values[field.id],
4890
+ onValueChange: (value) => setValue(field.id, value),
4891
+ onFileUpload: onFileUpload ?? (clientContext?.client ? (_file, _field) => defaultFileUpload(_file) : void 0),
4892
+ classNames
4893
+ },
4894
+ field.id
4895
+ )) });
4896
+ }
4897
+ function InputField({
4898
+ field,
4899
+ value,
4900
+ onValueChange,
4901
+ onFileUpload,
4902
+ classNames
4903
+ }) {
4904
+ const hasPriceAdjustment = field.price_adjustment != null && chunkPEDLCL72_js.parsePrice(field.price_adjustment) > 0;
4905
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-customer-input": true, "data-field-type": field.field_type, className: classNames?.field, children: [
4906
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-1.5", children: [
4907
+ /* @__PURE__ */ jsxRuntime.jsx("label", { className: cn("text-sm font-semibold", classNames?.label), children: field.name }),
4908
+ field.is_required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-xs text-destructive", classNames?.required), children: "Required" }),
4909
+ hasPriceAdjustment && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("text-xs text-muted-foreground", classNames?.priceAdjustment), children: [
4910
+ "+",
4911
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: field.price_adjustment })
4912
+ ] })
4913
+ ] }),
4914
+ field.help_text && /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-xs text-muted-foreground mb-1.5", classNames?.helpText), children: field.help_text }),
4915
+ /* @__PURE__ */ jsxRuntime.jsx(
4916
+ FieldInput,
4917
+ {
4918
+ field,
4919
+ value,
4920
+ onValueChange,
4921
+ onFileUpload,
4922
+ classNames
4923
+ }
4924
+ )
4925
+ ] });
4926
+ }
4927
+ function FieldInput({
4928
+ field,
4929
+ value,
4930
+ onValueChange,
4931
+ onFileUpload,
4932
+ classNames
4933
+ }) {
4934
+ const inputClass = cn(
4935
+ "w-full rounded-md border border-input bg-background px-3 py-2 text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring",
4936
+ classNames?.input
4937
+ );
4938
+ switch (field.field_type) {
4939
+ case chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.Text:
4940
+ case chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.Url:
4941
+ return /* @__PURE__ */ jsxRuntime.jsx(
4942
+ "input",
4943
+ {
4944
+ type: field.field_type === chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.Url ? "url" : "text",
4945
+ value: typeof value === "string" ? value : "",
4946
+ onChange: (e) => onValueChange(e.target.value),
4947
+ placeholder: field.placeholder,
4948
+ required: field.is_required,
4949
+ maxLength: field.validation?.max_length ?? void 0,
4950
+ className: inputClass
4951
+ }
4952
+ );
4953
+ case chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.Textarea:
4954
+ return /* @__PURE__ */ jsxRuntime.jsx(
4955
+ "textarea",
4956
+ {
4957
+ value: typeof value === "string" ? value : "",
4958
+ onChange: (e) => onValueChange(e.target.value),
4959
+ placeholder: field.placeholder,
4960
+ required: field.is_required,
4961
+ maxLength: field.validation?.max_length ?? void 0,
4962
+ rows: 3,
4963
+ className: cn(inputClass, "resize-none", classNames?.textarea)
4964
+ }
4965
+ );
4966
+ case chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.Number:
4967
+ return /* @__PURE__ */ jsxRuntime.jsx(
4968
+ "input",
4969
+ {
4970
+ type: "number",
4971
+ value: typeof value === "number" ? value : "",
4972
+ onChange: (e) => onValueChange(e.target.value ? parseFloat(e.target.value) : void 0),
4973
+ placeholder: field.placeholder,
4974
+ required: field.is_required,
4975
+ min: field.validation?.min_value ?? void 0,
4976
+ max: field.validation?.max_value ?? void 0,
4977
+ className: inputClass
4978
+ }
4979
+ );
4980
+ case chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.Select:
4981
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4982
+ "select",
4983
+ {
4984
+ value: typeof value === "string" ? value : "",
4985
+ onChange: (e) => onValueChange(e.target.value || void 0),
4986
+ required: field.is_required,
4987
+ className: cn(inputClass, classNames?.select),
4988
+ children: [
4989
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: field.placeholder || "Select..." }),
4990
+ (field.options || []).map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: opt, children: opt }, opt))
4991
+ ]
4992
+ }
4993
+ );
4994
+ case chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.Radio:
4995
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("space-y-2", classNames?.radioGroup), children: (field.options || []).map((opt) => /* @__PURE__ */ jsxRuntime.jsxs(
4996
+ "label",
4997
+ {
4998
+ className: cn(
4999
+ "flex items-center gap-2 text-sm cursor-pointer",
5000
+ classNames?.radioOption
5001
+ ),
5002
+ children: [
5003
+ /* @__PURE__ */ jsxRuntime.jsx(
5004
+ "input",
5005
+ {
5006
+ type: "radio",
5007
+ name: field.id,
5008
+ value: opt,
5009
+ checked: value === opt,
5010
+ onChange: () => onValueChange(opt),
5011
+ className: "accent-primary"
5012
+ }
5013
+ ),
5014
+ opt
5015
+ ]
5016
+ },
5017
+ opt
5018
+ )) });
5019
+ case chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.Checkbox:
5020
+ return /* @__PURE__ */ jsxRuntime.jsxs("label", { className: cn("flex items-center gap-2 text-sm cursor-pointer", classNames?.checkboxLabel), children: [
5021
+ /* @__PURE__ */ jsxRuntime.jsx(
5022
+ "input",
5023
+ {
5024
+ type: "checkbox",
5025
+ checked: value === true,
5026
+ onChange: (e) => onValueChange(e.target.checked),
5027
+ className: "accent-primary w-4 h-4"
5028
+ }
5029
+ ),
5030
+ field.placeholder || field.name
5031
+ ] });
5032
+ case chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.Color:
5033
+ return /* @__PURE__ */ jsxRuntime.jsx(
5034
+ "input",
5035
+ {
5036
+ type: "color",
5037
+ value: typeof value === "string" ? value : "#000000",
5038
+ onChange: (e) => onValueChange(e.target.value),
5039
+ className: cn("w-12 h-10 rounded-md border border-input cursor-pointer", classNames?.colorInput)
5040
+ }
5041
+ );
5042
+ case chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.Date:
5043
+ return /* @__PURE__ */ jsxRuntime.jsx(
5044
+ "input",
5045
+ {
5046
+ type: "date",
5047
+ value: typeof value === "string" ? value : "",
5048
+ onChange: (e) => onValueChange(e.target.value || void 0),
5049
+ required: field.is_required,
5050
+ className: inputClass
5051
+ }
5052
+ );
5053
+ case chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.File:
5054
+ case chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.Image:
5055
+ return /* @__PURE__ */ jsxRuntime.jsx(
5056
+ FileUploadInput,
5057
+ {
5058
+ field,
5059
+ value,
5060
+ onValueChange,
5061
+ onFileUpload,
5062
+ classNames
5063
+ }
5064
+ );
5065
+ case chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.Email:
5066
+ return /* @__PURE__ */ jsxRuntime.jsx(
5067
+ "input",
5068
+ {
5069
+ type: "email",
5070
+ value: typeof value === "string" ? value : "",
5071
+ onChange: (e) => onValueChange(e.target.value),
5072
+ placeholder: field.placeholder || "email@example.com",
5073
+ required: field.is_required,
5074
+ className: inputClass
5075
+ }
5076
+ );
5077
+ case chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.DateTime: {
5078
+ const dtLocalValue = typeof value === "string" && value.includes("T") ? value.slice(0, 16) : typeof value === "string" ? value : "";
5079
+ return /* @__PURE__ */ jsxRuntime.jsx(
5080
+ "input",
5081
+ {
5082
+ type: "datetime-local",
5083
+ value: dtLocalValue,
5084
+ onChange: (e) => {
5085
+ if (!e.target.value) {
5086
+ onValueChange(void 0);
5087
+ return;
5088
+ }
5089
+ const date = new Date(e.target.value);
5090
+ onValueChange(Number.isNaN(date.getTime()) ? e.target.value : date.toISOString());
5091
+ },
5092
+ required: field.is_required,
5093
+ className: inputClass
5094
+ }
5095
+ );
5096
+ }
5097
+ case chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.Time:
5098
+ return /* @__PURE__ */ jsxRuntime.jsx(
5099
+ "input",
5100
+ {
5101
+ type: "time",
5102
+ value: typeof value === "string" ? value : "",
5103
+ onChange: (e) => onValueChange(e.target.value || void 0),
5104
+ required: field.is_required,
5105
+ className: inputClass
5106
+ }
5107
+ );
5108
+ case chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.MultiSelect:
5109
+ return /* @__PURE__ */ jsxRuntime.jsx(
5110
+ MultiSelectInput,
5111
+ {
5112
+ field,
5113
+ value,
5114
+ onValueChange,
5115
+ classNames
5116
+ }
5117
+ );
5118
+ case chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.DateRange:
5119
+ return /* @__PURE__ */ jsxRuntime.jsx(
5120
+ DateRangeInput,
5121
+ {
5122
+ field,
5123
+ value,
5124
+ onValueChange,
5125
+ classNames,
5126
+ inputClass
5127
+ }
5128
+ );
5129
+ case chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.Address:
5130
+ return /* @__PURE__ */ jsxRuntime.jsx(
5131
+ AddressInput,
5132
+ {
5133
+ field,
5134
+ value,
5135
+ onValueChange,
5136
+ classNames,
5137
+ inputClass
5138
+ }
5139
+ );
5140
+ case chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.Location:
5141
+ return /* @__PURE__ */ jsxRuntime.jsx(
5142
+ LocationInput,
5143
+ {
5144
+ field,
5145
+ value,
5146
+ onValueChange,
5147
+ classNames,
5148
+ inputClass
5149
+ }
5150
+ );
5151
+ case chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.Phone:
5152
+ return /* @__PURE__ */ jsxRuntime.jsx(
5153
+ PhoneInput,
5154
+ {
5155
+ field,
5156
+ value,
5157
+ onValueChange,
5158
+ classNames,
5159
+ inputClass
5160
+ }
5161
+ );
5162
+ case chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.Signature:
5163
+ return /* @__PURE__ */ jsxRuntime.jsx(
5164
+ SignatureInput,
5165
+ {
5166
+ field,
5167
+ value,
5168
+ onValueChange,
5169
+ classNames
5170
+ }
5171
+ );
5172
+ default:
5173
+ return /* @__PURE__ */ jsxRuntime.jsx(
5174
+ "input",
5175
+ {
5176
+ type: "text",
5177
+ value: typeof value === "string" ? value : "",
5178
+ onChange: (e) => onValueChange(e.target.value),
5179
+ placeholder: field.placeholder,
5180
+ className: inputClass
5181
+ }
5182
+ );
5183
+ }
5184
+ }
5185
+ function FileUploadInput({
5186
+ field,
5187
+ value,
5188
+ onValueChange,
5189
+ onFileUpload,
5190
+ classNames
5191
+ }) {
5192
+ const [isUploading, setIsUploading] = React10__default.default.useState(false);
5193
+ const fileUrl = typeof value === "string" ? value : void 0;
5194
+ const acceptedFormats = field.validation?.accepted_formats;
5195
+ const accept = acceptedFormats ? acceptedFormats.map((f) => `.${f}`).join(",") : field.field_type === chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.Image ? "image/*" : void 0;
5196
+ const handleFile = async (file) => {
5197
+ if (!onFileUpload) return;
5198
+ if (field.validation?.max_size_mb) {
5199
+ const maxBytes = field.validation.max_size_mb * 1024 * 1024;
5200
+ if (file.size > maxBytes) {
5201
+ return;
5202
+ }
5203
+ }
5204
+ setIsUploading(true);
5205
+ try {
5206
+ const url = await onFileUpload(file, field);
5207
+ onValueChange(url);
5208
+ } finally {
5209
+ setIsUploading(false);
5210
+ }
5211
+ };
5212
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("space-y-2", classNames?.fileInput), children: fileUrl ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
5213
+ field.field_type === chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.Image && /* @__PURE__ */ jsxRuntime.jsx("img", { src: fileUrl, alt: "Uploaded", className: "w-16 h-16 object-cover rounded-md border border-border" }),
5214
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-foreground truncate", children: fileUrl.split("/").pop() }) }),
5215
+ /* @__PURE__ */ jsxRuntime.jsx(
5216
+ "button",
5217
+ {
5218
+ type: "button",
5219
+ onClick: () => onValueChange(void 0),
5220
+ className: "text-xs text-muted-foreground hover:text-destructive transition-colors",
5221
+ children: "Remove"
5222
+ }
5223
+ )
5224
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex flex-col items-center justify-center w-full h-24 border-2 border-dashed border-border rounded-lg cursor-pointer hover:border-primary/40 transition-colors", children: [
5225
+ /* @__PURE__ */ jsxRuntime.jsx(
5226
+ "input",
5227
+ {
5228
+ type: "file",
5229
+ accept,
5230
+ onChange: (e) => {
5231
+ const file = e.target.files?.[0];
5232
+ if (file) void handleFile(file);
5233
+ },
5234
+ className: "hidden",
5235
+ disabled: isUploading
5236
+ }
5237
+ ),
5238
+ isUploading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Uploading..." }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5239
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: field.placeholder || `Upload ${field.field_type === chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.Image ? "image" : "file"}` }),
5240
+ acceptedFormats && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground/60 mt-1", children: [
5241
+ acceptedFormats.map((f) => f.toUpperCase()).join(", "),
5242
+ field.validation?.max_size_mb && ` \xB7 Max ${field.validation.max_size_mb}MB`
5243
+ ] })
5244
+ ] })
5245
+ ] }) });
5246
+ }
5247
+ function MultiSelectInput({
5248
+ field,
5249
+ value,
5250
+ onValueChange,
5251
+ classNames
5252
+ }) {
5253
+ const selected = Array.isArray(value) ? value : [];
5254
+ const options = field.options || [];
5255
+ const maxSelections = field.validation?.max_selections;
5256
+ const toggle = (opt) => {
5257
+ const next = selected.includes(opt) ? selected.filter((s) => s !== opt) : maxSelections && selected.length >= maxSelections ? selected : [...selected, opt];
5258
+ onValueChange(next.length > 0 ? next : void 0);
5259
+ };
5260
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-2", classNames?.multiSelectGroup), children: [
5261
+ options.map((opt) => /* @__PURE__ */ jsxRuntime.jsxs(
5262
+ "label",
5263
+ {
5264
+ className: cn(
5265
+ "flex items-center gap-2 text-sm cursor-pointer",
5266
+ classNames?.multiSelectOption
5267
+ ),
5268
+ children: [
5269
+ /* @__PURE__ */ jsxRuntime.jsx(
5270
+ "input",
5271
+ {
5272
+ type: "checkbox",
5273
+ checked: selected.includes(opt),
5274
+ onChange: () => toggle(opt),
5275
+ className: "accent-primary w-4 h-4"
5276
+ }
5277
+ ),
5278
+ opt
5279
+ ]
5280
+ },
5281
+ opt
5282
+ )),
5283
+ maxSelections && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground", children: [
5284
+ selected.length,
5285
+ "/",
5286
+ maxSelections,
5287
+ " selected"
5288
+ ] })
5289
+ ] });
5290
+ }
5291
+ function DateRangeInput({
5292
+ field,
5293
+ value,
5294
+ onValueChange,
5295
+ classNames,
5296
+ inputClass
5297
+ }) {
5298
+ const range = value && typeof value === "object" ? value : {};
5299
+ const update = (key, v) => {
5300
+ const next = { ...range, [key]: v };
5301
+ onValueChange(next.start || next.end ? next : void 0);
5302
+ };
5303
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("grid grid-cols-2 gap-3", classNames?.dateRangeInput), children: [
5304
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5305
+ /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-xs text-muted-foreground mb-1 block", children: "Start" }),
5306
+ /* @__PURE__ */ jsxRuntime.jsx(
5307
+ "input",
5308
+ {
5309
+ type: "date",
5310
+ value: range.start || "",
5311
+ onChange: (e) => update("start", e.target.value),
5312
+ required: field.is_required,
5313
+ className: inputClass
5314
+ }
5315
+ )
5316
+ ] }),
5317
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5318
+ /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-xs text-muted-foreground mb-1 block", children: "End" }),
5319
+ /* @__PURE__ */ jsxRuntime.jsx(
5320
+ "input",
5321
+ {
5322
+ type: "date",
5323
+ value: range.end || "",
5324
+ onChange: (e) => update("end", e.target.value),
5325
+ required: field.is_required,
5326
+ className: inputClass
5327
+ }
5328
+ )
5329
+ ] })
5330
+ ] });
5331
+ }
5332
+ function AddressInput({
5333
+ field,
5334
+ value,
5335
+ onValueChange,
5336
+ classNames,
5337
+ inputClass
5338
+ }) {
5339
+ const clientContext = useOptionalCimplifyClient();
5340
+ const addr = value && typeof value === "object" ? value : null;
5341
+ const [inputText, setInputText] = React10__default.default.useState(addr?.formatted_address ?? "");
5342
+ const [suggestions, setSuggestions] = React10__default.default.useState([]);
5343
+ const [isOpen, setIsOpen] = React10__default.default.useState(false);
5344
+ const [highlightedIndex, setHighlightedIndex] = React10__default.default.useState(-1);
5345
+ const debounceRef = React10__default.default.useRef(null);
5346
+ const seqRef = React10__default.default.useRef(0);
5347
+ const sessionTokenRef = React10__default.default.useRef(createSessionToken());
5348
+ const blurTimeoutRef = React10__default.default.useRef(null);
5349
+ React10__default.default.useEffect(() => {
5350
+ return () => {
5351
+ if (debounceRef.current) clearTimeout(debounceRef.current);
5352
+ if (blurTimeoutRef.current) clearTimeout(blurTimeoutRef.current);
5353
+ seqRef.current += 1;
5354
+ };
5355
+ }, []);
5356
+ const fetchSuggestions = React10__default.default.useCallback(async (query) => {
5357
+ const client = clientContext?.client;
5358
+ if (!client || query.length < 3) {
5359
+ setSuggestions([]);
5360
+ setIsOpen(false);
5361
+ return;
5362
+ }
5363
+ const seq = ++seqRef.current;
5364
+ const result = await client.places.autocomplete(query, sessionTokenRef.current);
5365
+ if (seqRef.current !== seq) return;
5366
+ if (result.ok && result.value.predictions.length > 0) {
5367
+ setSuggestions(result.value.predictions);
5368
+ setHighlightedIndex(0);
5369
+ setIsOpen(true);
5370
+ } else {
5371
+ setSuggestions([]);
5372
+ setIsOpen(false);
5373
+ }
5374
+ }, [clientContext]);
5375
+ const handleInputChange = (nextValue) => {
5376
+ setInputText(nextValue);
5377
+ if (debounceRef.current) clearTimeout(debounceRef.current);
5378
+ debounceRef.current = setTimeout(() => void fetchSuggestions(nextValue.trim()), 300);
5379
+ };
5380
+ const selectSuggestion = React10__default.default.useCallback(async (suggestion) => {
5381
+ if (debounceRef.current) clearTimeout(debounceRef.current);
5382
+ if (blurTimeoutRef.current) clearTimeout(blurTimeoutRef.current);
5383
+ const fallback = suggestion.description.split(",")[0]?.trim() || suggestion.description;
5384
+ setInputText(fallback);
5385
+ setSuggestions([]);
5386
+ setIsOpen(false);
5387
+ const client = clientContext?.client;
5388
+ if (!client) return;
5389
+ const result = await client.places.details(suggestion.place_id, sessionTokenRef.current);
5390
+ sessionTokenRef.current = createSessionToken();
5391
+ if (result.ok) {
5392
+ const d = result.value;
5393
+ const addressValue = {
5394
+ formatted_address: d.formatted_address || fallback,
5395
+ street_address: d.street_address,
5396
+ apartment: d.apartment,
5397
+ city: d.city,
5398
+ region: d.region,
5399
+ postal_code: d.postal_code,
5400
+ country: d.country,
5401
+ latitude: d.latitude,
5402
+ longitude: d.longitude,
5403
+ place_id: d.place_id
5404
+ };
5405
+ setInputText(addressValue.formatted_address);
5406
+ onValueChange(addressValue);
5407
+ }
5408
+ }, [clientContext, onValueChange]);
5409
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-2 relative", classNames?.addressInput), children: [
5410
+ /* @__PURE__ */ jsxRuntime.jsx(
5411
+ "input",
5412
+ {
5413
+ type: "text",
5414
+ value: inputText,
5415
+ onChange: (e) => handleInputChange(e.target.value),
5416
+ onFocus: () => {
5417
+ if (suggestions.length > 0) setIsOpen(true);
5418
+ },
5419
+ onBlur: () => {
5420
+ blurTimeoutRef.current = setTimeout(() => setIsOpen(false), 120);
5421
+ },
5422
+ onKeyDown: (e) => {
5423
+ if (e.key === "Escape") {
5424
+ setIsOpen(false);
5425
+ return;
5426
+ }
5427
+ if (!isOpen || suggestions.length === 0) return;
5428
+ if (e.key === "ArrowDown") {
5429
+ e.preventDefault();
5430
+ setHighlightedIndex((i) => i < suggestions.length - 1 ? i + 1 : 0);
5431
+ } else if (e.key === "ArrowUp") {
5432
+ e.preventDefault();
5433
+ setHighlightedIndex((i) => i > 0 ? i - 1 : suggestions.length - 1);
5434
+ } else if (e.key === "Enter" && highlightedIndex >= 0) {
5435
+ e.preventDefault();
5436
+ void selectSuggestion(suggestions[highlightedIndex]);
5437
+ }
5438
+ },
5439
+ placeholder: field.placeholder || "Search for an address...",
5440
+ required: field.is_required,
5441
+ autoComplete: "off",
5442
+ "aria-autocomplete": "list",
5443
+ "aria-expanded": isOpen && suggestions.length > 0,
5444
+ className: inputClass
5445
+ }
5446
+ ),
5447
+ isOpen && suggestions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { role: "listbox", className: "absolute left-0 right-0 top-full z-20 mt-1 overflow-hidden rounded-md border border-border bg-background shadow-lg", children: suggestions.map((s, i) => /* @__PURE__ */ jsxRuntime.jsx(
5448
+ "button",
5449
+ {
5450
+ type: "button",
5451
+ role: "option",
5452
+ "aria-selected": i === highlightedIndex,
5453
+ onMouseDown: (e) => {
5454
+ e.preventDefault();
5455
+ void selectSuggestion(s);
5456
+ },
5457
+ className: cn("block w-full px-3 py-2.5 text-left text-sm transition-colors", i === highlightedIndex ? "bg-muted text-foreground" : "text-foreground hover:bg-muted/70"),
5458
+ children: s.description
5459
+ },
5460
+ s.place_id
5461
+ )) }),
5462
+ addr && /* @__PURE__ */ jsxRuntime.jsx(
5463
+ "input",
5464
+ {
5465
+ type: "text",
5466
+ value: addr.apartment || "",
5467
+ onChange: (e) => onValueChange({ ...addr, apartment: e.target.value || void 0 }),
5468
+ placeholder: "Apt, suite, unit (optional)",
5469
+ className: inputClass
5470
+ }
5471
+ )
5472
+ ] });
5473
+ }
5474
+ function LocationInput({
5475
+ field,
5476
+ value,
5477
+ onValueChange,
5478
+ classNames,
5479
+ inputClass
5480
+ }) {
5481
+ const clientContext = useOptionalCimplifyClient();
5482
+ const loc = value && typeof value === "object" ? value : null;
5483
+ const [inputText, setInputText] = React10__default.default.useState(loc?.label ?? "");
5484
+ const [suggestions, setSuggestions] = React10__default.default.useState([]);
5485
+ const [isOpen, setIsOpen] = React10__default.default.useState(false);
5486
+ const [highlightedIndex, setHighlightedIndex] = React10__default.default.useState(-1);
5487
+ const debounceRef = React10__default.default.useRef(null);
5488
+ const seqRef = React10__default.default.useRef(0);
5489
+ const sessionTokenRef = React10__default.default.useRef(createSessionToken());
5490
+ const blurTimeoutRef = React10__default.default.useRef(null);
5491
+ React10__default.default.useEffect(() => {
5492
+ return () => {
5493
+ if (debounceRef.current) clearTimeout(debounceRef.current);
5494
+ if (blurTimeoutRef.current) clearTimeout(blurTimeoutRef.current);
5495
+ seqRef.current += 1;
5496
+ };
5497
+ }, []);
5498
+ const fetchSuggestions = React10__default.default.useCallback(async (query) => {
5499
+ const client = clientContext?.client;
5500
+ if (!client || query.length < 3) {
5501
+ setSuggestions([]);
5502
+ setIsOpen(false);
5503
+ return;
5504
+ }
5505
+ const seq = ++seqRef.current;
5506
+ const result = await client.places.autocomplete(query, sessionTokenRef.current);
5507
+ if (seqRef.current !== seq) return;
5508
+ if (result.ok && result.value.predictions.length > 0) {
5509
+ setSuggestions(result.value.predictions);
5510
+ setHighlightedIndex(0);
5511
+ setIsOpen(true);
5512
+ } else {
5513
+ setSuggestions([]);
5514
+ setIsOpen(false);
5515
+ }
5516
+ }, [clientContext]);
5517
+ const handleInputChange = (nextValue) => {
5518
+ setInputText(nextValue);
5519
+ if (debounceRef.current) clearTimeout(debounceRef.current);
5520
+ debounceRef.current = setTimeout(() => void fetchSuggestions(nextValue.trim()), 300);
5521
+ };
5522
+ const selectSuggestion = React10__default.default.useCallback(async (suggestion) => {
5523
+ if (debounceRef.current) clearTimeout(debounceRef.current);
5524
+ if (blurTimeoutRef.current) clearTimeout(blurTimeoutRef.current);
5525
+ const label = suggestion.description.split(",")[0]?.trim() || suggestion.description;
5526
+ setInputText(label);
5527
+ setSuggestions([]);
5528
+ setIsOpen(false);
5529
+ const client = clientContext?.client;
5530
+ if (!client) return;
5531
+ const result = await client.places.details(suggestion.place_id, sessionTokenRef.current);
5532
+ sessionTokenRef.current = createSessionToken();
5533
+ if (result.ok) {
5534
+ const d = result.value;
5535
+ onValueChange({
5536
+ latitude: d.latitude,
5537
+ longitude: d.longitude,
5538
+ label: d.formatted_address || label
5539
+ });
5540
+ setInputText(d.formatted_address || label);
5541
+ }
5542
+ }, [clientContext, onValueChange]);
5543
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative", classNames?.locationInput), children: [
5544
+ /* @__PURE__ */ jsxRuntime.jsx(
5545
+ "input",
5546
+ {
5547
+ type: "text",
5548
+ value: inputText,
5549
+ onChange: (e) => handleInputChange(e.target.value),
5550
+ onFocus: () => {
5551
+ if (suggestions.length > 0) setIsOpen(true);
5552
+ },
5553
+ onBlur: () => {
5554
+ blurTimeoutRef.current = setTimeout(() => setIsOpen(false), 120);
5555
+ },
5556
+ onKeyDown: (e) => {
5557
+ if (e.key === "Escape") {
5558
+ setIsOpen(false);
5559
+ return;
5560
+ }
5561
+ if (!isOpen || suggestions.length === 0) return;
5562
+ if (e.key === "ArrowDown") {
5563
+ e.preventDefault();
5564
+ setHighlightedIndex((i) => i < suggestions.length - 1 ? i + 1 : 0);
5565
+ } else if (e.key === "ArrowUp") {
5566
+ e.preventDefault();
5567
+ setHighlightedIndex((i) => i > 0 ? i - 1 : suggestions.length - 1);
5568
+ } else if (e.key === "Enter" && highlightedIndex >= 0) {
5569
+ e.preventDefault();
5570
+ void selectSuggestion(suggestions[highlightedIndex]);
5571
+ }
5572
+ },
5573
+ placeholder: field.placeholder || "Search for a location...",
5574
+ required: field.is_required,
5575
+ autoComplete: "off",
5576
+ "aria-autocomplete": "list",
5577
+ "aria-expanded": isOpen && suggestions.length > 0,
5578
+ className: inputClass
5579
+ }
5580
+ ),
5581
+ isOpen && suggestions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { role: "listbox", className: "absolute left-0 right-0 top-full z-20 mt-1 overflow-hidden rounded-md border border-border bg-background shadow-lg", children: suggestions.map((s, i) => /* @__PURE__ */ jsxRuntime.jsx(
5582
+ "button",
5583
+ {
5584
+ type: "button",
5585
+ role: "option",
5586
+ "aria-selected": i === highlightedIndex,
5587
+ onMouseDown: (e) => {
5588
+ e.preventDefault();
5589
+ void selectSuggestion(s);
5590
+ },
5591
+ className: cn("block w-full px-3 py-2.5 text-left text-sm transition-colors", i === highlightedIndex ? "bg-muted text-foreground" : "text-foreground hover:bg-muted/70"),
5592
+ children: s.description
5593
+ },
5594
+ s.place_id
5595
+ )) }),
5596
+ loc && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground mt-1", children: [
5597
+ loc.latitude.toFixed(4),
5598
+ ", ",
5599
+ loc.longitude.toFixed(4)
5600
+ ] })
5601
+ ] });
5602
+ }
5603
+ function PhoneInput({
5604
+ field,
5605
+ value,
5606
+ onValueChange,
5607
+ classNames,
5608
+ inputClass
5609
+ }) {
5610
+ const phone = value && typeof value === "object" ? value : null;
5611
+ const [code, setCode] = React10__default.default.useState(phone?.country_code ?? "+1");
5612
+ const [number, setNumber] = React10__default.default.useState(phone?.number ?? "");
5613
+ const update = (nextCode, nextNumber) => {
5614
+ setCode(nextCode);
5615
+ setNumber(nextNumber);
5616
+ if (nextNumber) {
5617
+ onValueChange({
5618
+ country_code: nextCode,
5619
+ number: nextNumber,
5620
+ formatted: `${nextCode} ${nextNumber}`
5621
+ });
5622
+ } else {
5623
+ onValueChange(void 0);
5624
+ }
5625
+ };
5626
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex gap-2", classNames?.phoneInput), children: [
5627
+ /* @__PURE__ */ jsxRuntime.jsx(
5628
+ "input",
5629
+ {
5630
+ type: "text",
5631
+ value: code,
5632
+ onChange: (e) => update(e.target.value, number),
5633
+ placeholder: "+1",
5634
+ className: cn(inputClass, "w-20 shrink-0")
5635
+ }
5636
+ ),
5637
+ /* @__PURE__ */ jsxRuntime.jsx(
5638
+ "input",
5639
+ {
5640
+ type: "tel",
5641
+ value: number,
5642
+ onChange: (e) => update(code, e.target.value),
5643
+ placeholder: field.placeholder || "Phone number",
5644
+ required: field.is_required,
5645
+ className: inputClass
5646
+ }
5647
+ )
5648
+ ] });
5649
+ }
5650
+ function SignatureInput({
5651
+ field,
5652
+ value,
5653
+ onValueChange,
5654
+ classNames
5655
+ }) {
5656
+ const sig = value && typeof value === "object" ? value : null;
5657
+ const canvasRef = React10__default.default.useRef(null);
5658
+ const isDrawing = React10__default.default.useRef(false);
5659
+ const getCtx = () => canvasRef.current?.getContext("2d") ?? null;
5660
+ const startDraw = (e) => {
5661
+ const ctx = getCtx();
5662
+ if (!ctx) return;
5663
+ isDrawing.current = true;
5664
+ const rect = canvasRef.current.getBoundingClientRect();
5665
+ ctx.beginPath();
5666
+ ctx.moveTo(e.clientX - rect.left, e.clientY - rect.top);
5667
+ canvasRef.current.setPointerCapture(e.pointerId);
5668
+ };
5669
+ const draw = (e) => {
5670
+ if (!isDrawing.current) return;
5671
+ const ctx = getCtx();
5672
+ if (!ctx) return;
5673
+ const rect = canvasRef.current.getBoundingClientRect();
5674
+ ctx.lineWidth = 2;
5675
+ ctx.lineCap = "round";
5676
+ const style = getComputedStyle(canvasRef.current);
5677
+ ctx.strokeStyle = style.color || "#000";
5678
+ ctx.lineTo(e.clientX - rect.left, e.clientY - rect.top);
5679
+ ctx.stroke();
5680
+ };
5681
+ const endDraw = () => {
5682
+ if (!isDrawing.current) return;
5683
+ isDrawing.current = false;
5684
+ const canvas = canvasRef.current;
5685
+ if (!canvas) return;
5686
+ onValueChange({
5687
+ data_url: canvas.toDataURL("image/png"),
5688
+ signer_name: sig?.signer_name
5689
+ });
5690
+ };
5691
+ const clear = () => {
5692
+ const canvas = canvasRef.current;
5693
+ if (!canvas) return;
5694
+ const ctx = canvas.getContext("2d");
5695
+ if (ctx) ctx.clearRect(0, 0, canvas.width, canvas.height);
5696
+ onValueChange(void 0);
5697
+ };
5698
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-2", classNames?.signatureCanvas), children: [
5699
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative rounded-md border border-input overflow-hidden", children: [
5700
+ /* @__PURE__ */ jsxRuntime.jsx(
5701
+ "canvas",
5702
+ {
5703
+ ref: canvasRef,
5704
+ width: 400,
5705
+ height: 150,
5706
+ className: "w-full touch-none cursor-crosshair bg-background text-foreground",
5707
+ onPointerDown: startDraw,
5708
+ onPointerMove: draw,
5709
+ onPointerUp: endDraw,
5710
+ onPointerLeave: endDraw
5711
+ }
5712
+ ),
5713
+ sig?.data_url && /* @__PURE__ */ jsxRuntime.jsx(
5714
+ "button",
5715
+ {
5716
+ type: "button",
5717
+ onClick: clear,
5718
+ className: "absolute top-1.5 right-1.5 text-xs text-muted-foreground hover:text-destructive transition-colors",
5719
+ children: "Clear"
5720
+ }
5721
+ )
5722
+ ] }),
5723
+ !sig?.data_url && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: field.placeholder || "Draw your signature above" })
5724
+ ] });
5725
+ }
5726
+ function createSessionToken() {
5727
+ if (typeof crypto !== "undefined" && crypto.randomUUID) {
5728
+ return crypto.randomUUID();
5729
+ }
5730
+ return `places_${Date.now()}_${Math.random().toString(16).slice(2)}`;
5731
+ }
4778
5732
  function ProductCustomizer({
4779
5733
  product,
4780
5734
  onAddToCart,
@@ -4782,20 +5736,21 @@ function ProductCustomizer({
4782
5736
  className,
4783
5737
  classNames
4784
5738
  }) {
4785
- const [quantity, setQuantity] = React3.useState(product.min_order_quantity ?? 1);
4786
- const [isAdded, setIsAdded] = React3.useState(false);
4787
- const [isSubmitting, setIsSubmitting] = React3.useState(false);
4788
- const [selectedVariantId, setSelectedVariantId] = React3.useState();
4789
- const [selectedVariant, setSelectedVariant] = React3.useState();
4790
- const [selectedAddOnOptionIds, setSelectedAddOnOptionIds] = React3.useState([]);
4791
- const [compositeSelections, setCompositeSelections] = React3.useState([]);
4792
- const [compositePrice, setCompositePrice] = React3.useState(null);
4793
- const [compositeReady, setCompositeReady] = React3.useState(false);
4794
- const [bundleSelections, setBundleSelections] = React3.useState([]);
4795
- const [bundleTotalPrice, setBundleTotalPrice] = React3.useState(null);
4796
- const [bundleReady, setBundleReady] = React3.useState(false);
4797
- const [selectedBillingPlan, setSelectedBillingPlan] = React3.useState(null);
4798
- const [specialInstructions, setSpecialInstructions] = React3.useState("");
5739
+ const [quantity, setQuantity] = React10.useState(product.min_order_quantity ?? 1);
5740
+ const [isAdded, setIsAdded] = React10.useState(false);
5741
+ const [isSubmitting, setIsSubmitting] = React10.useState(false);
5742
+ const [selectedVariantId, setSelectedVariantId] = React10.useState();
5743
+ const [selectedVariant, setSelectedVariant] = React10.useState();
5744
+ const [selectedAddOnOptionIds, setSelectedAddOnOptionIds] = React10.useState([]);
5745
+ const [compositeSelections, setCompositeSelections] = React10.useState([]);
5746
+ const [compositePrice, setCompositePrice] = React10.useState(null);
5747
+ const [compositeReady, setCompositeReady] = React10.useState(false);
5748
+ const [bundleSelections, setBundleSelections] = React10.useState([]);
5749
+ const [bundleTotalPrice, setBundleTotalPrice] = React10.useState(null);
5750
+ const [bundleReady, setBundleReady] = React10.useState(false);
5751
+ const [selectedBillingPlan, setSelectedBillingPlan] = React10.useState(null);
5752
+ const [customerInputValues, setCustomerInputValues] = React10.useState({});
5753
+ const [specialInstructions, setSpecialInstructions] = React10.useState("");
4799
5754
  const cart = useCart();
4800
5755
  const productType = product.type || "product";
4801
5756
  const isComposite = productType === "composite";
@@ -4805,7 +5760,7 @@ function ProductCustomizer({
4805
5760
  const isStandard = !isComposite && !isBundle;
4806
5761
  const hasVariants = isStandard && product.variants && product.variants.length > 0;
4807
5762
  const hasAddOns = isStandard && product.add_ons && product.add_ons.length > 0;
4808
- React3.useEffect(() => {
5763
+ React10.useEffect(() => {
4809
5764
  setQuantity(product.min_order_quantity ?? 1);
4810
5765
  setIsAdded(false);
4811
5766
  setIsSubmitting(false);
@@ -4819,9 +5774,10 @@ function ProductCustomizer({
4819
5774
  setBundleTotalPrice(null);
4820
5775
  setBundleReady(false);
4821
5776
  setSelectedBillingPlan(null);
5777
+ setCustomerInputValues({});
4822
5778
  setSpecialInstructions("");
4823
5779
  }, [product.id, product.min_order_quantity]);
4824
- const selectedAddOnOptions = React3.useMemo(() => {
5780
+ const selectedAddOnOptions = React10.useMemo(() => {
4825
5781
  if (!product.add_ons) return [];
4826
5782
  const options = [];
4827
5783
  for (const addOn of product.add_ons) {
@@ -4833,11 +5789,11 @@ function ProductCustomizer({
4833
5789
  }
4834
5790
  return options;
4835
5791
  }, [product.add_ons, selectedAddOnOptionIds]);
4836
- const normalizedAddOnOptionIds = React3.useMemo(() => {
5792
+ const normalizedAddOnOptionIds = React10.useMemo(() => {
4837
5793
  if (selectedAddOnOptionIds.length === 0) return [];
4838
5794
  return Array.from(new Set(selectedAddOnOptionIds.map((id) => id.trim()).filter(Boolean))).sort();
4839
5795
  }, [selectedAddOnOptionIds]);
4840
- const localTotalPrice = React3.useMemo(() => {
5796
+ const localTotalPrice = React10.useMemo(() => {
4841
5797
  if (isComposite && compositePrice) {
4842
5798
  return chunkPEDLCL72_js.parsePrice(compositePrice.final_price) * quantity;
4843
5799
  }
@@ -4855,7 +5811,7 @@ function ProductCustomizer({
4855
5811
  }
4856
5812
  return price * quantity;
4857
5813
  }, [product.default_price, selectedVariant, selectedAddOnOptions, quantity, isComposite, compositePrice, isBundle, bundleTotalPrice]);
4858
- const requiredAddOnsSatisfied = React3.useMemo(() => {
5814
+ const requiredAddOnsSatisfied = React10.useMemo(() => {
4859
5815
  if (!product.add_ons) return true;
4860
5816
  for (const addOn of product.add_ons) {
4861
5817
  if (addOn.is_required) {
@@ -4870,7 +5826,7 @@ function ProductCustomizer({
4870
5826
  }
4871
5827
  return true;
4872
5828
  }, [product.add_ons, selectedAddOnOptionIds]);
4873
- const quoteInput = React3.useMemo(
5829
+ const quoteInput = React10.useMemo(
4874
5830
  () => ({
4875
5831
  productId: product.id,
4876
5832
  quantity,
@@ -4881,12 +5837,20 @@ function ProductCustomizer({
4881
5837
  }),
4882
5838
  [product.id, quantity, selectedVariantId, normalizedAddOnOptionIds, isBundle, bundleSelections, isComposite, compositeSelections]
4883
5839
  );
4884
- const quoteEnabled = isComposite ? compositeReady : isBundle ? bundleReady : requiredAddOnsSatisfied;
5840
+ const requiredInputsSatisfied = React10.useMemo(() => {
5841
+ if (!product.input_fields || product.input_fields.length === 0) return true;
5842
+ return product.input_fields.every((field) => {
5843
+ if (!field.is_required) return true;
5844
+ const val = customerInputValues[field.id];
5845
+ return val !== void 0 && val !== "" && val !== null;
5846
+ });
5847
+ }, [product.input_fields, customerInputValues]);
5848
+ const quoteEnabled = isComposite ? compositeReady && requiredInputsSatisfied : isBundle ? bundleReady && requiredInputsSatisfied : requiredAddOnsSatisfied && requiredInputsSatisfied;
4885
5849
  const { quote } = useQuote(quoteInput, {
4886
5850
  enabled: quoteEnabled
4887
5851
  });
4888
5852
  const quoteId = quote?.quote_id;
4889
- const quotedTotalPrice = React3.useMemo(() => {
5853
+ const quotedTotalPrice = React10.useMemo(() => {
4890
5854
  if (!quote) return void 0;
4891
5855
  const priceInfo = quote.quoted_total_price_info ?? quote.final_price_info;
4892
5856
  const perUnit = priceInfo.pre_tax_price;
@@ -4894,16 +5858,16 @@ function ProductCustomizer({
4894
5858
  return chunkPEDLCL72_js.parsePrice(perUnit) * quantity;
4895
5859
  }, [quote, quantity]);
4896
5860
  const displayTotalPrice = quotedTotalPrice ?? localTotalPrice;
4897
- const handleVariantChange = React3.useCallback(
5861
+ const handleVariantChange = React10.useCallback(
4898
5862
  (variantId, variant) => {
4899
5863
  setSelectedVariantId(variantId);
4900
5864
  setSelectedVariant(variant);
4901
5865
  },
4902
5866
  []
4903
5867
  );
4904
- const addedTimerRef = React3.useRef(void 0);
4905
- React3.useEffect(() => () => clearTimeout(addedTimerRef.current), []);
4906
- const handleAddToCart = React3.useCallback(async () => {
5868
+ const addedTimerRef = React10.useRef(void 0);
5869
+ React10.useEffect(() => () => clearTimeout(addedTimerRef.current), []);
5870
+ const handleAddToCart = React10.useCallback(async () => {
4907
5871
  if (isSubmitting) return;
4908
5872
  setIsSubmitting(true);
4909
5873
  const options = {
@@ -4920,6 +5884,7 @@ function ProductCustomizer({
4920
5884
  compositeSelections: isComposite && compositeSelections.length > 0 ? compositeSelections : void 0,
4921
5885
  bundleSelections: isBundle && bundleSelections.length > 0 ? bundleSelections : void 0,
4922
5886
  billingPlanId: selectedBillingPlan?.id,
5887
+ customerInputs: Object.keys(customerInputValues).length > 0 ? Object.entries(customerInputValues).filter(([, v]) => v !== void 0 && v !== "").map(([fieldId, value]) => ({ field_id: fieldId, value })) : void 0,
4923
5888
  specialInstructions: specialInstructions.trim() || void 0
4924
5889
  };
4925
5890
  try {
@@ -4938,7 +5903,7 @@ function ProductCustomizer({
4938
5903
  } finally {
4939
5904
  setIsSubmitting(false);
4940
5905
  }
4941
- }, [product, quantity, selectedVariantId, selectedVariant, quoteId, normalizedAddOnOptionIds, selectedAddOnOptions, isComposite, compositeSelections, isBundle, bundleSelections, selectedBillingPlan, specialInstructions, isSubmitting, onAddToCart, cart]);
5906
+ }, [product, quantity, selectedVariantId, selectedVariant, quoteId, normalizedAddOnOptionIds, selectedAddOnOptions, isComposite, compositeSelections, isBundle, bundleSelections, selectedBillingPlan, customerInputValues, specialInstructions, isSubmitting, onAddToCart, cart]);
4942
5907
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-customizer": true, className: cn("space-y-6", className, classNames?.root), children: [
4943
5908
  isComposite && product.groups && product.composite_id && /* @__PURE__ */ jsxRuntime.jsx(
4944
5909
  CompositeSelector,
@@ -4999,6 +5964,14 @@ function ProductCustomizer({
4999
5964
  currentQuantity: quantity
5000
5965
  }
5001
5966
  ),
5967
+ product.input_fields && product.input_fields.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
5968
+ CustomerInputFields,
5969
+ {
5970
+ fields: product.input_fields,
5971
+ values: customerInputValues,
5972
+ onChange: setCustomerInputValues
5973
+ }
5974
+ ),
5002
5975
  product.deposit_type && product.deposit_type !== "none" && product.deposit_amount && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-customizer-deposit": true, className: cn("text-sm text-muted-foreground", classNames?.depositInfo), children: product.deposit_type === "fixed" ? /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
5003
5976
  "Deposit required: ",
5004
5977
  /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.deposit_amount })
@@ -5106,14 +6079,14 @@ function ProductImageGallery({
5106
6079
  aspectRatio = "4/3",
5107
6080
  className
5108
6081
  }) {
5109
- const normalizedImages = React3.useMemo(
6082
+ const normalizedImages = React10.useMemo(
5110
6083
  () => images.filter(
5111
6084
  (image) => typeof image === "string" && image.trim().length > 0
5112
6085
  ),
5113
6086
  [images]
5114
6087
  );
5115
- const [selectedImage, setSelectedImage] = React3.useState(0);
5116
- React3.useEffect(() => {
6088
+ const [selectedImage, setSelectedImage] = React10.useState(0);
6089
+ React10.useEffect(() => {
5117
6090
  setSelectedImage(0);
5118
6091
  }, [normalizedImages.length, productName]);
5119
6092
  if (normalizedImages.length === 0) {
@@ -5193,13 +6166,17 @@ function CartLineItemRow({
5193
6166
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-item": true, className: classNames?.item, children: [
5194
6167
  /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-item-info": true, children: [
5195
6168
  /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-name": true, className: classNames?.itemName, children: item.product.name }),
5196
- item.variant && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-variant": true, children: chunk4JSRPSNA_js.getVariantDisplayName(item.variant, item.product.name) }),
6169
+ item.variant && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-variant": true, children: chunkR4AKAGZQ_js.getVariantDisplayName(item.variant, item.product.name) }),
5197
6170
  item.addOnOptions && item.addOnOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-cart-item-addons": true, children: [
5198
6171
  "+ ",
5199
6172
  item.addOnOptions.map((opt) => opt.name).join(", ")
5200
6173
  ] }),
5201
6174
  (hasComposite || hasBundle) && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-badge": true, children: hasComposite ? "Custom" : "Bundle" }),
5202
6175
  item.specialInstructions && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-instructions": true, className: "text-xs text-muted-foreground", children: item.specialInstructions }),
6176
+ item.customerInputs && item.customerInputs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-cart-customer-inputs": true, className: classNames?.customerInputs, children: item.customerInputs.map((input) => /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-input": true, children: [
6177
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-input-label": true, children: input.field_name }),
6178
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-input-value": true, children: input.field_type === chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.File || input.field_type === chunkR4AKAGZQ_js.INPUT_FIELD_TYPE.Image ? String(input.value).split("/").pop() || "Uploaded file" : String(input.value) })
6179
+ ] }, input.field_id)) }),
5203
6180
  (item.lineType === "service" || item.product.type === "service") && item.scheduledStart && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-service-info": true, className: classNames?.serviceInfo, children: [
5204
6181
  /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
5205
6182
  "\u{1F4C5}",
@@ -5718,7 +6695,7 @@ function FoodProductCard({
5718
6695
  const tags = product.tags || [];
5719
6696
  const isSignature = product.metadata?.is_signature === true;
5720
6697
  const isNew = product.metadata?.is_new === true;
5721
- const isComposite = product.type === chunk4JSRPSNA_js.PRODUCT_TYPE.Composite;
6698
+ const isComposite = product.type === chunkR4AKAGZQ_js.PRODUCT_TYPE.Composite;
5722
6699
  return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, className, children: [
5723
6700
  /* @__PURE__ */ jsxRuntime.jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "square", renderImage, children: [
5724
6701
  isSignature && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute top-3 left-3 inline-flex items-center gap-1 text-[11px] font-semibold tracking-wide bg-amber-50 text-amber-700 border border-amber-200/60 px-2 py-0.5 rounded-md", children: [
@@ -5887,6 +6864,98 @@ function DigitalProductCard({
5887
6864
  ] })
5888
6865
  ] });
5889
6866
  }
6867
+ function BundleProductCard({
6868
+ product,
6869
+ onQuickAdd,
6870
+ renderImage,
6871
+ renderLink,
6872
+ className
6873
+ }) {
6874
+ const image = product.image_url || product.images?.[0] || "";
6875
+ const components = product.components || [];
6876
+ const componentCount = components.length;
6877
+ const onSale = chunkPEDLCL72_js.isOnSale(product);
6878
+ const discount = chunkPEDLCL72_js.getDiscountPercentage(product);
6879
+ const hasVariantChoice = components.some((c) => c.allow_variant_choice);
6880
+ return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, className, children: [
6881
+ /* @__PURE__ */ jsxRuntime.jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "square", renderImage, children: [
6882
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute top-3 left-3 text-[11px] font-semibold tracking-wide bg-indigo-50 text-indigo-700 border border-indigo-200/60 px-2 py-0.5 rounded-md", children: "Bundle" }),
6883
+ componentCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute top-3 right-3 text-[11px] font-semibold tracking-wide bg-background/90 backdrop-blur text-foreground px-2 py-0.5 rounded-md", children: [
6884
+ componentCount,
6885
+ " item",
6886
+ componentCount !== 1 ? "s" : ""
6887
+ ] }),
6888
+ /* @__PURE__ */ jsxRuntime.jsx(
6889
+ QuickAddButton,
6890
+ {
6891
+ onClick: () => onQuickAdd?.(product),
6892
+ className: "absolute bottom-3 right-3"
6893
+ }
6894
+ )
6895
+ ] }),
6896
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-3.5", children: [
6897
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[14.5px] font-semibold text-foreground leading-snug tracking-tight truncate", children: product.name }),
6898
+ componentCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-[11px] text-muted-foreground mt-1 truncate", children: [
6899
+ "Includes: ",
6900
+ components.map((c) => c.product_name || c.product_id).join(", ")
6901
+ ] }),
6902
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-2.5", children: [
6903
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price, className: "text-sm font-bold" }),
6904
+ onSale && product.bundle_price && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6905
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: chunkPEDLCL72_js.getBasePrice(product), className: "text-xs text-muted-foreground line-through" }),
6906
+ discount != null && discount > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] font-semibold text-emerald-600", children: [
6907
+ "Save ",
6908
+ discount,
6909
+ "%"
6910
+ ] })
6911
+ ] })
6912
+ ] }),
6913
+ hasVariantChoice && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block mt-2 text-[10px] font-medium text-muted-foreground px-1.5 py-0.5 bg-muted rounded", children: "Customizable" })
6914
+ ] })
6915
+ ] });
6916
+ }
6917
+ function CompositeProductCard({
6918
+ product,
6919
+ onQuickAdd,
6920
+ renderImage,
6921
+ renderLink,
6922
+ className
6923
+ }) {
6924
+ const image = product.image_url || product.images?.[0] || "";
6925
+ const groups = product.groups || [];
6926
+ const groupCount = groups.length;
6927
+ groups.reduce((sum, g) => sum + g.components.length, 0);
6928
+ const tags = product.tags || [];
6929
+ return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, className, children: [
6930
+ /* @__PURE__ */ jsxRuntime.jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "square", renderImage, children: [
6931
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute top-3 left-3 text-[11px] font-semibold tracking-wide bg-violet-50 text-violet-700 border border-violet-200/60 px-2 py-0.5 rounded-md", children: "Build Your Own" }),
6932
+ groupCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute top-3 right-3 text-[11px] font-semibold tracking-wide bg-background/90 backdrop-blur text-foreground px-2 py-0.5 rounded-md", children: [
6933
+ groupCount,
6934
+ " choice",
6935
+ groupCount !== 1 ? "s" : ""
6936
+ ] }),
6937
+ /* @__PURE__ */ jsxRuntime.jsx(
6938
+ QuickAddButton,
6939
+ {
6940
+ onClick: () => onQuickAdd?.(product),
6941
+ className: "absolute bottom-3 right-3"
6942
+ }
6943
+ )
6944
+ ] }),
6945
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-3.5", children: [
6946
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[14.5px] font-semibold text-foreground leading-snug tracking-tight truncate", children: product.name }),
6947
+ product.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[12px] text-muted-foreground mt-1 line-clamp-1", children: product.description }),
6948
+ groupCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[11px] text-muted-foreground mt-1 truncate", children: groups.map((g) => g.name).join(" + ") }),
6949
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mt-2.5", children: [
6950
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm font-bold", children: [
6951
+ "From ",
6952
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price })
6953
+ ] }),
6954
+ tags.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium text-muted-foreground px-1.5 py-0.5 bg-muted rounded", children: tags[0] })
6955
+ ] })
6956
+ ] })
6957
+ ] });
6958
+ }
5890
6959
  function formatDuration2(minutes, unit) {
5891
6960
  if (unit && unit !== "minutes") return `${minutes} ${unit}`;
5892
6961
  if (minutes >= 60) {
@@ -6348,6 +7417,8 @@ var CardVariant = /* @__PURE__ */ ((CardVariant2) => {
6348
7417
  CardVariant2["Retail"] = "retail";
6349
7418
  CardVariant2["Wholesale"] = "wholesale";
6350
7419
  CardVariant2["Digital"] = "digital";
7420
+ CardVariant2["Bundle"] = "bundle";
7421
+ CardVariant2["Composite"] = "composite";
6351
7422
  CardVariant2["Standard"] = "standard";
6352
7423
  CardVariant2["Compact"] = "compact";
6353
7424
  CardVariant2["Schedule"] = "schedule";
@@ -6372,22 +7443,30 @@ var BUILT_IN_CARDS = {
6372
7443
  ["rental" /* Rental */]: RentalServiceCard,
6373
7444
  ["accommodation" /* Accommodation */]: AccommodationCard,
6374
7445
  ["lease" /* Lease */]: LeaseServiceCard,
7446
+ ["bundle" /* Bundle */]: BundleProductCard,
7447
+ ["composite" /* Composite */]: CompositeProductCard,
6375
7448
  ["subscription" /* Subscription */]: SubscriptionCard
6376
7449
  };
6377
- var RENTAL_UNITS = /* @__PURE__ */ new Set([chunk4JSRPSNA_js.DURATION_UNIT.Days, chunk4JSRPSNA_js.DURATION_UNIT.Hours]);
6378
- var LEASE_UNITS = /* @__PURE__ */ new Set([chunk4JSRPSNA_js.DURATION_UNIT.Weeks, chunk4JSRPSNA_js.DURATION_UNIT.Months, chunk4JSRPSNA_js.DURATION_UNIT.Years]);
7450
+ var RENTAL_UNITS = /* @__PURE__ */ new Set([chunkR4AKAGZQ_js.DURATION_UNIT.Days, chunkR4AKAGZQ_js.DURATION_UNIT.Hours]);
7451
+ var LEASE_UNITS = /* @__PURE__ */ new Set([chunkR4AKAGZQ_js.DURATION_UNIT.Weeks, chunkR4AKAGZQ_js.DURATION_UNIT.Months, chunkR4AKAGZQ_js.DURATION_UNIT.Years]);
6379
7452
  function resolveCardVariant(product) {
7453
+ if (product.type === chunkR4AKAGZQ_js.PRODUCT_TYPE.Bundle) {
7454
+ return "bundle" /* Bundle */;
7455
+ }
7456
+ if (product.type === chunkR4AKAGZQ_js.PRODUCT_TYPE.Composite) {
7457
+ return "composite" /* Composite */;
7458
+ }
6380
7459
  if (product.quantity_pricing && product.quantity_pricing.length > 1) {
6381
7460
  return "wholesale" /* Wholesale */;
6382
7461
  }
6383
- if (product.type === chunk4JSRPSNA_js.PRODUCT_TYPE.Digital) {
7462
+ if (product.type === chunkR4AKAGZQ_js.PRODUCT_TYPE.Digital) {
6384
7463
  return "digital" /* Digital */;
6385
7464
  }
6386
- if (product.type === chunk4JSRPSNA_js.PRODUCT_TYPE.Service) {
7465
+ if (product.type === chunkR4AKAGZQ_js.PRODUCT_TYPE.Service) {
6387
7466
  if (product.duration_unit && RENTAL_UNITS.has(product.duration_unit)) {
6388
7467
  return "rental" /* Rental */;
6389
7468
  }
6390
- if (product.duration_unit === chunk4JSRPSNA_js.DURATION_UNIT.Nights) {
7469
+ if (product.duration_unit === chunkR4AKAGZQ_js.DURATION_UNIT.Nights) {
6391
7470
  return "accommodation" /* Accommodation */;
6392
7471
  }
6393
7472
  if (product.duration_unit && LEASE_UNITS.has(product.duration_unit)) {
@@ -6398,10 +7477,10 @@ function resolveCardVariant(product) {
6398
7477
  }
6399
7478
  return "standard" /* Standard */;
6400
7479
  }
6401
- if (product.render_hint === chunk4JSRPSNA_js.RENDER_HINT.Food) {
7480
+ if (product.render_hint === chunkR4AKAGZQ_js.RENDER_HINT.Food) {
6402
7481
  return "food" /* Food */;
6403
7482
  }
6404
- if (product.render_hint === chunk4JSRPSNA_js.RENDER_HINT.Physical) {
7483
+ if (product.render_hint === chunkR4AKAGZQ_js.RENDER_HINT.Physical) {
6405
7484
  return "retail" /* Retail */;
6406
7485
  }
6407
7486
  return "retail" /* Retail */;
@@ -6422,22 +7501,22 @@ function ProductCard({
6422
7501
  classNames
6423
7502
  }) {
6424
7503
  const mode = displayMode ?? product.display_mode ?? "card";
6425
- const [isOpen, setIsOpen] = React3.useState(false);
6426
- const [shouldFetch, setShouldFetch] = React3.useState(false);
7504
+ const [isOpen, setIsOpen] = React10.useState(false);
7505
+ const [shouldFetch, setShouldFetch] = React10.useState(false);
6427
7506
  const { product: productDetails } = useProduct(
6428
7507
  product.slug ?? product.id,
6429
7508
  { enabled: shouldFetch || isOpen }
6430
7509
  );
6431
- const handlePrefetch = React3.useCallback(() => {
7510
+ const handlePrefetch = React10.useCallback(() => {
6432
7511
  setShouldFetch(true);
6433
7512
  }, []);
6434
- const handleOpenChange = React3.useCallback((open) => {
7513
+ const handleOpenChange = React10.useCallback((open) => {
6435
7514
  setIsOpen(open);
6436
7515
  if (open) {
6437
7516
  setShouldFetch(true);
6438
7517
  }
6439
7518
  }, []);
6440
- const handleClose = React3.useCallback(() => {
7519
+ const handleClose = React10.useCallback(() => {
6441
7520
  setIsOpen(false);
6442
7521
  }, []);
6443
7522
  const imageUrl = product.image_url || product.images?.[0];
@@ -6566,13 +7645,13 @@ function ProductGrid({
6566
7645
  className,
6567
7646
  classNames
6568
7647
  }) {
6569
- const rawId = React3__default.default.useId();
7648
+ const rawId = React10__default.default.useId();
6570
7649
  const gridId = `cimplify-grid-${rawId.replace(/:/g, "")}`;
6571
7650
  const sm = columns?.sm ?? 1;
6572
7651
  const md = columns?.md ?? 2;
6573
7652
  const lg = columns?.lg ?? 3;
6574
7653
  const xl = columns?.xl ?? 4;
6575
- const css = React3__default.default.useMemo(
7654
+ const css = React10__default.default.useMemo(
6576
7655
  () => [
6577
7656
  `#${gridId}{display:grid;grid-template-columns:repeat(${sm},1fr);gap:1rem}`,
6578
7657
  `@media(min-width:768px){#${gridId}{grid-template-columns:repeat(${md},1fr)}}`,
@@ -6650,12 +7729,12 @@ function SearchInput({
6650
7729
  className,
6651
7730
  classNames
6652
7731
  }) {
6653
- const mergedOptions = React3.useMemo(
7732
+ const mergedOptions = React10.useMemo(
6654
7733
  () => categoryId ? { ...searchOptions, category: categoryId } : searchOptions ?? {},
6655
7734
  [searchOptions, categoryId]
6656
7735
  );
6657
7736
  const { results, isLoading, query, setQuery, clear } = useSearch(mergedOptions);
6658
- const handleValueChange = React3.useCallback(
7737
+ const handleValueChange = React10.useCallback(
6659
7738
  (value) => {
6660
7739
  setQuery(value);
6661
7740
  },
@@ -6754,7 +7833,7 @@ function CategoryFilter({
6754
7833
  classNames
6755
7834
  }) {
6756
7835
  const { categories, isLoading } = useCategories();
6757
- const handleValueChange = React3.useCallback(
7836
+ const handleValueChange = React10.useCallback(
6758
7837
  (value) => {
6759
7838
  onSelect(value === ALL_VALUE ? null : String(value));
6760
7839
  },
@@ -6821,10 +7900,10 @@ function DiscountInput({
6821
7900
  className,
6822
7901
  classNames
6823
7902
  }) {
6824
- const [code, setCode] = React3.useState("");
6825
- const [appliedValidation, setAppliedValidation] = React3.useState(null);
7903
+ const [code, setCode] = React10.useState("");
7904
+ const [appliedValidation, setAppliedValidation] = React10.useState(null);
6826
7905
  const { validate, isValidating, error } = useValidateDiscount();
6827
- const handleApply = React3.useCallback(async () => {
7906
+ const handleApply = React10.useCallback(async () => {
6828
7907
  const trimmed = code.trim();
6829
7908
  if (!trimmed) return;
6830
7909
  const result = await validate(trimmed, orderSubtotal, locationId);
@@ -6837,12 +7916,12 @@ function DiscountInput({
6837
7916
  }
6838
7917
  }
6839
7918
  }, [code, validate, orderSubtotal, locationId, onApply]);
6840
- const handleClear = React3.useCallback(() => {
7919
+ const handleClear = React10.useCallback(() => {
6841
7920
  setCode("");
6842
7921
  setAppliedValidation(null);
6843
7922
  onClear?.();
6844
7923
  }, [onClear]);
6845
- const handleKeyDown = React3.useCallback(
7924
+ const handleKeyDown = React10.useCallback(
6846
7925
  (e) => {
6847
7926
  if (e.key === "Enter") {
6848
7927
  void handleApply();
@@ -6933,7 +8012,7 @@ function CategoryGrid({
6933
8012
  enabled: categoriesProp === void 0
6934
8013
  });
6935
8014
  const categories = categoriesProp ?? fetched;
6936
- const rawId = React3__default.default.useId();
8015
+ const rawId = React10__default.default.useId();
6937
8016
  const gridId = `cimplify-cat-grid-${rawId.replace(/:/g, "")}`;
6938
8017
  const sm = columns?.sm ?? 2;
6939
8018
  const md = columns?.md ?? 3;
@@ -7159,7 +8238,7 @@ function OrderSummary({
7159
8238
  /* @__PURE__ */ jsxRuntime.jsx("p", { children: order.delivery_address })
7160
8239
  ] }),
7161
8240
  /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-order-items": true, className: classNames?.items, children: order.items.map(
7162
- (item) => renderLineItem ? /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: renderLineItem(item) }, item.id) : /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-order-line-item": true, className: classNames?.lineItem, children: [
8241
+ (item) => renderLineItem ? /* @__PURE__ */ jsxRuntime.jsx(React10__default.default.Fragment, { children: renderLineItem(item) }, item.id) : /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-order-line-item": true, className: classNames?.lineItem, children: [
7163
8242
  /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-order-line-info": true, children: [
7164
8243
  /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-order-line-qty": true, children: [
7165
8244
  item.quantity,
@@ -7594,9 +8673,9 @@ function DateSlotPicker({
7594
8673
  className,
7595
8674
  classNames
7596
8675
  }) {
7597
- const [offset, setOffset] = React3.useState(0);
7598
- const [selectedDate, setSelectedDate] = React3.useState(toDateString(/* @__PURE__ */ new Date()));
7599
- const dateRange = React3.useMemo(() => {
8676
+ const [offset, setOffset] = React10.useState(0);
8677
+ const [selectedDate, setSelectedDate] = React10.useState(toDateString(/* @__PURE__ */ new Date()));
8678
+ const dateRange = React10.useMemo(() => {
7600
8679
  const today = /* @__PURE__ */ new Date();
7601
8680
  const start = addDays(today, offset);
7602
8681
  const dates = [];
@@ -7619,25 +8698,25 @@ function DateSlotPicker({
7619
8698
  }
7620
8699
  );
7621
8700
  const days = availabilityProp ?? fetchedDays;
7622
- const availabilityMap = React3.useMemo(() => {
8701
+ const availabilityMap = React10.useMemo(() => {
7623
8702
  const map = /* @__PURE__ */ new Map();
7624
8703
  for (const day of days) {
7625
8704
  map.set(day.date, day);
7626
8705
  }
7627
8706
  return map;
7628
8707
  }, [days]);
7629
- const handlePrev = React3.useCallback(() => {
8708
+ const handlePrev = React10.useCallback(() => {
7630
8709
  setOffset((prev) => Math.max(0, prev - daysToShow));
7631
8710
  }, [daysToShow]);
7632
- const handleNext = React3.useCallback(() => {
8711
+ const handleNext = React10.useCallback(() => {
7633
8712
  setOffset((prev) => prev + daysToShow);
7634
8713
  }, [daysToShow]);
7635
- const handleDateChange = React3.useCallback((value) => {
8714
+ const handleDateChange = React10.useCallback((value) => {
7636
8715
  if (typeof value === "string") {
7637
8716
  setSelectedDate(value);
7638
8717
  }
7639
8718
  }, []);
7640
- const handleSlotSelect = React3.useCallback(
8719
+ const handleSlotSelect = React10.useCallback(
7641
8720
  (slot) => {
7642
8721
  onSlotSelect?.(slot, selectedDate);
7643
8722
  },
@@ -8140,7 +9219,7 @@ function DefaultCatalogueLayout({
8140
9219
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg font-medium", children: "No products found" }),
8141
9220
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Try adjusting your filters" })
8142
9221
  ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 gap-4", children: products.map(
8143
- (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
9222
+ (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React10__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
8144
9223
  ProductCard,
8145
9224
  {
8146
9225
  product,
@@ -8247,7 +9326,7 @@ function CompactCatalogueLayout({
8247
9326
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg font-medium", children: "No items found" }),
8248
9327
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Try a different category or search" })
8249
9328
  ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 lg:grid-cols-3 gap-5", children: products.map(
8250
- (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
9329
+ (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React10__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
8251
9330
  ProductCard,
8252
9331
  {
8253
9332
  product,
@@ -8270,8 +9349,8 @@ var BUILT_IN_LAYOUTS = {
8270
9349
  ["compact" /* Compact */]: CompactCatalogueLayout
8271
9350
  };
8272
9351
  function useDebounce(value, delay) {
8273
- const [debounced, setDebounced] = React3__default.default.useState(value);
8274
- React3__default.default.useEffect(() => {
9352
+ const [debounced, setDebounced] = React10__default.default.useState(value);
9353
+ React10__default.default.useEffect(() => {
8275
9354
  const timer = setTimeout(() => setDebounced(value), delay);
8276
9355
  return () => clearTimeout(timer);
8277
9356
  }, [value, delay]);
@@ -8295,15 +9374,15 @@ function CataloguePage({
8295
9374
  className,
8296
9375
  classNames
8297
9376
  }) {
8298
- const [selectedCategory, setSelectedCategory] = React3.useState(null);
8299
- const [searchQuery, setSearchQuery] = React3.useState("");
8300
- const [sortBy, setSortBy] = React3.useState(defaultSort?.by ?? "created_at");
8301
- const [sortOrder, setSortOrder] = React3.useState(defaultSort?.order ?? "desc");
8302
- const [inStockOnly, setInStockOnly] = React3.useState(false);
8303
- const [selectedTags, setSelectedTags] = React3.useState([]);
8304
- const [minPrice, setMinPrice] = React3.useState("");
8305
- const [maxPrice, setMaxPrice] = React3.useState("");
8306
- const [page, setPage] = React3.useState(1);
9377
+ const [selectedCategory, setSelectedCategory] = React10.useState(null);
9378
+ const [searchQuery, setSearchQuery] = React10.useState("");
9379
+ const [sortBy, setSortBy] = React10.useState(defaultSort?.by ?? "created_at");
9380
+ const [sortOrder, setSortOrder] = React10.useState(defaultSort?.order ?? "desc");
9381
+ const [inStockOnly, setInStockOnly] = React10.useState(false);
9382
+ const [selectedTags, setSelectedTags] = React10.useState([]);
9383
+ const [minPrice, setMinPrice] = React10.useState("");
9384
+ const [maxPrice, setMaxPrice] = React10.useState("");
9385
+ const [page, setPage] = React10.useState(1);
8307
9386
  const debouncedSearch = useDebounce(searchQuery, 300);
8308
9387
  const { products: fetchedProducts, isLoading, pagination } = useProducts({
8309
9388
  enabled: productsProp === void 0,
@@ -8324,22 +9403,22 @@ function CataloguePage({
8324
9403
  const products = productsProp ?? fetchedProducts;
8325
9404
  const categories = categoriesProp ?? fetchedCategories;
8326
9405
  const totalPages = pagination?.total_pages ?? 1;
8327
- const handleCategoryChange = React3.useCallback((id) => {
9406
+ const handleCategoryChange = React10.useCallback((id) => {
8328
9407
  setSelectedCategory(id);
8329
9408
  setPage(1);
8330
9409
  }, []);
8331
- const handleSortChange = React3.useCallback((by, order) => {
9410
+ const handleSortChange = React10.useCallback((by, order) => {
8332
9411
  setSortBy(by);
8333
9412
  setSortOrder(order);
8334
9413
  setPage(1);
8335
9414
  }, []);
8336
- const handleTagToggle = React3.useCallback((tag) => {
9415
+ const handleTagToggle = React10.useCallback((tag) => {
8337
9416
  setSelectedTags(
8338
9417
  (prev) => prev.includes(tag) ? prev.filter((t) => t !== tag) : [...prev, tag]
8339
9418
  );
8340
9419
  setPage(1);
8341
9420
  }, []);
8342
- const handlePriceRangeChange = React3.useCallback((min, max) => {
9421
+ const handlePriceRangeChange = React10.useCallback((min, max) => {
8343
9422
  setMinPrice(min);
8344
9423
  setMaxPrice(max);
8345
9424
  setPage(1);
@@ -8999,12 +10078,161 @@ function DigitalProductLayout({
8999
10078
  )
9000
10079
  ] });
9001
10080
  }
10081
+ function BundleProductLayout({
10082
+ product,
10083
+ onAddToCart,
10084
+ renderBreadcrumb,
10085
+ relatedProducts,
10086
+ showRelated = true,
10087
+ className
10088
+ }) {
10089
+ const images = product.images || (product.image_url ? [product.image_url] : []);
10090
+ const components = product.components || [];
10091
+ const onSale = chunkPEDLCL72_js.isOnSale(product);
10092
+ const discount = chunkPEDLCL72_js.getDiscountPercentage(product);
10093
+ const baseTotal = components.reduce(
10094
+ (sum, c) => sum + chunkPEDLCL72_js.parsePrice(c.effective_price ?? 0) * (c.quantity ?? 1),
10095
+ 0
10096
+ );
10097
+ const bundlePrice = chunkPEDLCL72_js.parsePrice(product.default_price);
10098
+ const savings = baseTotal > bundlePrice ? baseTotal - bundlePrice : 0;
10099
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-product-layout": "bundle", className: cn("space-y-8", className), children: [
10100
+ renderBreadcrumb?.(product),
10101
+ /* @__PURE__ */ jsxRuntime.jsx(
10102
+ TwoColumnGrid,
10103
+ {
10104
+ left: /* @__PURE__ */ jsxRuntime.jsx(
10105
+ ProductImageGallery,
10106
+ {
10107
+ images,
10108
+ productName: product.name
10109
+ }
10110
+ ),
10111
+ right: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
10112
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
10113
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-semibold text-indigo-700 bg-indigo-50 border border-indigo-200/60 px-2.5 py-1 rounded-md", children: "Bundle" }),
10114
+ savings > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs font-semibold text-emerald-700 bg-emerald-50 border border-emerald-200/60 px-2.5 py-1 rounded-md", children: [
10115
+ "Save ",
10116
+ discount,
10117
+ "%"
10118
+ ] }),
10119
+ /* @__PURE__ */ jsxRuntime.jsx(TagPills, { tags: product.tags || [] })
10120
+ ] }),
10121
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10122
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { "data-cimplify-product-layout-name": true, className: "text-3xl lg:text-4xl font-bold tracking-tight", children: product.name }),
10123
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-3 mt-2", children: [
10124
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price, className: "text-2xl font-bold" }),
10125
+ onSale && baseTotal > 0 && /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: baseTotal, className: "text-lg text-muted-foreground line-through" })
10126
+ ] })
10127
+ ] }),
10128
+ product.description && /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-product-layout-description": true, className: "text-muted-foreground leading-relaxed", children: product.description }),
10129
+ components.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-bundle-components": true, className: "space-y-3", children: [
10130
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-semibold", children: "Included in this bundle" }),
10131
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y divide-border border border-border rounded-lg overflow-hidden", children: components.map((component) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 p-3", children: [
10132
+ component.product_image_url && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-12 h-12 rounded-lg overflow-hidden bg-muted shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: component.product_image_url, alt: component.product_name, className: "w-full h-full object-cover" }) }),
10133
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
10134
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium truncate", children: component.product_name }),
10135
+ component.quantity > 1 && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground", children: [
10136
+ "Qty: ",
10137
+ component.quantity
10138
+ ] }),
10139
+ component.allow_variant_choice && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-violet-600 font-medium", children: "Choose variant" })
10140
+ ] }),
10141
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: component.effective_price ?? 0, className: "text-sm text-muted-foreground shrink-0" })
10142
+ ] }, component.id)) })
10143
+ ] }),
10144
+ savings > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-bundle-savings": true, className: "flex items-center gap-2 p-3 bg-emerald-50 border border-emerald-200/60 text-sm text-emerald-800", children: [
10145
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-4 h-4 shrink-0", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 13l4 4L19 7" }) }),
10146
+ "You save ",
10147
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: savings, className: "font-semibold" }),
10148
+ " with this bundle"
10149
+ ] }),
10150
+ /* @__PURE__ */ jsxRuntime.jsx(CustomAttributesTable, { attributes: product.custom_attributes || [] }),
10151
+ /* @__PURE__ */ jsxRuntime.jsx(
10152
+ ProductCustomizer,
10153
+ {
10154
+ product,
10155
+ onAddToCart
10156
+ }
10157
+ )
10158
+ ] })
10159
+ }
10160
+ ),
10161
+ showRelated && relatedProducts && relatedProducts.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(RelatedProductsSection, { products: relatedProducts })
10162
+ ] });
10163
+ }
10164
+ function CompositeProductLayout({
10165
+ product,
10166
+ onAddToCart,
10167
+ renderBreadcrumb,
10168
+ relatedProducts,
10169
+ showRelated = true,
10170
+ className
10171
+ }) {
10172
+ const images = product.images || (product.image_url ? [product.image_url] : []);
10173
+ const groups = product.groups || [];
10174
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-product-layout": "composite", className: cn("space-y-8", className), children: [
10175
+ renderBreadcrumb?.(product),
10176
+ /* @__PURE__ */ jsxRuntime.jsx(
10177
+ TwoColumnGrid,
10178
+ {
10179
+ left: /* @__PURE__ */ jsxRuntime.jsx(
10180
+ ProductImageGallery,
10181
+ {
10182
+ images,
10183
+ productName: product.name
10184
+ }
10185
+ ),
10186
+ right: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
10187
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
10188
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-semibold text-violet-700 bg-violet-50 border border-violet-200/60 px-2.5 py-1 rounded-md", children: "Build Your Own" }),
10189
+ groups.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs font-medium text-muted-foreground bg-muted px-2.5 py-1 rounded-md", children: [
10190
+ groups.length,
10191
+ " choice",
10192
+ groups.length !== 1 ? "s" : ""
10193
+ ] }),
10194
+ /* @__PURE__ */ jsxRuntime.jsx(TagPills, { tags: product.tags || [] })
10195
+ ] }),
10196
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10197
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { "data-cimplify-product-layout-name": true, className: "text-3xl lg:text-4xl font-bold tracking-tight", children: product.name }),
10198
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-lg text-muted-foreground mt-2", children: [
10199
+ "From ",
10200
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price, className: "font-semibold text-foreground" })
10201
+ ] })
10202
+ ] }),
10203
+ product.description && /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-product-layout-description": true, className: "text-muted-foreground leading-relaxed", children: product.description }),
10204
+ groups.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-composite-overview": true, className: "flex flex-wrap gap-2", children: groups.map((group) => {
10205
+ const availableCount = group.components.filter((c) => c.is_available && !c.is_archived).length;
10206
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 px-3 py-2 bg-muted rounded-lg text-sm", children: [
10207
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: group.name }),
10208
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground text-xs", children: [
10209
+ group.min_selections > 0 ? `Pick ${group.min_selections}` : "Optional",
10210
+ ` \xB7 ${availableCount} option${availableCount !== 1 ? "s" : ""}`
10211
+ ] })
10212
+ ] }, group.id);
10213
+ }) }),
10214
+ /* @__PURE__ */ jsxRuntime.jsx(CustomAttributesTable, { attributes: product.custom_attributes || [] }),
10215
+ /* @__PURE__ */ jsxRuntime.jsx(
10216
+ ProductCustomizer,
10217
+ {
10218
+ product,
10219
+ onAddToCart
10220
+ }
10221
+ )
10222
+ ] })
10223
+ }
10224
+ ),
10225
+ showRelated && relatedProducts && relatedProducts.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(RelatedProductsSection, { products: relatedProducts })
10226
+ ] });
10227
+ }
9002
10228
  var ProductTemplate = /* @__PURE__ */ ((ProductTemplate2) => {
9003
10229
  ProductTemplate2["Default"] = "default";
9004
10230
  ProductTemplate2["Food"] = "food";
9005
10231
  ProductTemplate2["Wholesale"] = "wholesale";
9006
10232
  ProductTemplate2["Service"] = "service";
9007
10233
  ProductTemplate2["Digital"] = "digital";
10234
+ ProductTemplate2["Bundle"] = "bundle";
10235
+ ProductTemplate2["Composite"] = "composite";
9008
10236
  ProductTemplate2["Physical"] = "physical";
9009
10237
  return ProductTemplate2;
9010
10238
  })(ProductTemplate || {});
@@ -9013,6 +10241,8 @@ var BUILT_IN_LAYOUTS2 = {
9013
10241
  ["wholesale" /* Wholesale */]: WholesaleProductLayout,
9014
10242
  ["service" /* Service */]: ServiceProductLayout,
9015
10243
  ["digital" /* Digital */]: DigitalProductLayout,
10244
+ ["bundle" /* Bundle */]: BundleProductLayout,
10245
+ ["composite" /* Composite */]: CompositeProductLayout,
9016
10246
  ["default" /* Default */]: DefaultProductLayout
9017
10247
  };
9018
10248
  function resolveTemplateKey(product) {
@@ -9020,19 +10250,25 @@ function resolveTemplateKey(product) {
9020
10250
  if (typeof metaTemplate === "string" && metaTemplate.trim()) {
9021
10251
  return metaTemplate.trim();
9022
10252
  }
10253
+ if (product.type === chunkR4AKAGZQ_js.PRODUCT_TYPE.Bundle) {
10254
+ return "bundle" /* Bundle */;
10255
+ }
10256
+ if (product.type === chunkR4AKAGZQ_js.PRODUCT_TYPE.Composite) {
10257
+ return "composite" /* Composite */;
10258
+ }
9023
10259
  if (product.quantity_pricing && product.quantity_pricing.length > 1) {
9024
10260
  return "wholesale" /* Wholesale */;
9025
10261
  }
9026
- if (product.type === chunk4JSRPSNA_js.PRODUCT_TYPE.Service) {
10262
+ if (product.type === chunkR4AKAGZQ_js.PRODUCT_TYPE.Service) {
9027
10263
  return "service" /* Service */;
9028
10264
  }
9029
- if (product.type === chunk4JSRPSNA_js.PRODUCT_TYPE.Digital) {
10265
+ if (product.type === chunkR4AKAGZQ_js.PRODUCT_TYPE.Digital) {
9030
10266
  return "digital" /* Digital */;
9031
10267
  }
9032
- if (product.render_hint === chunk4JSRPSNA_js.RENDER_HINT.Food) {
10268
+ if (product.render_hint === chunkR4AKAGZQ_js.RENDER_HINT.Food) {
9033
10269
  return "food" /* Food */;
9034
10270
  }
9035
- if (product.render_hint === chunk4JSRPSNA_js.RENDER_HINT.Physical) {
10271
+ if (product.render_hint === chunkR4AKAGZQ_js.RENDER_HINT.Physical) {
9036
10272
  return "physical" /* Physical */;
9037
10273
  }
9038
10274
  return "default" /* Default */;
@@ -9298,9 +10534,9 @@ function DefaultCollectionLayout({
9298
10534
  onQuickAdd,
9299
10535
  className
9300
10536
  }) {
9301
- const [searchQuery, setSearchQuery] = React3.useState("");
9302
- const [activeTag, setActiveTag] = React3.useState(null);
9303
- const collectionTags = React3.useMemo(() => {
10537
+ const [searchQuery, setSearchQuery] = React10.useState("");
10538
+ const [activeTag, setActiveTag] = React10.useState(null);
10539
+ const collectionTags = React10.useMemo(() => {
9304
10540
  const tagSet = /* @__PURE__ */ new Set();
9305
10541
  for (const p of products) {
9306
10542
  if (p.tags) {
@@ -9309,7 +10545,7 @@ function DefaultCollectionLayout({
9309
10545
  }
9310
10546
  return Array.from(tagSet).slice(0, 6);
9311
10547
  }, [products]);
9312
- const filtered = React3.useMemo(() => {
10548
+ const filtered = React10.useMemo(() => {
9313
10549
  let result = products;
9314
10550
  if (searchQuery.trim().length >= 2) {
9315
10551
  const q = searchQuery.toLowerCase();
@@ -9384,7 +10620,7 @@ function DefaultCollectionLayout({
9384
10620
  ] })
9385
10621
  ] }),
9386
10622
  filtered.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4", children: filtered.map(
9387
- (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
10623
+ (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React10__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
9388
10624
  ProductCard,
9389
10625
  {
9390
10626
  product,
@@ -9437,7 +10673,7 @@ function FeaturedCollectionLayout({
9437
10673
  ] })
9438
10674
  ] }),
9439
10675
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6", children: products.map(
9440
- (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
10676
+ (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React10__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
9441
10677
  ProductCard,
9442
10678
  {
9443
10679
  product,
@@ -9459,10 +10695,10 @@ function CatalogueCollectionLayout({
9459
10695
  onQuickAdd,
9460
10696
  className
9461
10697
  }) {
9462
- const [searchQuery, setSearchQuery] = React3.useState("");
9463
- const [activeCategory, setActiveCategory] = React3.useState(null);
9464
- const [sortBy, setSortBy] = React3.useState("default");
9465
- const categories = React3.useMemo(() => {
10698
+ const [searchQuery, setSearchQuery] = React10.useState("");
10699
+ const [activeCategory, setActiveCategory] = React10.useState(null);
10700
+ const [sortBy, setSortBy] = React10.useState("default");
10701
+ const categories = React10.useMemo(() => {
9466
10702
  const cats = /* @__PURE__ */ new Map();
9467
10703
  for (const p of products) {
9468
10704
  if (p.category_id && p.tags) {
@@ -9473,7 +10709,7 @@ function CatalogueCollectionLayout({
9473
10709
  }
9474
10710
  return Array.from(cats.values()).slice(0, 8);
9475
10711
  }, [products]);
9476
- const filtered = React3.useMemo(() => {
10712
+ const filtered = React10.useMemo(() => {
9477
10713
  let result = products;
9478
10714
  if (searchQuery.trim().length >= 2) {
9479
10715
  const q = searchQuery.toLowerCase();
@@ -9561,7 +10797,7 @@ function CatalogueCollectionLayout({
9561
10797
  ] })
9562
10798
  ] }),
9563
10799
  filtered.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4", children: filtered.map(
9564
- (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
10800
+ (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React10__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
9565
10801
  ProductCard,
9566
10802
  {
9567
10803
  product,
@@ -9740,13 +10976,13 @@ function OrderHistoryPage({
9740
10976
  className,
9741
10977
  classNames
9742
10978
  }) {
9743
- const [statusFilter, setStatusFilter] = React3.useState(void 0);
9744
- const [selectedOrder, setSelectedOrder] = React3.useState(null);
9745
- const handleTabChange = React3.useCallback((value) => {
10979
+ const [statusFilter, setStatusFilter] = React10.useState(void 0);
10980
+ const [selectedOrder, setSelectedOrder] = React10.useState(null);
10981
+ const handleTabChange = React10.useCallback((value) => {
9746
10982
  const filter = STATUS_FILTERS.find((f) => f.tabValue === value);
9747
10983
  setStatusFilter(filter?.value);
9748
10984
  }, []);
9749
- const handleOrderClick = React3.useCallback(
10985
+ const handleOrderClick = React10.useCallback(
9750
10986
  (order) => {
9751
10987
  if (onOrderNavigate) {
9752
10988
  onOrderNavigate(order);
@@ -9756,7 +10992,7 @@ function OrderHistoryPage({
9756
10992
  },
9757
10993
  [onOrderNavigate]
9758
10994
  );
9759
- const handleBack = React3.useCallback(() => {
10995
+ const handleBack = React10.useCallback(() => {
9760
10996
  setSelectedOrder(null);
9761
10997
  }, []);
9762
10998
  const activeTabValue = STATUS_FILTERS.find((f) => f.value === statusFilter)?.tabValue ?? "all";
@@ -9941,7 +11177,7 @@ function DefaultSearchLayout({
9941
11177
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Try a different search term" }),
9942
11178
  /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: clear, className: "text-sm font-medium text-primary mt-4 hover:underline", children: "Clear search" })
9943
11179
  ] }) : results.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 gap-4", children: results.map(
9944
- (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
11180
+ (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React10__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
9945
11181
  ProductCard,
9946
11182
  {
9947
11183
  product,
@@ -10043,7 +11279,7 @@ function CompactSearchLayout({
10043
11279
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Try a different search term" }),
10044
11280
  /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: clear, className: "text-sm font-medium text-primary mt-4 hover:underline", children: "Clear search" })
10045
11281
  ] }) : results.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 lg:grid-cols-3 gap-5", children: results.map(
10046
- (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React3__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
11282
+ (product) => renderCard ? /* @__PURE__ */ jsxRuntime.jsx(React10__default.default.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsxRuntime.jsx(
10047
11283
  ProductCard,
10048
11284
  {
10049
11285
  product,
@@ -10374,11 +11610,11 @@ function DeliveryEstimate({
10374
11610
  }) {
10375
11611
  const context = useOptionalCimplifyClient();
10376
11612
  const client = context?.client ?? null;
10377
- const [result, setResult] = React3.useState(null);
10378
- const [isLoading, setIsLoading] = React3.useState(true);
10379
- const [error, setError] = React3.useState(null);
10380
- const requestIdRef = React3.useRef(0);
10381
- React3.useEffect(() => {
11613
+ const [result, setResult] = React10.useState(null);
11614
+ const [isLoading, setIsLoading] = React10.useState(true);
11615
+ const [error, setError] = React10.useState(null);
11616
+ const requestIdRef = React10.useRef(0);
11617
+ React10.useEffect(() => {
10382
11618
  if (!client) return;
10383
11619
  const nextRequestId = ++requestIdRef.current;
10384
11620
  setIsLoading(true);
@@ -10459,10 +11695,10 @@ function CurrencySelector({
10459
11695
  }) {
10460
11696
  const context = useOptionalCimplifyClient();
10461
11697
  const client = context?.client ?? null;
10462
- const [rates, setRates] = React3.useState({});
10463
- const [isLoadingRates, setIsLoadingRates] = React3.useState(false);
10464
- const requestIdRef = React3.useRef(0);
10465
- React3.useEffect(() => {
11698
+ const [rates, setRates] = React10.useState({});
11699
+ const [isLoadingRates, setIsLoadingRates] = React10.useState(false);
11700
+ const requestIdRef = React10.useRef(0);
11701
+ React10.useEffect(() => {
10466
11702
  if (!showRate || !baseCurrency || !client) return;
10467
11703
  const targets = currencies.filter((c) => c !== baseCurrency);
10468
11704
  if (targets.length === 0) return;
@@ -10610,7 +11846,7 @@ function ResourcePicker({
10610
11846
 
10611
11847
  Object.defineProperty(exports, "getVariantDisplayName", {
10612
11848
  enumerable: true,
10613
- get: function () { return chunk4JSRPSNA_js.getVariantDisplayName; }
11849
+ get: function () { return chunkR4AKAGZQ_js.getVariantDisplayName; }
10614
11850
  });
10615
11851
  exports.AccommodationCard = AccommodationCard;
10616
11852
  exports.Ad = Ad;
@@ -10622,6 +11858,8 @@ exports.AvailabilityBadge = AvailabilityBadge;
10622
11858
  exports.BillingPlanSelector = BillingPlanSelector;
10623
11859
  exports.BookingCard = BookingCard;
10624
11860
  exports.BookingList = BookingList;
11861
+ exports.BundleProductCard = BundleProductCard;
11862
+ exports.BundleProductLayout = BundleProductLayout;
10625
11863
  exports.BundleSelector = BundleSelector;
10626
11864
  exports.CardImage = CardImage;
10627
11865
  exports.CardShell = CardShell;
@@ -10644,9 +11882,12 @@ exports.CompactCartLayout = CompactCartLayout;
10644
11882
  exports.CompactCatalogueLayout = CompactCatalogueLayout;
10645
11883
  exports.CompactSearchLayout = CompactSearchLayout;
10646
11884
  exports.CompactServiceCard = CompactServiceCard;
11885
+ exports.CompositeProductCard = CompositeProductCard;
11886
+ exports.CompositeProductLayout = CompositeProductLayout;
10647
11887
  exports.CompositeSelector = CompositeSelector;
10648
11888
  exports.CurrencySelector = CurrencySelector;
10649
11889
  exports.CustomAttributesTable = CustomAttributesTable;
11890
+ exports.CustomerInputFields = CustomerInputFields;
10650
11891
  exports.DateSlotPicker = DateSlotPicker;
10651
11892
  exports.DealBanner = DealBanner;
10652
11893
  exports.DealsPage = DealsPage;
@@ -10749,6 +11990,8 @@ exports.useRecommendations = useRecommendations;
10749
11990
  exports.useSearch = useSearch;
10750
11991
  exports.useServiceAvailability = useServiceAvailability;
10751
11992
  exports.useServices = useServices;
11993
+ exports.useSubscription = useSubscription;
11994
+ exports.useSubscriptions = useSubscriptions;
10752
11995
  exports.useTaxonomies = useTaxonomies;
10753
11996
  exports.useTaxonomy = useTaxonomy;
10754
11997
  exports.useTaxonomyPath = useTaxonomyPath;