@cimplify/sdk 0.20.2 → 0.22.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.
Files changed (34) hide show
  1. package/dist/advanced.d.mts +2 -2
  2. package/dist/advanced.d.ts +2 -2
  3. package/dist/advanced.js +20 -20
  4. package/dist/advanced.mjs +1 -1
  5. package/dist/{chunk-WXFEO3LT.js → chunk-A7IQN5EK.js} +17 -17
  6. package/dist/{chunk-VTMRPTQ7.mjs → chunk-R4EYMPSN.mjs} +39 -0
  7. package/dist/{chunk-UVBJDWIV.js → chunk-VYSXEDBV.js} +39 -0
  8. package/dist/{chunk-X23RNZAD.mjs → chunk-W3DMONZR.mjs} +1 -1
  9. package/dist/{client-D4E9aJy7.d.mts → client-uvCOGdBp.d.ts} +24 -2
  10. package/dist/{client-VyO6Bqz2.d.ts → client-v1NFqZFG.d.mts} +24 -2
  11. package/dist/index.d.mts +4 -4
  12. package/dist/index.d.ts +4 -4
  13. package/dist/index.js +58 -58
  14. package/dist/index.mjs +2 -2
  15. package/dist/{payment-CKqMU4xT.d.ts → payment-DazihbCY.d.mts} +1 -0
  16. package/dist/{payment-CKqMU4xT.d.mts → payment-DazihbCY.d.ts} +1 -0
  17. package/dist/{price-e4beObLZ.d.ts → price-5_L8WK6Q.d.ts} +1 -1
  18. package/dist/{price-BqV_DjjQ.d.mts → price-BcHVTqqu.d.mts} +1 -1
  19. package/dist/react.d.mts +73 -9
  20. package/dist/react.d.ts +73 -9
  21. package/dist/react.js +329 -114
  22. package/dist/react.mjs +312 -99
  23. package/dist/styles.css +1 -1
  24. package/dist/utils.d.mts +2 -2
  25. package/dist/utils.d.ts +2 -2
  26. package/package.json +1 -1
  27. package/registry/booking-card.json +1 -1
  28. package/registry/booking-page.json +1 -1
  29. package/registry/order-detail-page.json +1 -1
  30. package/registry/order-history-page.json +1 -1
  31. package/registry/order-history.json +1 -1
  32. package/registry/order-summary.json +1 -1
  33. package/registry/product-card.json +1 -1
  34. package/registry/service-card.json +1 -1
package/dist/react.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
- import { getVariantDisplayName, createCimplifyClient } from './chunk-X23RNZAD.mjs';
3
- export { getVariantDisplayName } from './chunk-X23RNZAD.mjs';
4
- import { ELEMENT_TYPES, EVENT_TYPES } from './chunk-VTMRPTQ7.mjs';
2
+ import { getVariantDisplayName, createCimplifyClient } from './chunk-W3DMONZR.mjs';
3
+ export { getVariantDisplayName } from './chunk-W3DMONZR.mjs';
4
+ import { ELEMENT_TYPES, EVENT_TYPES } from './chunk-R4EYMPSN.mjs';
5
5
  import { isSupportedCurrency, formatPrice, parsePrice, isOnSale, getDiscountPercentage, getBasePrice } from './chunk-JFT63H34.mjs';
6
6
  import React3, { createContext, useContext, useState, useEffect, useRef, useMemo, useSyncExternalStore, useCallback, useId } from 'react';
7
7
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
@@ -439,6 +439,9 @@ function buildLineKey(productId, options) {
439
439
  if (options.staffId) {
440
440
  parts.push(`st:${options.staffId}`);
441
441
  }
442
+ if (options.resourceId) {
443
+ parts.push(`r:${options.resourceId}`);
444
+ }
442
445
  return parts.join("|");
443
446
  }
444
447
  function calculateLineSubtotal(item) {
@@ -756,7 +759,8 @@ function createCartStore(params) {
756
759
  composite_selections: normalizedOptions.compositeSelections,
757
760
  scheduled_start: normalizedOptions.scheduledStart,
758
761
  scheduled_end: normalizedOptions.scheduledEnd,
759
- staff_id: normalizedOptions.staffId
762
+ staff_id: normalizedOptions.staffId,
763
+ resource_id: normalizedOptions.resourceId
760
764
  });
761
765
  if (!result.ok) {
762
766
  throw result.error;
@@ -887,6 +891,14 @@ function createCartStore(params) {
887
891
  await initializePromise;
888
892
  initializePromise = null;
889
893
  }
894
+ async function reorder(orderId) {
895
+ const result = await client.cart.reorderFromOrder(orderId);
896
+ if (!result.ok) {
897
+ throw result.error;
898
+ }
899
+ await sync();
900
+ return result.value;
901
+ }
890
902
  return {
891
903
  subscribe(listener) {
892
904
  listeners.add(listener);
@@ -902,7 +914,8 @@ function createCartStore(params) {
902
914
  removeItem,
903
915
  updateQuantity,
904
916
  clearCart,
905
- sync
917
+ sync,
918
+ reorder
906
919
  };
907
920
  }
908
921
  function getStoreKey(client, locationId, isDemoMode) {
@@ -983,6 +996,12 @@ function useCart(options = {}) {
983
996
  throw syncError;
984
997
  }
985
998
  }, [store]);
999
+ const reorder = useCallback(
1000
+ async (orderId) => {
1001
+ return store.reorder(orderId);
1002
+ },
1003
+ [store]
1004
+ );
986
1005
  const itemCount = useMemo(
987
1006
  () => snapshot.items.reduce((sum, item) => sum + item.quantity, 0),
988
1007
  [snapshot.items]
@@ -1000,7 +1019,8 @@ function useCart(options = {}) {
1000
1019
  removeItem,
1001
1020
  updateQuantity,
1002
1021
  clearCart,
1003
- sync
1022
+ sync,
1023
+ reorder
1004
1024
  };
1005
1025
  }
1006
1026
  var LOCATION_STORAGE_KEY = "cimplify_location_id";
@@ -2003,6 +2023,7 @@ function useCategories(options = {}) {
2003
2023
  }, [cacheKey, load]);
2004
2024
  return { categories, isLoading, error, refetch };
2005
2025
  }
2026
+ var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "cancelled", "refunded"]);
2006
2027
  var orderCache = /* @__PURE__ */ new Map();
2007
2028
  var orderInflight = /* @__PURE__ */ new Map();
2008
2029
  function buildOrderCacheKey(client, orderId) {
@@ -2019,6 +2040,9 @@ function useOrder(orderId, options = {}) {
2019
2040
  const poll = options.poll ?? false;
2020
2041
  const pollInterval = options.pollInterval ?? 5e3;
2021
2042
  const requestIdRef = useRef(0);
2043
+ const previousStatusRef = useRef(null);
2044
+ const onStatusChangeRef = useRef(options.onStatusChange);
2045
+ onStatusChangeRef.current = options.onStatusChange;
2022
2046
  const cacheKey = useMemo(
2023
2047
  () => buildOrderCacheKey(client, normalizedOrderId),
2024
2048
  [client, normalizedOrderId]
@@ -2069,6 +2093,12 @@ function useOrder(orderId, options = {}) {
2069
2093
  if (nextRequestId === requestIdRef.current) {
2070
2094
  setOrder(value);
2071
2095
  setError(null);
2096
+ if (value && previousStatusRef.current !== null && previousStatusRef.current !== value.status) {
2097
+ onStatusChangeRef.current?.(previousStatusRef.current, value.status, value);
2098
+ }
2099
+ if (value) {
2100
+ previousStatusRef.current = value.status;
2101
+ }
2072
2102
  }
2073
2103
  } catch (loadError) {
2074
2104
  if (nextRequestId === requestIdRef.current) {
@@ -2085,8 +2115,9 @@ function useOrder(orderId, options = {}) {
2085
2115
  useEffect(() => {
2086
2116
  void load(false);
2087
2117
  }, [load]);
2118
+ const isTerminal = order ? TERMINAL_STATUSES.has(order.status) : false;
2088
2119
  useEffect(() => {
2089
- if (!poll || !enabled || normalizedOrderId.length === 0) {
2120
+ if (!poll || !enabled || normalizedOrderId.length === 0 || isTerminal) {
2090
2121
  return;
2091
2122
  }
2092
2123
  const timer = window.setInterval(() => {
@@ -2095,12 +2126,12 @@ function useOrder(orderId, options = {}) {
2095
2126
  return () => {
2096
2127
  window.clearInterval(timer);
2097
2128
  };
2098
- }, [enabled, load, normalizedOrderId, poll, pollInterval]);
2129
+ }, [enabled, isTerminal, load, normalizedOrderId, poll, pollInterval]);
2099
2130
  const refetch = useCallback(async () => {
2100
2131
  orderCache.delete(cacheKey);
2101
2132
  await load(true);
2102
2133
  }, [cacheKey, load]);
2103
- return { order, isLoading, error, refetch };
2134
+ return { order, isLoading, error, refetch, isTerminal };
2104
2135
  }
2105
2136
  var LOCATION_STORAGE_KEY2 = "cimplify_location_id";
2106
2137
  function readStoredLocationId() {
@@ -4457,6 +4488,7 @@ function useRecommendations(options = {}) {
4457
4488
  return { recommendations, intent, isLoading, error, refetch };
4458
4489
  }
4459
4490
  var deliveryFeeCache = /* @__PURE__ */ new Map();
4491
+ var deliveryFeeInflight = /* @__PURE__ */ new Map();
4460
4492
  function buildDeliveryFeeCacheKey(client, latitude, longitude, country) {
4461
4493
  return JSON.stringify({
4462
4494
  key: client.getPublicKey(),
@@ -4500,13 +4532,26 @@ function useDeliveryFee(options) {
4500
4532
  setIsLoading(true);
4501
4533
  const currentRequestId = ++requestIdRef.current;
4502
4534
  try {
4503
- const result = await client.delivery.getFee(latitude, longitude, country);
4504
- if (currentRequestId !== requestIdRef.current) return;
4505
- if (!result.ok) {
4506
- throw result.error;
4535
+ const existing = deliveryFeeInflight.get(cacheKey);
4536
+ const promise = existing ?? (async () => {
4537
+ const result = await client.delivery.getFee(latitude, longitude, country);
4538
+ if (!result.ok) {
4539
+ throw result.error;
4540
+ }
4541
+ return result.value;
4542
+ })();
4543
+ if (!existing) {
4544
+ deliveryFeeInflight.set(
4545
+ cacheKey,
4546
+ promise.finally(() => {
4547
+ deliveryFeeInflight.delete(cacheKey);
4548
+ })
4549
+ );
4507
4550
  }
4508
- deliveryFeeCache.set(cacheKey, result.value);
4509
- setFee(result.value);
4551
+ const value = await promise;
4552
+ if (currentRequestId !== requestIdRef.current) return;
4553
+ deliveryFeeCache.set(cacheKey, value);
4554
+ setFee(value);
4510
4555
  } catch (loadError) {
4511
4556
  if (currentRequestId !== requestIdRef.current) return;
4512
4557
  setError(loadError);
@@ -6850,11 +6895,8 @@ function ProductCard({
6850
6895
  "div",
6851
6896
  {
6852
6897
  "data-cimplify-product-card-image-container": true,
6853
- className: classNames?.imageContainer,
6854
- style: {
6855
- overflow: "hidden",
6856
- ...ASPECT_STYLES2[aspectRatio]
6857
- },
6898
+ className: cn("overflow-hidden rounded-t-xl", classNames?.imageContainer),
6899
+ style: ASPECT_STYLES2[aspectRatio],
6858
6900
  children: renderImage ? renderImage({
6859
6901
  src: imageUrl,
6860
6902
  alt: product.name,
@@ -6864,8 +6906,7 @@ function ProductCard({
6864
6906
  {
6865
6907
  src: imageUrl,
6866
6908
  alt: product.name,
6867
- className: classNames?.image,
6868
- style: { width: "100%", height: "100%", objectFit: "cover" },
6909
+ className: cn("w-full h-full object-cover transition-transform duration-300 group-hover:scale-105", classNames?.image),
6869
6910
  "data-cimplify-product-card-image": true
6870
6911
  }
6871
6912
  )
@@ -6875,13 +6916,13 @@ function ProductCard({
6875
6916
  "div",
6876
6917
  {
6877
6918
  "data-cimplify-product-card-body": true,
6878
- className: classNames?.body,
6919
+ className: cn("p-4 flex flex-col gap-1", classNames?.body),
6879
6920
  children: [
6880
6921
  /* @__PURE__ */ jsx(
6881
6922
  "span",
6882
6923
  {
6883
6924
  "data-cimplify-product-card-name": true,
6884
- className: classNames?.name,
6925
+ className: cn("font-semibold text-foreground leading-tight", classNames?.name),
6885
6926
  children: product.name
6886
6927
  }
6887
6928
  ),
@@ -6889,13 +6930,7 @@ function ProductCard({
6889
6930
  "span",
6890
6931
  {
6891
6932
  "data-cimplify-product-card-description": true,
6892
- className: classNames?.description,
6893
- style: {
6894
- display: "-webkit-box",
6895
- WebkitLineClamp: 2,
6896
- WebkitBoxOrient: "vertical",
6897
- overflow: "hidden"
6898
- },
6933
+ className: cn("text-sm text-muted-foreground line-clamp-2", classNames?.description),
6899
6934
  children: product.description
6900
6935
  }
6901
6936
  ),
@@ -6903,7 +6938,7 @@ function ProductCard({
6903
6938
  Price,
6904
6939
  {
6905
6940
  amount: product.default_price,
6906
- className: classNames?.price
6941
+ className: cn("text-sm font-medium text-foreground mt-1", classNames?.price)
6907
6942
  }
6908
6943
  )
6909
6944
  ]
@@ -6912,7 +6947,7 @@ function ProductCard({
6912
6947
  ] });
6913
6948
  if (mode === "page") {
6914
6949
  const linkHref = href ?? `/menu/${product.slug}`;
6915
- const linkClassName = cn("block no-underline text-[inherit]", className, classNames?.root);
6950
+ const linkClassName = cn("group block no-underline text-[inherit] rounded-xl border border-border bg-background transition-shadow duration-200 hover:shadow-md", className, classNames?.root);
6916
6951
  if (renderLink) {
6917
6952
  return renderLink({ href: linkHref, className: linkClassName, children: cardBody });
6918
6953
  }
@@ -6935,7 +6970,7 @@ function ProductCard({
6935
6970
  "data-cimplify-product-card": true,
6936
6971
  "data-display-mode": "card",
6937
6972
  className: cn(
6938
- "block w-full text-left bg-transparent border-none p-0 cursor-pointer font-[inherit] text-[inherit]",
6973
+ "group block w-full text-left p-0 cursor-pointer font-[inherit] text-[inherit] rounded-xl border border-border bg-background transition-shadow duration-200 hover:shadow-md",
6939
6974
  className,
6940
6975
  classNames?.root
6941
6976
  ),
@@ -7518,12 +7553,15 @@ function OrderSummary({
7518
7553
  orderId,
7519
7554
  poll = false,
7520
7555
  renderLineItem,
7556
+ onReorder,
7557
+ onStatusChange,
7521
7558
  className,
7522
7559
  classNames
7523
7560
  }) {
7524
7561
  const { order: fetched, isLoading } = useOrder(orderProp ? null : orderId, {
7525
7562
  enabled: !orderProp && !!orderId,
7526
- poll
7563
+ poll,
7564
+ onStatusChange
7527
7565
  });
7528
7566
  const order = orderProp ?? fetched;
7529
7567
  if (isLoading && !order) {
@@ -7689,6 +7727,16 @@ function OrderSummary({
7689
7727
  className: classNames?.trackingLink,
7690
7728
  children: "Track your order"
7691
7729
  }
7730
+ ),
7731
+ onReorder && /* @__PURE__ */ jsx(
7732
+ "button",
7733
+ {
7734
+ type: "button",
7735
+ onClick: () => onReorder(order),
7736
+ "data-cimplify-order-reorder": true,
7737
+ className: classNames?.reorderButton,
7738
+ children: "Reorder"
7739
+ }
7692
7740
  )
7693
7741
  ] });
7694
7742
  }
@@ -7712,6 +7760,7 @@ function OrderHistory({
7712
7760
  limit,
7713
7761
  onOrderClick,
7714
7762
  renderOrder,
7763
+ onReorder,
7715
7764
  emptyMessage = "No orders yet",
7716
7765
  className,
7717
7766
  classNames
@@ -7783,7 +7832,20 @@ function OrderHistory({
7783
7832
  order.total_quantity === 1 ? "item" : "items"
7784
7833
  ] }),
7785
7834
  /* @__PURE__ */ jsx("span", { "data-cimplify-order-history-total": true, className: classNames?.total, children: /* @__PURE__ */ jsx(Price, { amount: order.total_price }) })
7786
- ] })
7835
+ ] }),
7836
+ onReorder && /* @__PURE__ */ jsx(
7837
+ "button",
7838
+ {
7839
+ type: "button",
7840
+ onClick: (e) => {
7841
+ e.stopPropagation();
7842
+ onReorder(order);
7843
+ },
7844
+ "data-cimplify-order-reorder": true,
7845
+ className: classNames?.reorderButton,
7846
+ children: "Reorder"
7847
+ }
7848
+ )
7787
7849
  ] })
7788
7850
  },
7789
7851
  order.id
@@ -8242,10 +8304,14 @@ function BookingCard({
8242
8304
  {
8243
8305
  "data-cimplify-booking-card": true,
8244
8306
  "data-status": booking.status,
8245
- className: cn(className, classNames?.root),
8307
+ className: cn(
8308
+ "rounded-xl border border-border bg-background p-4 flex flex-col gap-3",
8309
+ className,
8310
+ classNames?.root
8311
+ ),
8246
8312
  children: [
8247
- /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-main": true, children: [
8248
- /* @__PURE__ */ jsxs("span", { "data-cimplify-booking-service": true, className: classNames?.service, children: [
8313
+ /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-main": true, className: "flex items-center justify-between gap-2", children: [
8314
+ /* @__PURE__ */ jsxs("span", { "data-cimplify-booking-service": true, className: cn("font-semibold text-foreground", classNames?.service), children: [
8249
8315
  "Booking #",
8250
8316
  booking.order_id.slice(0, 8)
8251
8317
  ] }),
@@ -8254,22 +8320,37 @@ function BookingCard({
8254
8320
  {
8255
8321
  "data-cimplify-booking-status": true,
8256
8322
  "data-status": booking.status,
8257
- className: classNames?.status,
8323
+ className: cn(
8324
+ "text-xs font-medium px-2 py-0.5 rounded-full",
8325
+ active ? "bg-primary/10 text-primary" : "bg-muted text-muted-foreground",
8326
+ classNames?.status
8327
+ ),
8258
8328
  children: STATUS_LABELS3[booking.status] ?? booking.status
8259
8329
  }
8260
8330
  )
8261
8331
  ] }),
8262
- firstItem?.confirmation_code && /* @__PURE__ */ jsx("span", { "data-cimplify-booking-code": true, className: classNames?.confirmationCode, children: firstItem.confirmation_code }),
8263
- scheduledTime && /* @__PURE__ */ jsx("time", { "data-cimplify-booking-time": true, className: classNames?.time, children: scheduledTime }),
8264
- /* @__PURE__ */ jsx("span", { "data-cimplify-booking-total": true, className: classNames?.total, children: /* @__PURE__ */ jsx(Price, { amount: booking.total_price }) }),
8265
- active && (onCancel || onReschedule) && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-actions": true, className: classNames?.actions, children: [
8332
+ firstItem?.confirmation_code && /* @__PURE__ */ jsx("span", { "data-cimplify-booking-code": true, className: cn("text-xs font-mono text-muted-foreground tracking-wide", classNames?.confirmationCode), children: firstItem.confirmation_code }),
8333
+ scheduledTime && /* @__PURE__ */ jsx(
8334
+ "time",
8335
+ {
8336
+ "data-cimplify-booking-time": true,
8337
+ dateTime: firstItem?.scheduled_start ?? void 0,
8338
+ className: cn("text-sm text-foreground", classNames?.time),
8339
+ children: scheduledTime
8340
+ }
8341
+ ),
8342
+ /* @__PURE__ */ jsx("span", { "data-cimplify-booking-total": true, className: cn("text-sm font-medium text-foreground", classNames?.total), children: /* @__PURE__ */ jsx(Price, { amount: booking.total_price }) }),
8343
+ active && (onCancel || onReschedule) && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-actions": true, className: cn("flex gap-2 pt-1 border-t border-border mt-1", classNames?.actions), children: [
8266
8344
  onReschedule && /* @__PURE__ */ jsx(
8267
8345
  "button",
8268
8346
  {
8269
8347
  type: "button",
8270
8348
  onClick: () => onReschedule(booking),
8271
8349
  "data-cimplify-booking-reschedule": true,
8272
- className: classNames?.rescheduleButton,
8350
+ className: cn(
8351
+ "flex-1 text-sm font-medium py-2 rounded-lg border border-border bg-background text-foreground transition-colors hover:bg-muted cursor-pointer",
8352
+ classNames?.rescheduleButton
8353
+ ),
8273
8354
  children: "Reschedule"
8274
8355
  }
8275
8356
  ),
@@ -8279,7 +8360,10 @@ function BookingCard({
8279
8360
  type: "button",
8280
8361
  onClick: () => onCancel(booking),
8281
8362
  "data-cimplify-booking-cancel": true,
8282
- className: classNames?.cancelButton,
8363
+ className: cn(
8364
+ "flex-1 text-sm font-medium py-2 rounded-lg border border-border bg-background text-destructive transition-colors hover:bg-destructive/10 cursor-pointer",
8365
+ classNames?.cancelButton
8366
+ ),
8283
8367
  children: "Cancel"
8284
8368
  }
8285
8369
  )
@@ -8392,11 +8476,8 @@ function ServiceCard({
8392
8476
  "div",
8393
8477
  {
8394
8478
  "data-cimplify-service-card-image-container": true,
8395
- className: classNames?.imageContainer,
8396
- style: {
8397
- overflow: "hidden",
8398
- ...ASPECT_STYLES3[aspectRatio]
8399
- },
8479
+ className: cn("overflow-hidden rounded-t-xl", classNames?.imageContainer),
8480
+ style: ASPECT_STYLES3[aspectRatio],
8400
8481
  children: renderImage ? renderImage({
8401
8482
  src: imageUrl,
8402
8483
  alt: service.name,
@@ -8406,36 +8487,35 @@ function ServiceCard({
8406
8487
  {
8407
8488
  src: imageUrl,
8408
8489
  alt: service.name,
8409
- className: classNames?.image,
8410
- style: { width: "100%", height: "100%", objectFit: "cover" },
8490
+ className: cn("w-full h-full object-cover transition-transform duration-300 group-hover:scale-105", classNames?.image),
8411
8491
  "data-cimplify-service-card-image": true
8412
8492
  }
8413
8493
  )
8414
8494
  }
8415
8495
  ),
8416
- /* @__PURE__ */ jsxs("div", { "data-cimplify-service-card-body": true, className: classNames?.body, children: [
8417
- /* @__PURE__ */ jsx("span", { "data-cimplify-service-card-name": true, className: classNames?.name, children: service.name }),
8496
+ /* @__PURE__ */ jsxs("div", { "data-cimplify-service-card-body": true, className: cn("p-4 flex flex-col gap-1.5", classNames?.body), children: [
8497
+ /* @__PURE__ */ jsx("span", { "data-cimplify-service-card-name": true, className: cn("font-semibold text-foreground leading-tight", classNames?.name), children: service.name }),
8418
8498
  service.description && /* @__PURE__ */ jsx(
8419
8499
  "span",
8420
8500
  {
8421
8501
  "data-cimplify-service-card-description": true,
8422
- className: classNames?.description,
8423
- style: {
8424
- display: "-webkit-box",
8425
- WebkitLineClamp: 2,
8426
- WebkitBoxOrient: "vertical",
8427
- overflow: "hidden"
8428
- },
8502
+ className: cn("text-sm text-muted-foreground line-clamp-2", classNames?.description),
8429
8503
  children: service.description
8430
8504
  }
8431
8505
  ),
8432
- /* @__PURE__ */ jsxs("div", { "data-cimplify-service-card-meta": true, className: classNames?.meta, children: [
8433
- /* @__PURE__ */ jsx("span", { "data-cimplify-service-card-duration": true, className: classNames?.duration, children: formatDuration2(service.duration_minutes, service.duration_unit) }),
8434
- service.price && /* @__PURE__ */ jsx("span", { "data-cimplify-service-card-price": true, className: classNames?.price, children: /* @__PURE__ */ jsx(Price, { amount: service.price }) })
8506
+ /* @__PURE__ */ jsxs("div", { "data-cimplify-service-card-meta": true, className: cn("flex items-center gap-2 mt-1 text-sm", classNames?.meta), children: [
8507
+ /* @__PURE__ */ jsx("span", { "data-cimplify-service-card-duration": true, className: cn("text-muted-foreground", classNames?.duration), children: formatDuration2(service.duration_minutes, service.duration_unit) }),
8508
+ service.price && /* @__PURE__ */ jsx("span", { "data-cimplify-service-card-price": true, className: cn("font-medium text-foreground", classNames?.price), children: /* @__PURE__ */ jsx(Price, { amount: service.price }) })
8435
8509
  ] })
8436
8510
  ] }),
8437
- !href && onBook && /* @__PURE__ */ jsx("span", { "data-cimplify-service-card-action": true, className: classNames?.action, children: actionLabel })
8511
+ !href && onBook && /* @__PURE__ */ jsx("span", { "data-cimplify-service-card-action": true, className: cn("px-4 pb-4 pt-1 text-sm font-medium text-primary", classNames?.action), children: actionLabel })
8438
8512
  ] });
8513
+ const cardClasses = cn(
8514
+ "group block w-full rounded-xl border border-border bg-background text-left transition-shadow duration-200 hover:shadow-md",
8515
+ !service.is_available && "opacity-60",
8516
+ className,
8517
+ classNames?.root
8518
+ );
8439
8519
  if (href) {
8440
8520
  return /* @__PURE__ */ jsx(
8441
8521
  "a",
@@ -8443,8 +8523,7 @@ function ServiceCard({
8443
8523
  href,
8444
8524
  "data-cimplify-service-card": true,
8445
8525
  "data-available": service.is_available || void 0,
8446
- className: cn(className, classNames?.root),
8447
- style: { display: "block", textDecoration: "none", color: "inherit" },
8526
+ className: cn(cardClasses, "no-underline text-[inherit]"),
8448
8527
  children: cardBody
8449
8528
  }
8450
8529
  );
@@ -8457,18 +8536,7 @@ function ServiceCard({
8457
8536
  disabled: !service.is_available,
8458
8537
  "data-cimplify-service-card": true,
8459
8538
  "data-available": service.is_available || void 0,
8460
- className: cn(className, classNames?.root),
8461
- style: {
8462
- display: "block",
8463
- width: "100%",
8464
- textAlign: "inherit",
8465
- background: "none",
8466
- border: "none",
8467
- padding: 0,
8468
- cursor: service.is_available ? "pointer" : "default",
8469
- font: "inherit",
8470
- color: "inherit"
8471
- },
8539
+ className: cn(cardClasses, "cursor-pointer font-[inherit] p-0 border-border"),
8472
8540
  children: cardBody
8473
8541
  }
8474
8542
  );
@@ -8975,6 +9043,8 @@ function OrderDetailPage({
8975
9043
  poll = true,
8976
9044
  onBack,
8977
9045
  renderLineItem,
9046
+ onReorder,
9047
+ onStatusChange,
8978
9048
  backLabel = "Back to orders",
8979
9049
  className,
8980
9050
  classNames
@@ -8999,7 +9069,9 @@ function OrderDetailPage({
8999
9069
  order,
9000
9070
  orderId: order ? void 0 : orderId,
9001
9071
  poll,
9002
- renderLineItem
9072
+ renderLineItem,
9073
+ onReorder,
9074
+ onStatusChange
9003
9075
  }
9004
9076
  ) })
9005
9077
  ] });
@@ -9015,6 +9087,7 @@ function OrderHistoryPage({
9015
9087
  orders: ordersProp,
9016
9088
  limit = 20,
9017
9089
  onOrderNavigate,
9090
+ onReorder,
9018
9091
  showFilters = true,
9019
9092
  renderOrder,
9020
9093
  className,
@@ -9052,7 +9125,7 @@ function OrderHistoryPage({
9052
9125
  children: "Back to orders"
9053
9126
  }
9054
9127
  ),
9055
- /* @__PURE__ */ jsx(OrderSummary, { order: selectedOrder })
9128
+ /* @__PURE__ */ jsx(OrderSummary, { order: selectedOrder, onReorder })
9056
9129
  ] }) });
9057
9130
  }
9058
9131
  return /* @__PURE__ */ jsxs("div", { "data-cimplify-order-history-page": true, className: cn(className, classNames?.root), children: [
@@ -9075,7 +9148,8 @@ function OrderHistoryPage({
9075
9148
  status: statusFilter,
9076
9149
  limit,
9077
9150
  onOrderClick: handleOrderClick,
9078
- renderOrder
9151
+ renderOrder,
9152
+ onReorder
9079
9153
  }
9080
9154
  ) })
9081
9155
  ] });
@@ -9198,10 +9272,114 @@ function DealsPage({
9198
9272
  isEmpty && /* @__PURE__ */ jsx("div", { "data-cimplify-deals-empty": true, className: classNames?.empty, children: /* @__PURE__ */ jsx("p", { children: "No deals available right now. Check back soon!" }) })
9199
9273
  ] });
9200
9274
  }
9275
+ var ANY_VALUE2 = "__any__";
9276
+ function roomToResource(room) {
9277
+ return {
9278
+ id: room.id,
9279
+ name: room.name,
9280
+ capacity: room.capacity,
9281
+ floor: room.floor,
9282
+ is_available: room.status === "available"
9283
+ };
9284
+ }
9285
+ function ResourcePicker({
9286
+ resources,
9287
+ selectedResourceId,
9288
+ onResourceSelect,
9289
+ showAnyOption = true,
9290
+ anyLabel = "Any available",
9291
+ renderImage,
9292
+ className,
9293
+ classNames
9294
+ }) {
9295
+ const groupValue = selectedResourceId === null ? ANY_VALUE2 : selectedResourceId ?? "";
9296
+ return /* @__PURE__ */ jsxs(
9297
+ RadioGroup,
9298
+ {
9299
+ "data-cimplify-resource-picker": true,
9300
+ className: cn("flex flex-col gap-2", className, classNames?.root),
9301
+ value: groupValue,
9302
+ onValueChange: (value) => {
9303
+ onResourceSelect?.(value === ANY_VALUE2 ? null : value);
9304
+ },
9305
+ children: [
9306
+ showAnyOption && /* @__PURE__ */ jsx(
9307
+ Radio.Root,
9308
+ {
9309
+ value: ANY_VALUE2,
9310
+ "data-cimplify-resource-option": true,
9311
+ "data-selected": selectedResourceId === null || void 0,
9312
+ "data-any": true,
9313
+ className: cn(
9314
+ "flex items-center gap-3 rounded-lg border border-border p-3 transition-colors cursor-pointer",
9315
+ "hover:bg-muted data-[checked]:border-primary data-[checked]:bg-primary/5",
9316
+ classNames?.option
9317
+ ),
9318
+ children: /* @__PURE__ */ jsx("span", { "data-cimplify-resource-name": true, className: cn("font-medium text-foreground", classNames?.name), children: anyLabel })
9319
+ }
9320
+ ),
9321
+ resources.map((resource) => {
9322
+ const unavailable = resource.is_available === false;
9323
+ return /* @__PURE__ */ jsxs(
9324
+ Radio.Root,
9325
+ {
9326
+ value: resource.id,
9327
+ disabled: unavailable,
9328
+ "data-cimplify-resource-option": true,
9329
+ "data-selected": selectedResourceId === resource.id || void 0,
9330
+ "data-unavailable": unavailable || void 0,
9331
+ className: cn(
9332
+ "flex items-center gap-3 rounded-lg border border-border p-3 transition-colors cursor-pointer",
9333
+ "hover:bg-muted data-[checked]:border-primary data-[checked]:bg-primary/5",
9334
+ unavailable && "opacity-50 cursor-not-allowed",
9335
+ classNames?.option,
9336
+ unavailable ? classNames?.unavailable : void 0
9337
+ ),
9338
+ children: [
9339
+ resource.image_url && (renderImage ? renderImage({
9340
+ src: resource.image_url,
9341
+ alt: resource.name,
9342
+ className: classNames?.image
9343
+ }) : /* @__PURE__ */ jsx(
9344
+ "img",
9345
+ {
9346
+ src: resource.image_url,
9347
+ alt: resource.name,
9348
+ "data-cimplify-resource-image": true,
9349
+ className: cn("w-10 h-10 rounded-lg object-cover", classNames?.image)
9350
+ }
9351
+ )),
9352
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5 flex-1 min-w-0", children: [
9353
+ /* @__PURE__ */ jsx("span", { "data-cimplify-resource-name": true, className: cn("font-medium text-foreground", classNames?.name), children: resource.name }),
9354
+ resource.description && /* @__PURE__ */ jsx("span", { "data-cimplify-resource-description": true, className: cn("text-sm text-muted-foreground truncate", classNames?.description), children: resource.description }),
9355
+ /* @__PURE__ */ jsxs("div", { "data-cimplify-resource-meta": true, className: cn("flex items-center gap-2 text-xs text-muted-foreground", classNames?.meta), children: [
9356
+ resource.capacity !== void 0 && /* @__PURE__ */ jsxs("span", { "data-cimplify-resource-capacity": true, className: classNames?.capacity, children: [
9357
+ "Up to ",
9358
+ resource.capacity
9359
+ ] }),
9360
+ resource.floor && /* @__PURE__ */ jsx("span", { "data-cimplify-resource-floor": true, className: classNames?.floor, children: resource.floor })
9361
+ ] })
9362
+ ] })
9363
+ ]
9364
+ },
9365
+ resource.id
9366
+ );
9367
+ })
9368
+ ]
9369
+ }
9370
+ );
9371
+ }
9372
+ var STEP = {
9373
+ SELECT_SLOT: "select-slot",
9374
+ SELECT_RESOURCE: "select-resource",
9375
+ SELECT_STAFF: "select-staff",
9376
+ CONFIRM: "confirm"
9377
+ };
9201
9378
  function BookingPage({
9202
9379
  service,
9203
9380
  product,
9204
9381
  staff,
9382
+ resources,
9205
9383
  participantCount,
9206
9384
  title,
9207
9385
  onBooked,
@@ -9215,12 +9393,14 @@ function BookingPage({
9215
9393
  const { addItem } = useCart();
9216
9394
  const { client } = useCimplifyClient();
9217
9395
  const isReschedule = existingBooking !== void 0;
9218
- const [step, setStep] = useState("select-slot");
9396
+ const [step, setStep] = useState(STEP.SELECT_SLOT);
9219
9397
  const [selectedSlot, setSelectedSlot] = useState(null);
9220
9398
  const [selectedDate, setSelectedDate] = useState(null);
9221
9399
  const [selectedStaffId, setSelectedStaffId] = useState(null);
9400
+ const [selectedResourceId, setSelectedResourceId] = useState(null);
9222
9401
  const [isSubmitting, setIsSubmitting] = useState(false);
9223
9402
  const [error, setError] = useState(null);
9403
+ const hasResourceStep = resources && resources.length > 0;
9224
9404
  const hasStaffStep = staff && staff.length > 0;
9225
9405
  const depositType = product?.deposit_type;
9226
9406
  const depositAmount = product?.deposit_amount;
@@ -9232,28 +9412,45 @@ function BookingPage({
9232
9412
  setSelectedSlot(slot);
9233
9413
  setSelectedDate(date);
9234
9414
  setError(null);
9415
+ if (hasResourceStep) {
9416
+ setStep(STEP.SELECT_RESOURCE);
9417
+ } else if (hasStaffStep) {
9418
+ setStep(STEP.SELECT_STAFF);
9419
+ } else {
9420
+ setStep(STEP.CONFIRM);
9421
+ }
9422
+ },
9423
+ [hasResourceStep, hasStaffStep]
9424
+ );
9425
+ const handleResourceSelect = useCallback(
9426
+ (resourceId) => {
9427
+ setSelectedResourceId(resourceId);
9235
9428
  if (hasStaffStep) {
9236
- setStep("select-staff");
9429
+ setStep(STEP.SELECT_STAFF);
9237
9430
  } else {
9238
- setStep("confirm");
9431
+ setStep(STEP.CONFIRM);
9239
9432
  }
9240
9433
  },
9241
9434
  [hasStaffStep]
9242
9435
  );
9243
9436
  const handleStaffSelect = useCallback((staffId) => {
9244
9437
  setSelectedStaffId(staffId);
9245
- setStep("confirm");
9438
+ setStep(STEP.CONFIRM);
9246
9439
  }, []);
9247
9440
  const handleBack = useCallback(() => {
9248
9441
  setError(null);
9249
- if (step === "confirm" && hasStaffStep) {
9250
- setStep("select-staff");
9251
- } else if (step === "confirm" || step === "select-staff") {
9252
- setStep("select-slot");
9442
+ if (step === STEP.CONFIRM && hasStaffStep) {
9443
+ setStep(STEP.SELECT_STAFF);
9444
+ } else if (step === STEP.CONFIRM && hasResourceStep) {
9445
+ setStep(STEP.SELECT_RESOURCE);
9446
+ } else if (step === STEP.SELECT_STAFF && hasResourceStep) {
9447
+ setStep(STEP.SELECT_RESOURCE);
9448
+ } else if (step === STEP.CONFIRM || step === STEP.SELECT_STAFF || step === STEP.SELECT_RESOURCE) {
9449
+ setStep(STEP.SELECT_SLOT);
9253
9450
  } else {
9254
9451
  onBack?.();
9255
9452
  }
9256
- }, [step, hasStaffStep, onBack]);
9453
+ }, [step, hasStaffStep, hasResourceStep, onBack]);
9257
9454
  const handleConfirm = useCallback(async () => {
9258
9455
  if (!selectedSlot || !selectedDate) return;
9259
9456
  setIsSubmitting(true);
@@ -9293,7 +9490,8 @@ function BookingPage({
9293
9490
  await addItem(serviceProduct, 1, {
9294
9491
  scheduledStart: selectedSlot.start_time,
9295
9492
  scheduledEnd: selectedSlot.end_time,
9296
- staffId: selectedStaffId || void 0
9493
+ staffId: selectedStaffId || void 0,
9494
+ resourceId: selectedResourceId || void 0
9297
9495
  });
9298
9496
  onBooked?.(selectedSlot, selectedStaffId);
9299
9497
  }
@@ -9306,7 +9504,7 @@ function BookingPage({
9306
9504
  }, [selectedSlot, selectedDate, selectedStaffId, service, addItem, onBooked, isReschedule, existingBooking, client, onRescheduled]);
9307
9505
  return /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-page": true, className: cn(className, classNames?.root), children: [
9308
9506
  /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-page-header": true, className: classNames?.header, children: [
9309
- onBack && step === "select-slot" && /* @__PURE__ */ jsx(
9507
+ onBack && step === STEP.SELECT_SLOT && /* @__PURE__ */ jsx(
9310
9508
  "button",
9311
9509
  {
9312
9510
  type: "button",
@@ -9316,7 +9514,7 @@ function BookingPage({
9316
9514
  children: "Back"
9317
9515
  }
9318
9516
  ),
9319
- step !== "select-slot" && /* @__PURE__ */ jsx(
9517
+ step !== STEP.SELECT_SLOT && /* @__PURE__ */ jsx(
9320
9518
  "button",
9321
9519
  {
9322
9520
  type: "button",
@@ -9351,7 +9549,7 @@ function BookingPage({
9351
9549
  ] })
9352
9550
  ] }),
9353
9551
  error && /* @__PURE__ */ jsx("div", { "data-cimplify-booking-error": true, className: classNames?.error, children: error }),
9354
- step === "select-slot" && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-step": "select-slot", className: classNames?.step, children: [
9552
+ step === STEP.SELECT_SLOT && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-step": "select-slot", className: classNames?.step, children: [
9355
9553
  /* @__PURE__ */ jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Select a date & time" }),
9356
9554
  /* @__PURE__ */ jsx(
9357
9555
  DateSlotPicker,
@@ -9364,7 +9562,18 @@ function BookingPage({
9364
9562
  }
9365
9563
  )
9366
9564
  ] }),
9367
- step === "select-staff" && staff && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-step": "select-staff", className: classNames?.step, children: [
9565
+ step === STEP.SELECT_RESOURCE && resources && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-step": "select-resource", className: cn(classNames?.step, classNames?.resourceStep), children: [
9566
+ /* @__PURE__ */ jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Choose a room" }),
9567
+ /* @__PURE__ */ jsx(
9568
+ ResourcePicker,
9569
+ {
9570
+ resources,
9571
+ selectedResourceId,
9572
+ onResourceSelect: handleResourceSelect
9573
+ }
9574
+ )
9575
+ ] }),
9576
+ step === STEP.SELECT_STAFF && staff && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-step": "select-staff", className: classNames?.step, children: [
9368
9577
  /* @__PURE__ */ jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Choose a provider" }),
9369
9578
  /* @__PURE__ */ jsx(
9370
9579
  StaffPicker,
@@ -9375,7 +9584,7 @@ function BookingPage({
9375
9584
  }
9376
9585
  )
9377
9586
  ] }),
9378
- step === "confirm" && selectedSlot && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-step": "confirm", className: classNames?.step, children: [
9587
+ step === STEP.CONFIRM && selectedSlot && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-step": "confirm", className: classNames?.step, children: [
9379
9588
  /* @__PURE__ */ jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Confirm your booking" }),
9380
9589
  /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-summary": true, className: classNames?.summary, children: [
9381
9590
  /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
@@ -9397,6 +9606,10 @@ function BookingPage({
9397
9606
  /* @__PURE__ */ jsx("span", { children: "Duration" }),
9398
9607
  /* @__PURE__ */ jsx("span", { children: formatDuration2(service.duration_minutes, service.duration_unit) })
9399
9608
  ] }),
9609
+ selectedResourceId && resources && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
9610
+ /* @__PURE__ */ jsx("span", { children: "Room" }),
9611
+ /* @__PURE__ */ jsx("span", { children: resources.find((r) => r.id === selectedResourceId)?.name ?? "Selected" })
9612
+ ] }),
9400
9613
  selectedStaffId && staff && /* @__PURE__ */ jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
9401
9614
  /* @__PURE__ */ jsx("span", { children: "Provider" }),
9402
9615
  /* @__PURE__ */ jsx("span", { children: staff.find((s) => s.id === selectedStaffId)?.name ?? "Selected" })
@@ -9965,4 +10178,4 @@ function CurrencySelector({
9965
10178
  }) });
9966
10179
  }
9967
10180
 
9968
- export { Ad, AdProvider, AddOnSelector, AddressElement, AuthElement, AvailabilityBadge, BillingPlanSelector, BookingCard, BookingList, BookingPage, BookingsPage, BundleSelector, CartPage, CartSummary, CataloguePage, CategoryFilter, CategoryGrid, CheckoutPage, CimplifyCheckout, CimplifyProvider, CollectionPage, CompositeSelector, CurrencySelector, DateSlotPicker, DealBanner, DealsPage, DeliveryEstimate, DiscountInput, ElementsProvider, LocationPicker, OrderDetailPage, OrderHistory, OrderHistoryPage, OrderSummary, PaymentElement, Price, ProductCard, ProductCustomizer, ProductGrid, ProductImageGallery, ProductPage, ProductSheet, QuantitySelector, RecentlyViewed, RecommendationCarousel, SaleBadge, SearchInput, SearchPage, ServiceCard, ServiceGrid, SessionMessageBanner, SlotPicker, StaffPicker, StoreNav, VariantSelector, cn, useActivityState, useAds, useAttributeDefinitions, useAvailableSlots, useBillingPlans, useBookings, useBootstrap, useBundles, useCart, useCategories, useCheckout, useCimplify, useCimplifyClient, useCollection, useCollections, useDeals, useDeliveryFee, useElements, useElementsReady, useFxRate, useLocations, useOptionalCimplify, useOrder, useOrders, useProduct, useProductAvailability, useProductDeals, useProductPrice, useProductSchedules, useProducts, useProductsOnSale, usePropertyFacets, useQuote, useRecommendations, useSearch, useServiceAvailability, useServices, useTaxonomies, useTaxonomy, useTaxonomyPath, useValidateDiscount, useVariantSelector };
10181
+ export { Ad, AdProvider, AddOnSelector, AddressElement, AuthElement, AvailabilityBadge, BillingPlanSelector, BookingCard, BookingList, BookingPage, BookingsPage, BundleSelector, CartPage, CartSummary, CataloguePage, CategoryFilter, CategoryGrid, CheckoutPage, CimplifyCheckout, CimplifyProvider, CollectionPage, CompositeSelector, CurrencySelector, DateSlotPicker, DealBanner, DealsPage, DeliveryEstimate, DiscountInput, ElementsProvider, LocationPicker, OrderDetailPage, OrderHistory, OrderHistoryPage, OrderSummary, PaymentElement, Price, ProductCard, ProductCustomizer, ProductGrid, ProductImageGallery, ProductPage, ProductSheet, QuantitySelector, RecentlyViewed, RecommendationCarousel, ResourcePicker, SaleBadge, SearchInput, SearchPage, ServiceCard, ServiceGrid, SessionMessageBanner, SlotPicker, StaffPicker, StoreNav, VariantSelector, cn, roomToResource, useActivityState, useAds, useAttributeDefinitions, useAvailableSlots, useBillingPlans, useBookings, useBootstrap, useBundles, useCart, useCategories, useCheckout, useCimplify, useCimplifyClient, useCollection, useCollections, useDeals, useDeliveryFee, useElements, useElementsReady, useFxRate, useLocations, useOptionalCimplify, useOrder, useOrders, useProduct, useProductAvailability, useProductDeals, useProductPrice, useProductSchedules, useProducts, useProductsOnSale, usePropertyFacets, useQuote, useRecommendations, useSearch, useServiceAvailability, useServices, useTaxonomies, useTaxonomy, useTaxonomyPath, useValidateDiscount, useVariantSelector };