@resira/ui 0.4.13 → 0.4.15

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/index.cjs CHANGED
@@ -2031,10 +2031,17 @@ function groupProductsByCategory(products, resources) {
2031
2031
  let groupId;
2032
2032
  let label;
2033
2033
  let catImage;
2034
+ let catGalleryImages;
2034
2035
  if (productCategory) {
2035
2036
  groupId = productCategory.toLowerCase();
2036
2037
  label = product.categoryName?.trim() ? product.categoryName.trim() : formatCategoryLabel(productCategory);
2038
+ catGalleryImages = Array.isArray(product.categoryGalleryImages) ? product.categoryGalleryImages.filter(
2039
+ (url) => typeof url === "string" && url.trim().length > 0
2040
+ ) : void 0;
2037
2041
  catImage = product.categoryImage ?? void 0;
2042
+ if (!catImage && catGalleryImages && catGalleryImages.length > 0) {
2043
+ catImage = catGalleryImages[0];
2044
+ }
2038
2045
  } else {
2039
2046
  let categoryResource;
2040
2047
  const categoryType = product.equipmentIds.map((equipmentId) => {
@@ -2053,6 +2060,7 @@ function groupProductsByCategory(products, resources) {
2053
2060
  id: groupId,
2054
2061
  label,
2055
2062
  imageUrl: catImage,
2063
+ galleryImages: catGalleryImages,
2056
2064
  products: []
2057
2065
  });
2058
2066
  }
@@ -2061,14 +2069,11 @@ function groupProductsByCategory(products, resources) {
2061
2069
  if (!group.imageUrl) {
2062
2070
  if (catImage) {
2063
2071
  group.imageUrl = catImage;
2064
- } else {
2065
- const coverImage = product.images?.[0];
2066
- const firstImage = (coverImage?.showInCategoryHeader !== false ? coverImage?.url : void 0) ?? product.imageUrl;
2067
- if (firstImage) {
2068
- group.imageUrl = firstImage;
2069
- }
2070
2072
  }
2071
2073
  }
2074
+ if ((!group.galleryImages || group.galleryImages.length === 0) && catGalleryImages && catGalleryImages.length > 0) {
2075
+ group.galleryImages = catGalleryImages;
2076
+ }
2072
2077
  });
2073
2078
  return Array.from(groups.values());
2074
2079
  }
@@ -3092,6 +3097,14 @@ function formatPrice5(cents, currency) {
3092
3097
  currency
3093
3098
  }).format(cents / 100);
3094
3099
  }
3100
+ function normalizeDurationMinutes(value) {
3101
+ if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
3102
+ if (typeof value === "string" && value.trim()) {
3103
+ const parsed = Number(value);
3104
+ if (Number.isFinite(parsed) && parsed > 0) return parsed;
3105
+ }
3106
+ return void 0;
3107
+ }
3095
3108
  function buildSteps(domain, hasPayment, catalogMode) {
3096
3109
  const steps = [];
3097
3110
  if (domain === "watersport" || domain === "service" || catalogMode && domain !== "restaurant") {
@@ -3209,6 +3222,7 @@ function ResiraBookingWidget() {
3209
3222
  setPromoValidation(result);
3210
3223
  }, []);
3211
3224
  const [slotDate, setSlotDate] = react.useState(todayStr());
3225
+ const activeDurationMinutes = normalizeDurationMinutes(selection.duration);
3212
3226
  const availabilityParams = react.useMemo(() => {
3213
3227
  if (isDateBased) {
3214
3228
  if (selection.startDate && selection.endDate) {
@@ -3219,9 +3233,9 @@ function ResiraBookingWidget() {
3219
3233
  return {
3220
3234
  date: slotDate,
3221
3235
  partySize: selection.partySize,
3222
- durationMinutes: selection.duration
3236
+ durationMinutes: activeDurationMinutes
3223
3237
  };
3224
- }, [isDateBased, selection.startDate, selection.endDate, slotDate, selection.partySize, selection.duration]);
3238
+ }, [isDateBased, selection.startDate, selection.endDate, slotDate, selection.partySize, activeDurationMinutes]);
3225
3239
  const availabilityProductId = isServiceBased ? selectedProduct?.id : void 0;
3226
3240
  const { data: availability, loading, error, refetch } = useAvailability(
3227
3241
  availabilityParams,
@@ -3265,7 +3279,7 @@ function ResiraBookingWidget() {
3265
3279
  productId: selectedProduct?.id ?? "",
3266
3280
  resourceId,
3267
3281
  partySize: selection.partySize,
3268
- durationMinutes: selection.duration,
3282
+ durationMinutes: activeDurationMinutes,
3269
3283
  startDate: selection.startDate,
3270
3284
  startTime: selection.startTime,
3271
3285
  endTime: selection.endTime,
@@ -3277,7 +3291,7 @@ function ResiraBookingWidget() {
3277
3291
  termsAccepted: termsAccepted || void 0,
3278
3292
  waiverAccepted: waiverAccepted || void 0
3279
3293
  };
3280
- }, [activeResourceId, selectedProduct, selection, guest, discountCode, termsAccepted, waiverAccepted, isCheckoutMode, checkoutSession, checkoutSessionToken]);
3294
+ }, [activeResourceId, selectedProduct, selection, guest, discountCode, termsAccepted, waiverAccepted, isCheckoutMode, checkoutSession, checkoutSessionToken, activeDurationMinutes]);
3281
3295
  const blockedDates = react.useMemo(() => {
3282
3296
  const dates = calendarData?.dates?.blockedDates ?? availability?.dates?.blockedDates ?? [];
3283
3297
  return new Set(dates);
@@ -3297,11 +3311,11 @@ function ResiraBookingWidget() {
3297
3311
  if (selectedProduct) {
3298
3312
  let base = selectedProduct.priceCents;
3299
3313
  if (selectedProduct.pricingModel === "per_rider" && activeRiderDurationPricing?.length) {
3300
- const match = selection.duration ? activeRiderDurationPricing.find((dp) => dp.durationMinutes === selection.duration) : activeRiderDurationPricing[0];
3314
+ const match = activeDurationMinutes ? activeRiderDurationPricing.find((dp) => dp.durationMinutes === activeDurationMinutes) : activeRiderDurationPricing[0];
3301
3315
  if (match) base = match.priceCents;
3302
- } else if (selectedProduct.durationPricing?.length && selection.duration) {
3316
+ } else if (selectedProduct.durationPricing?.length && activeDurationMinutes) {
3303
3317
  const match = selectedProduct.durationPricing.find(
3304
- (dp) => dp.durationMinutes === selection.duration
3318
+ (dp) => dp.durationMinutes === activeDurationMinutes
3305
3319
  );
3306
3320
  if (match) base = match.priceCents;
3307
3321
  }
@@ -3319,7 +3333,7 @@ function ResiraBookingWidget() {
3319
3333
  return { total, amountNow, amountAtVenue };
3320
3334
  }
3321
3335
  return null;
3322
- }, [selectedProduct, availability, selection.partySize, selection.duration, depositPercent, activeRiderDurationPricing]);
3336
+ }, [selectedProduct, availability, selection.partySize, activeDurationMinutes, depositPercent, activeRiderDurationPricing]);
3323
3337
  const stepTitle = react.useMemo(() => {
3324
3338
  switch (step) {
3325
3339
  case "resource":
@@ -3763,7 +3777,7 @@ function ResiraBookingWidget() {
3763
3777
  onPartySizeChange: handlePartySizeChange,
3764
3778
  showPartySize: true,
3765
3779
  showDuration: domain === "watersport" || domain === "service",
3766
- selectedDuration: selection.duration,
3780
+ selectedDuration: activeDurationMinutes,
3767
3781
  onDurationChange: handleDurationChange,
3768
3782
  maxPartySizeOverride: selectedProduct?.maxPartySize,
3769
3783
  durationPricing: activeRiderDurationPricing ?? selectedProduct?.durationPricing,
@@ -3775,19 +3789,19 @@ function ResiraBookingWidget() {
3775
3789
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "resira-price-preview-row", children: [
3776
3790
  /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
3777
3791
  selectedProduct.name,
3778
- selection.duration && selectedProduct.durationPricing && selectedProduct.durationPricing.length > 1 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "resira-price-preview-label", children: [
3792
+ activeDurationMinutes && selectedProduct.durationPricing && selectedProduct.durationPricing.length > 1 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "resira-price-preview-label", children: [
3779
3793
  " ",
3780
3794
  "(",
3781
- selection.duration < 60 ? `${selection.duration} min` : `${Math.floor(selection.duration / 60)}h${selection.duration % 60 ? selection.duration % 60 : ""}`,
3795
+ activeDurationMinutes < 60 ? `${activeDurationMinutes} min` : `${Math.floor(activeDurationMinutes / 60)}h${activeDurationMinutes % 60 ? activeDurationMinutes % 60 : ""}`,
3782
3796
  ")"
3783
3797
  ] })
3784
3798
  ] }),
3785
3799
  /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
3786
3800
  (() => {
3787
3801
  let unitPrice = selectedProduct.priceCents;
3788
- if (selectedProduct.durationPricing?.length && selection.duration) {
3802
+ if (selectedProduct.durationPricing?.length && activeDurationMinutes) {
3789
3803
  const match = selectedProduct.durationPricing.find(
3790
- (dp) => dp.durationMinutes === selection.duration
3804
+ (dp) => dp.durationMinutes === activeDurationMinutes
3791
3805
  );
3792
3806
  if (match) unitPrice = match.priceCents;
3793
3807
  }