@cimplify/sdk 0.21.0 → 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.
package/dist/react.js CHANGED
@@ -444,6 +444,9 @@ function buildLineKey(productId, options) {
444
444
  if (options.staffId) {
445
445
  parts.push(`st:${options.staffId}`);
446
446
  }
447
+ if (options.resourceId) {
448
+ parts.push(`r:${options.resourceId}`);
449
+ }
447
450
  return parts.join("|");
448
451
  }
449
452
  function calculateLineSubtotal(item) {
@@ -761,7 +764,8 @@ function createCartStore(params) {
761
764
  composite_selections: normalizedOptions.compositeSelections,
762
765
  scheduled_start: normalizedOptions.scheduledStart,
763
766
  scheduled_end: normalizedOptions.scheduledEnd,
764
- staff_id: normalizedOptions.staffId
767
+ staff_id: normalizedOptions.staffId,
768
+ resource_id: normalizedOptions.resourceId
765
769
  });
766
770
  if (!result.ok) {
767
771
  throw result.error;
@@ -4489,6 +4493,7 @@ function useRecommendations(options = {}) {
4489
4493
  return { recommendations, intent, isLoading, error, refetch };
4490
4494
  }
4491
4495
  var deliveryFeeCache = /* @__PURE__ */ new Map();
4496
+ var deliveryFeeInflight = /* @__PURE__ */ new Map();
4492
4497
  function buildDeliveryFeeCacheKey(client, latitude, longitude, country) {
4493
4498
  return JSON.stringify({
4494
4499
  key: client.getPublicKey(),
@@ -4532,13 +4537,26 @@ function useDeliveryFee(options) {
4532
4537
  setIsLoading(true);
4533
4538
  const currentRequestId = ++requestIdRef.current;
4534
4539
  try {
4535
- const result = await client.delivery.getFee(latitude, longitude, country);
4536
- if (currentRequestId !== requestIdRef.current) return;
4537
- if (!result.ok) {
4538
- throw result.error;
4540
+ const existing = deliveryFeeInflight.get(cacheKey);
4541
+ const promise = existing ?? (async () => {
4542
+ const result = await client.delivery.getFee(latitude, longitude, country);
4543
+ if (!result.ok) {
4544
+ throw result.error;
4545
+ }
4546
+ return result.value;
4547
+ })();
4548
+ if (!existing) {
4549
+ deliveryFeeInflight.set(
4550
+ cacheKey,
4551
+ promise.finally(() => {
4552
+ deliveryFeeInflight.delete(cacheKey);
4553
+ })
4554
+ );
4539
4555
  }
4540
- deliveryFeeCache.set(cacheKey, result.value);
4541
- setFee(result.value);
4556
+ const value = await promise;
4557
+ if (currentRequestId !== requestIdRef.current) return;
4558
+ deliveryFeeCache.set(cacheKey, value);
4559
+ setFee(value);
4542
4560
  } catch (loadError) {
4543
4561
  if (currentRequestId !== requestIdRef.current) return;
4544
4562
  setError(loadError);
@@ -6882,11 +6900,8 @@ function ProductCard({
6882
6900
  "div",
6883
6901
  {
6884
6902
  "data-cimplify-product-card-image-container": true,
6885
- className: classNames?.imageContainer,
6886
- style: {
6887
- overflow: "hidden",
6888
- ...ASPECT_STYLES2[aspectRatio]
6889
- },
6903
+ className: cn("overflow-hidden rounded-t-xl", classNames?.imageContainer),
6904
+ style: ASPECT_STYLES2[aspectRatio],
6890
6905
  children: renderImage ? renderImage({
6891
6906
  src: imageUrl,
6892
6907
  alt: product.name,
@@ -6896,8 +6911,7 @@ function ProductCard({
6896
6911
  {
6897
6912
  src: imageUrl,
6898
6913
  alt: product.name,
6899
- className: classNames?.image,
6900
- style: { width: "100%", height: "100%", objectFit: "cover" },
6914
+ className: cn("w-full h-full object-cover transition-transform duration-300 group-hover:scale-105", classNames?.image),
6901
6915
  "data-cimplify-product-card-image": true
6902
6916
  }
6903
6917
  )
@@ -6907,13 +6921,13 @@ function ProductCard({
6907
6921
  "div",
6908
6922
  {
6909
6923
  "data-cimplify-product-card-body": true,
6910
- className: classNames?.body,
6924
+ className: cn("p-4 flex flex-col gap-1", classNames?.body),
6911
6925
  children: [
6912
6926
  /* @__PURE__ */ jsxRuntime.jsx(
6913
6927
  "span",
6914
6928
  {
6915
6929
  "data-cimplify-product-card-name": true,
6916
- className: classNames?.name,
6930
+ className: cn("font-semibold text-foreground leading-tight", classNames?.name),
6917
6931
  children: product.name
6918
6932
  }
6919
6933
  ),
@@ -6921,13 +6935,7 @@ function ProductCard({
6921
6935
  "span",
6922
6936
  {
6923
6937
  "data-cimplify-product-card-description": true,
6924
- className: classNames?.description,
6925
- style: {
6926
- display: "-webkit-box",
6927
- WebkitLineClamp: 2,
6928
- WebkitBoxOrient: "vertical",
6929
- overflow: "hidden"
6930
- },
6938
+ className: cn("text-sm text-muted-foreground line-clamp-2", classNames?.description),
6931
6939
  children: product.description
6932
6940
  }
6933
6941
  ),
@@ -6935,7 +6943,7 @@ function ProductCard({
6935
6943
  Price,
6936
6944
  {
6937
6945
  amount: product.default_price,
6938
- className: classNames?.price
6946
+ className: cn("text-sm font-medium text-foreground mt-1", classNames?.price)
6939
6947
  }
6940
6948
  )
6941
6949
  ]
@@ -6944,7 +6952,7 @@ function ProductCard({
6944
6952
  ] });
6945
6953
  if (mode === "page") {
6946
6954
  const linkHref = href ?? `/menu/${product.slug}`;
6947
- const linkClassName = cn("block no-underline text-[inherit]", className, classNames?.root);
6955
+ 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);
6948
6956
  if (renderLink) {
6949
6957
  return renderLink({ href: linkHref, className: linkClassName, children: cardBody });
6950
6958
  }
@@ -6967,7 +6975,7 @@ function ProductCard({
6967
6975
  "data-cimplify-product-card": true,
6968
6976
  "data-display-mode": "card",
6969
6977
  className: cn(
6970
- "block w-full text-left bg-transparent border-none p-0 cursor-pointer font-[inherit] text-[inherit]",
6978
+ "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",
6971
6979
  className,
6972
6980
  classNames?.root
6973
6981
  ),
@@ -8301,10 +8309,14 @@ function BookingCard({
8301
8309
  {
8302
8310
  "data-cimplify-booking-card": true,
8303
8311
  "data-status": booking.status,
8304
- className: cn(className, classNames?.root),
8312
+ className: cn(
8313
+ "rounded-xl border border-border bg-background p-4 flex flex-col gap-3",
8314
+ className,
8315
+ classNames?.root
8316
+ ),
8305
8317
  children: [
8306
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-main": true, children: [
8307
- /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-booking-service": true, className: classNames?.service, children: [
8318
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-main": true, className: "flex items-center justify-between gap-2", children: [
8319
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-booking-service": true, className: cn("font-semibold text-foreground", classNames?.service), children: [
8308
8320
  "Booking #",
8309
8321
  booking.order_id.slice(0, 8)
8310
8322
  ] }),
@@ -8313,22 +8325,37 @@ function BookingCard({
8313
8325
  {
8314
8326
  "data-cimplify-booking-status": true,
8315
8327
  "data-status": booking.status,
8316
- className: classNames?.status,
8328
+ className: cn(
8329
+ "text-xs font-medium px-2 py-0.5 rounded-full",
8330
+ active ? "bg-primary/10 text-primary" : "bg-muted text-muted-foreground",
8331
+ classNames?.status
8332
+ ),
8317
8333
  children: STATUS_LABELS3[booking.status] ?? booking.status
8318
8334
  }
8319
8335
  )
8320
8336
  ] }),
8321
- firstItem?.confirmation_code && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-booking-code": true, className: classNames?.confirmationCode, children: firstItem.confirmation_code }),
8322
- scheduledTime && /* @__PURE__ */ jsxRuntime.jsx("time", { "data-cimplify-booking-time": true, className: classNames?.time, children: scheduledTime }),
8323
- /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-booking-total": true, className: classNames?.total, children: /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: booking.total_price }) }),
8324
- active && (onCancel || onReschedule) && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-actions": true, className: classNames?.actions, children: [
8337
+ firstItem?.confirmation_code && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-booking-code": true, className: cn("text-xs font-mono text-muted-foreground tracking-wide", classNames?.confirmationCode), children: firstItem.confirmation_code }),
8338
+ scheduledTime && /* @__PURE__ */ jsxRuntime.jsx(
8339
+ "time",
8340
+ {
8341
+ "data-cimplify-booking-time": true,
8342
+ dateTime: firstItem?.scheduled_start ?? void 0,
8343
+ className: cn("text-sm text-foreground", classNames?.time),
8344
+ children: scheduledTime
8345
+ }
8346
+ ),
8347
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-booking-total": true, className: cn("text-sm font-medium text-foreground", classNames?.total), children: /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: booking.total_price }) }),
8348
+ active && (onCancel || onReschedule) && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-actions": true, className: cn("flex gap-2 pt-1 border-t border-border mt-1", classNames?.actions), children: [
8325
8349
  onReschedule && /* @__PURE__ */ jsxRuntime.jsx(
8326
8350
  "button",
8327
8351
  {
8328
8352
  type: "button",
8329
8353
  onClick: () => onReschedule(booking),
8330
8354
  "data-cimplify-booking-reschedule": true,
8331
- className: classNames?.rescheduleButton,
8355
+ className: cn(
8356
+ "flex-1 text-sm font-medium py-2 rounded-lg border border-border bg-background text-foreground transition-colors hover:bg-muted cursor-pointer",
8357
+ classNames?.rescheduleButton
8358
+ ),
8332
8359
  children: "Reschedule"
8333
8360
  }
8334
8361
  ),
@@ -8338,7 +8365,10 @@ function BookingCard({
8338
8365
  type: "button",
8339
8366
  onClick: () => onCancel(booking),
8340
8367
  "data-cimplify-booking-cancel": true,
8341
- className: classNames?.cancelButton,
8368
+ className: cn(
8369
+ "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",
8370
+ classNames?.cancelButton
8371
+ ),
8342
8372
  children: "Cancel"
8343
8373
  }
8344
8374
  )
@@ -8451,11 +8481,8 @@ function ServiceCard({
8451
8481
  "div",
8452
8482
  {
8453
8483
  "data-cimplify-service-card-image-container": true,
8454
- className: classNames?.imageContainer,
8455
- style: {
8456
- overflow: "hidden",
8457
- ...ASPECT_STYLES3[aspectRatio]
8458
- },
8484
+ className: cn("overflow-hidden rounded-t-xl", classNames?.imageContainer),
8485
+ style: ASPECT_STYLES3[aspectRatio],
8459
8486
  children: renderImage ? renderImage({
8460
8487
  src: imageUrl,
8461
8488
  alt: service.name,
@@ -8465,36 +8492,35 @@ function ServiceCard({
8465
8492
  {
8466
8493
  src: imageUrl,
8467
8494
  alt: service.name,
8468
- className: classNames?.image,
8469
- style: { width: "100%", height: "100%", objectFit: "cover" },
8495
+ className: cn("w-full h-full object-cover transition-transform duration-300 group-hover:scale-105", classNames?.image),
8470
8496
  "data-cimplify-service-card-image": true
8471
8497
  }
8472
8498
  )
8473
8499
  }
8474
8500
  ),
8475
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-service-card-body": true, className: classNames?.body, children: [
8476
- /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-service-card-name": true, className: classNames?.name, children: service.name }),
8501
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-service-card-body": true, className: cn("p-4 flex flex-col gap-1.5", classNames?.body), children: [
8502
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-service-card-name": true, className: cn("font-semibold text-foreground leading-tight", classNames?.name), children: service.name }),
8477
8503
  service.description && /* @__PURE__ */ jsxRuntime.jsx(
8478
8504
  "span",
8479
8505
  {
8480
8506
  "data-cimplify-service-card-description": true,
8481
- className: classNames?.description,
8482
- style: {
8483
- display: "-webkit-box",
8484
- WebkitLineClamp: 2,
8485
- WebkitBoxOrient: "vertical",
8486
- overflow: "hidden"
8487
- },
8507
+ className: cn("text-sm text-muted-foreground line-clamp-2", classNames?.description),
8488
8508
  children: service.description
8489
8509
  }
8490
8510
  ),
8491
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-service-card-meta": true, className: classNames?.meta, children: [
8492
- /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-service-card-duration": true, className: classNames?.duration, children: formatDuration2(service.duration_minutes, service.duration_unit) }),
8493
- service.price && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-service-card-price": true, className: classNames?.price, children: /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: service.price }) })
8511
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-service-card-meta": true, className: cn("flex items-center gap-2 mt-1 text-sm", classNames?.meta), children: [
8512
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-service-card-duration": true, className: cn("text-muted-foreground", classNames?.duration), children: formatDuration2(service.duration_minutes, service.duration_unit) }),
8513
+ service.price && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-service-card-price": true, className: cn("font-medium text-foreground", classNames?.price), children: /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: service.price }) })
8494
8514
  ] })
8495
8515
  ] }),
8496
- !href && onBook && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-service-card-action": true, className: classNames?.action, children: actionLabel })
8516
+ !href && onBook && /* @__PURE__ */ jsxRuntime.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 })
8497
8517
  ] });
8518
+ const cardClasses = cn(
8519
+ "group block w-full rounded-xl border border-border bg-background text-left transition-shadow duration-200 hover:shadow-md",
8520
+ !service.is_available && "opacity-60",
8521
+ className,
8522
+ classNames?.root
8523
+ );
8498
8524
  if (href) {
8499
8525
  return /* @__PURE__ */ jsxRuntime.jsx(
8500
8526
  "a",
@@ -8502,8 +8528,7 @@ function ServiceCard({
8502
8528
  href,
8503
8529
  "data-cimplify-service-card": true,
8504
8530
  "data-available": service.is_available || void 0,
8505
- className: cn(className, classNames?.root),
8506
- style: { display: "block", textDecoration: "none", color: "inherit" },
8531
+ className: cn(cardClasses, "no-underline text-[inherit]"),
8507
8532
  children: cardBody
8508
8533
  }
8509
8534
  );
@@ -8516,18 +8541,7 @@ function ServiceCard({
8516
8541
  disabled: !service.is_available,
8517
8542
  "data-cimplify-service-card": true,
8518
8543
  "data-available": service.is_available || void 0,
8519
- className: cn(className, classNames?.root),
8520
- style: {
8521
- display: "block",
8522
- width: "100%",
8523
- textAlign: "inherit",
8524
- background: "none",
8525
- border: "none",
8526
- padding: 0,
8527
- cursor: service.is_available ? "pointer" : "default",
8528
- font: "inherit",
8529
- color: "inherit"
8530
- },
8544
+ className: cn(cardClasses, "cursor-pointer font-[inherit] p-0 border-border"),
8531
8545
  children: cardBody
8532
8546
  }
8533
8547
  );
@@ -9263,10 +9277,114 @@ function DealsPage({
9263
9277
  isEmpty && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-deals-empty": true, className: classNames?.empty, children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: "No deals available right now. Check back soon!" }) })
9264
9278
  ] });
9265
9279
  }
9280
+ var ANY_VALUE2 = "__any__";
9281
+ function roomToResource(room) {
9282
+ return {
9283
+ id: room.id,
9284
+ name: room.name,
9285
+ capacity: room.capacity,
9286
+ floor: room.floor,
9287
+ is_available: room.status === "available"
9288
+ };
9289
+ }
9290
+ function ResourcePicker({
9291
+ resources,
9292
+ selectedResourceId,
9293
+ onResourceSelect,
9294
+ showAnyOption = true,
9295
+ anyLabel = "Any available",
9296
+ renderImage,
9297
+ className,
9298
+ classNames
9299
+ }) {
9300
+ const groupValue = selectedResourceId === null ? ANY_VALUE2 : selectedResourceId ?? "";
9301
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9302
+ radioGroup.RadioGroup,
9303
+ {
9304
+ "data-cimplify-resource-picker": true,
9305
+ className: cn("flex flex-col gap-2", className, classNames?.root),
9306
+ value: groupValue,
9307
+ onValueChange: (value) => {
9308
+ onResourceSelect?.(value === ANY_VALUE2 ? null : value);
9309
+ },
9310
+ children: [
9311
+ showAnyOption && /* @__PURE__ */ jsxRuntime.jsx(
9312
+ radio.Radio.Root,
9313
+ {
9314
+ value: ANY_VALUE2,
9315
+ "data-cimplify-resource-option": true,
9316
+ "data-selected": selectedResourceId === null || void 0,
9317
+ "data-any": true,
9318
+ className: cn(
9319
+ "flex items-center gap-3 rounded-lg border border-border p-3 transition-colors cursor-pointer",
9320
+ "hover:bg-muted data-[checked]:border-primary data-[checked]:bg-primary/5",
9321
+ classNames?.option
9322
+ ),
9323
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-resource-name": true, className: cn("font-medium text-foreground", classNames?.name), children: anyLabel })
9324
+ }
9325
+ ),
9326
+ resources.map((resource) => {
9327
+ const unavailable = resource.is_available === false;
9328
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9329
+ radio.Radio.Root,
9330
+ {
9331
+ value: resource.id,
9332
+ disabled: unavailable,
9333
+ "data-cimplify-resource-option": true,
9334
+ "data-selected": selectedResourceId === resource.id || void 0,
9335
+ "data-unavailable": unavailable || void 0,
9336
+ className: cn(
9337
+ "flex items-center gap-3 rounded-lg border border-border p-3 transition-colors cursor-pointer",
9338
+ "hover:bg-muted data-[checked]:border-primary data-[checked]:bg-primary/5",
9339
+ unavailable && "opacity-50 cursor-not-allowed",
9340
+ classNames?.option,
9341
+ unavailable ? classNames?.unavailable : void 0
9342
+ ),
9343
+ children: [
9344
+ resource.image_url && (renderImage ? renderImage({
9345
+ src: resource.image_url,
9346
+ alt: resource.name,
9347
+ className: classNames?.image
9348
+ }) : /* @__PURE__ */ jsxRuntime.jsx(
9349
+ "img",
9350
+ {
9351
+ src: resource.image_url,
9352
+ alt: resource.name,
9353
+ "data-cimplify-resource-image": true,
9354
+ className: cn("w-10 h-10 rounded-lg object-cover", classNames?.image)
9355
+ }
9356
+ )),
9357
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5 flex-1 min-w-0", children: [
9358
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-resource-name": true, className: cn("font-medium text-foreground", classNames?.name), children: resource.name }),
9359
+ resource.description && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-resource-description": true, className: cn("text-sm text-muted-foreground truncate", classNames?.description), children: resource.description }),
9360
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-resource-meta": true, className: cn("flex items-center gap-2 text-xs text-muted-foreground", classNames?.meta), children: [
9361
+ resource.capacity !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-resource-capacity": true, className: classNames?.capacity, children: [
9362
+ "Up to ",
9363
+ resource.capacity
9364
+ ] }),
9365
+ resource.floor && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-resource-floor": true, className: classNames?.floor, children: resource.floor })
9366
+ ] })
9367
+ ] })
9368
+ ]
9369
+ },
9370
+ resource.id
9371
+ );
9372
+ })
9373
+ ]
9374
+ }
9375
+ );
9376
+ }
9377
+ var STEP = {
9378
+ SELECT_SLOT: "select-slot",
9379
+ SELECT_RESOURCE: "select-resource",
9380
+ SELECT_STAFF: "select-staff",
9381
+ CONFIRM: "confirm"
9382
+ };
9266
9383
  function BookingPage({
9267
9384
  service,
9268
9385
  product,
9269
9386
  staff,
9387
+ resources,
9270
9388
  participantCount,
9271
9389
  title,
9272
9390
  onBooked,
@@ -9280,12 +9398,14 @@ function BookingPage({
9280
9398
  const { addItem } = useCart();
9281
9399
  const { client } = useCimplifyClient();
9282
9400
  const isReschedule = existingBooking !== void 0;
9283
- const [step, setStep] = React3.useState("select-slot");
9401
+ const [step, setStep] = React3.useState(STEP.SELECT_SLOT);
9284
9402
  const [selectedSlot, setSelectedSlot] = React3.useState(null);
9285
9403
  const [selectedDate, setSelectedDate] = React3.useState(null);
9286
9404
  const [selectedStaffId, setSelectedStaffId] = React3.useState(null);
9405
+ const [selectedResourceId, setSelectedResourceId] = React3.useState(null);
9287
9406
  const [isSubmitting, setIsSubmitting] = React3.useState(false);
9288
9407
  const [error, setError] = React3.useState(null);
9408
+ const hasResourceStep = resources && resources.length > 0;
9289
9409
  const hasStaffStep = staff && staff.length > 0;
9290
9410
  const depositType = product?.deposit_type;
9291
9411
  const depositAmount = product?.deposit_amount;
@@ -9297,28 +9417,45 @@ function BookingPage({
9297
9417
  setSelectedSlot(slot);
9298
9418
  setSelectedDate(date);
9299
9419
  setError(null);
9420
+ if (hasResourceStep) {
9421
+ setStep(STEP.SELECT_RESOURCE);
9422
+ } else if (hasStaffStep) {
9423
+ setStep(STEP.SELECT_STAFF);
9424
+ } else {
9425
+ setStep(STEP.CONFIRM);
9426
+ }
9427
+ },
9428
+ [hasResourceStep, hasStaffStep]
9429
+ );
9430
+ const handleResourceSelect = React3.useCallback(
9431
+ (resourceId) => {
9432
+ setSelectedResourceId(resourceId);
9300
9433
  if (hasStaffStep) {
9301
- setStep("select-staff");
9434
+ setStep(STEP.SELECT_STAFF);
9302
9435
  } else {
9303
- setStep("confirm");
9436
+ setStep(STEP.CONFIRM);
9304
9437
  }
9305
9438
  },
9306
9439
  [hasStaffStep]
9307
9440
  );
9308
9441
  const handleStaffSelect = React3.useCallback((staffId) => {
9309
9442
  setSelectedStaffId(staffId);
9310
- setStep("confirm");
9443
+ setStep(STEP.CONFIRM);
9311
9444
  }, []);
9312
9445
  const handleBack = React3.useCallback(() => {
9313
9446
  setError(null);
9314
- if (step === "confirm" && hasStaffStep) {
9315
- setStep("select-staff");
9316
- } else if (step === "confirm" || step === "select-staff") {
9317
- setStep("select-slot");
9447
+ if (step === STEP.CONFIRM && hasStaffStep) {
9448
+ setStep(STEP.SELECT_STAFF);
9449
+ } else if (step === STEP.CONFIRM && hasResourceStep) {
9450
+ setStep(STEP.SELECT_RESOURCE);
9451
+ } else if (step === STEP.SELECT_STAFF && hasResourceStep) {
9452
+ setStep(STEP.SELECT_RESOURCE);
9453
+ } else if (step === STEP.CONFIRM || step === STEP.SELECT_STAFF || step === STEP.SELECT_RESOURCE) {
9454
+ setStep(STEP.SELECT_SLOT);
9318
9455
  } else {
9319
9456
  onBack?.();
9320
9457
  }
9321
- }, [step, hasStaffStep, onBack]);
9458
+ }, [step, hasStaffStep, hasResourceStep, onBack]);
9322
9459
  const handleConfirm = React3.useCallback(async () => {
9323
9460
  if (!selectedSlot || !selectedDate) return;
9324
9461
  setIsSubmitting(true);
@@ -9358,7 +9495,8 @@ function BookingPage({
9358
9495
  await addItem(serviceProduct, 1, {
9359
9496
  scheduledStart: selectedSlot.start_time,
9360
9497
  scheduledEnd: selectedSlot.end_time,
9361
- staffId: selectedStaffId || void 0
9498
+ staffId: selectedStaffId || void 0,
9499
+ resourceId: selectedResourceId || void 0
9362
9500
  });
9363
9501
  onBooked?.(selectedSlot, selectedStaffId);
9364
9502
  }
@@ -9371,7 +9509,7 @@ function BookingPage({
9371
9509
  }, [selectedSlot, selectedDate, selectedStaffId, service, addItem, onBooked, isReschedule, existingBooking, client, onRescheduled]);
9372
9510
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-page": true, className: cn(className, classNames?.root), children: [
9373
9511
  /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-page-header": true, className: classNames?.header, children: [
9374
- onBack && step === "select-slot" && /* @__PURE__ */ jsxRuntime.jsx(
9512
+ onBack && step === STEP.SELECT_SLOT && /* @__PURE__ */ jsxRuntime.jsx(
9375
9513
  "button",
9376
9514
  {
9377
9515
  type: "button",
@@ -9381,7 +9519,7 @@ function BookingPage({
9381
9519
  children: "Back"
9382
9520
  }
9383
9521
  ),
9384
- step !== "select-slot" && /* @__PURE__ */ jsxRuntime.jsx(
9522
+ step !== STEP.SELECT_SLOT && /* @__PURE__ */ jsxRuntime.jsx(
9385
9523
  "button",
9386
9524
  {
9387
9525
  type: "button",
@@ -9416,7 +9554,7 @@ function BookingPage({
9416
9554
  ] })
9417
9555
  ] }),
9418
9556
  error && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-booking-error": true, className: classNames?.error, children: error }),
9419
- step === "select-slot" && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-step": "select-slot", className: classNames?.step, children: [
9557
+ step === STEP.SELECT_SLOT && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-step": "select-slot", className: classNames?.step, children: [
9420
9558
  /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Select a date & time" }),
9421
9559
  /* @__PURE__ */ jsxRuntime.jsx(
9422
9560
  DateSlotPicker,
@@ -9429,7 +9567,18 @@ function BookingPage({
9429
9567
  }
9430
9568
  )
9431
9569
  ] }),
9432
- step === "select-staff" && staff && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-step": "select-staff", className: classNames?.step, children: [
9570
+ step === STEP.SELECT_RESOURCE && resources && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-step": "select-resource", className: cn(classNames?.step, classNames?.resourceStep), children: [
9571
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Choose a room" }),
9572
+ /* @__PURE__ */ jsxRuntime.jsx(
9573
+ ResourcePicker,
9574
+ {
9575
+ resources,
9576
+ selectedResourceId,
9577
+ onResourceSelect: handleResourceSelect
9578
+ }
9579
+ )
9580
+ ] }),
9581
+ step === STEP.SELECT_STAFF && staff && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-step": "select-staff", className: classNames?.step, children: [
9433
9582
  /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Choose a provider" }),
9434
9583
  /* @__PURE__ */ jsxRuntime.jsx(
9435
9584
  StaffPicker,
@@ -9440,7 +9589,7 @@ function BookingPage({
9440
9589
  }
9441
9590
  )
9442
9591
  ] }),
9443
- step === "confirm" && selectedSlot && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-step": "confirm", className: classNames?.step, children: [
9592
+ step === STEP.CONFIRM && selectedSlot && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-step": "confirm", className: classNames?.step, children: [
9444
9593
  /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Confirm your booking" }),
9445
9594
  /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary": true, className: classNames?.summary, children: [
9446
9595
  /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
@@ -9462,6 +9611,10 @@ function BookingPage({
9462
9611
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Duration" }),
9463
9612
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatDuration2(service.duration_minutes, service.duration_unit) })
9464
9613
  ] }),
9614
+ selectedResourceId && resources && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
9615
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Room" }),
9616
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: resources.find((r) => r.id === selectedResourceId)?.name ?? "Selected" })
9617
+ ] }),
9465
9618
  selectedStaffId && staff && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
9466
9619
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Provider" }),
9467
9620
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: staff.find((s) => s.id === selectedStaffId)?.name ?? "Selected" })
@@ -10079,6 +10232,7 @@ exports.ProductSheet = ProductSheet;
10079
10232
  exports.QuantitySelector = QuantitySelector;
10080
10233
  exports.RecentlyViewed = RecentlyViewed;
10081
10234
  exports.RecommendationCarousel = RecommendationCarousel;
10235
+ exports.ResourcePicker = ResourcePicker;
10082
10236
  exports.SaleBadge = SaleBadge;
10083
10237
  exports.SearchInput = SearchInput;
10084
10238
  exports.SearchPage = SearchPage;
@@ -10090,6 +10244,7 @@ exports.StaffPicker = StaffPicker;
10090
10244
  exports.StoreNav = StoreNav;
10091
10245
  exports.VariantSelector = VariantSelector;
10092
10246
  exports.cn = cn;
10247
+ exports.roomToResource = roomToResource;
10093
10248
  exports.useActivityState = useActivityState;
10094
10249
  exports.useAds = useAds;
10095
10250
  exports.useAttributeDefinitions = useAttributeDefinitions;