@wix/headless-bookings 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/cjs/dist/__mocks__/booking/booking-mocks.d.ts +1 -1
  2. package/cjs/dist/__mocks__/services/services-mocks.d.ts +23 -0
  3. package/cjs/dist/__mocks__/services/services-mocks.js +65 -1
  4. package/cjs/dist/api/query-services/index.js +2 -2
  5. package/cjs/dist/react/core/booking/Booking.d.ts +1 -1
  6. package/cjs/dist/react/core/booking/Booking.js +18 -5
  7. package/cjs/dist/react/core/location/Location.d.ts +1 -1
  8. package/cjs/dist/react/core/location/Location.js +5 -5
  9. package/cjs/dist/react/core/service/Service.d.ts +10 -1
  10. package/cjs/dist/react/core/service/Service.js +5 -4
  11. package/cjs/dist/react/service/Service.d.ts +68 -1
  12. package/cjs/dist/react/service/Service.js +81 -1
  13. package/cjs/dist/services/booking/booking.d.ts +1 -1
  14. package/cjs/dist/services/location-list/location-list.def.d.ts +1 -1
  15. package/cjs/dist/services/location-list/location-list.def.js +1 -1
  16. package/cjs/dist/services/location-list/location-list.js +7 -7
  17. package/cjs/dist/services/payment/payment.def.d.ts +6 -0
  18. package/cjs/dist/services/payment/payment.js +56 -5
  19. package/dist/__mocks__/booking/booking-mocks.d.ts +1 -1
  20. package/dist/__mocks__/services/services-mocks.d.ts +23 -0
  21. package/dist/__mocks__/services/services-mocks.js +64 -0
  22. package/dist/api/query-services/index.js +1 -1
  23. package/dist/react/core/booking/Booking.d.ts +1 -1
  24. package/dist/react/core/booking/Booking.js +18 -5
  25. package/dist/react/core/location/Location.d.ts +1 -1
  26. package/dist/react/core/location/Location.js +1 -1
  27. package/dist/react/core/service/Service.d.ts +10 -1
  28. package/dist/react/core/service/Service.js +5 -4
  29. package/dist/react/service/Service.d.ts +68 -1
  30. package/dist/react/service/Service.js +81 -1
  31. package/dist/services/booking/booking.d.ts +1 -1
  32. package/dist/services/location-list/location-list.def.d.ts +1 -1
  33. package/dist/services/location-list/location-list.def.js +1 -1
  34. package/dist/services/location-list/location-list.js +1 -1
  35. package/dist/services/payment/payment.def.d.ts +6 -0
  36. package/dist/services/payment/payment.js +57 -6
  37. package/package.json +5 -3
@@ -1,5 +1,5 @@
1
1
  import type { FormValues } from '@wix/forms/components';
2
- import type { Location } from '@wix/auto_sdk_bookings_services';
2
+ import type { V2Location as Location } from '@wix/auto_sdk_bookings_services';
3
3
  import type { ServiceSelection, ServiceSelectionTimeSlot, ExtendedResource } from '../../services/booking/booking.js';
4
4
  export declare function createMockResource(overrides?: Partial<ExtendedResource>): ExtendedResource;
5
5
  export declare function createMockLocation(overrides?: Partial<Location>): Location;
@@ -35,6 +35,29 @@ export declare const mockServiceCourse: Service;
35
35
  * Mock service without optional fields (minimal)
36
36
  */
37
37
  export declare const mockServiceMinimal: Service;
38
+ /**
39
+ * Mock service driving the fixed-duration path: a single value in
40
+ * `sessionDurations`, no `durationRange`. Drives `Service.DurationInMinutes`;
41
+ * `Service.DurationRange` renders nothing for this shape.
42
+ *
43
+ * `mockService` already carries this shape — this is a renamed copy for
44
+ * tests/examples that want to name the case they're exercising.
45
+ */
46
+ export declare const mockServiceFixedDuration: Service;
47
+ /**
48
+ * Mock service driving the HOUR-unit DurationRange path. Mirrors the server
49
+ * payload shape: empty `sessionDurations`, range pre-computed at
50
+ * `availabilityConstraints.durationRange`. `durationRange` is not yet in the
51
+ * SDK's `AvailabilityConstraints` typing (runtime is ahead of types), so the
52
+ * service object is cast — matches the read-side cast in
53
+ * `core/service/Service.tsx`.
54
+ */
55
+ export declare const mockServiceHourRange: Service;
56
+ /**
57
+ * Mock service driving the DAY-unit DurationRange path. Same server shape as
58
+ * {@link mockServiceHourRange}.
59
+ */
60
+ export declare const mockServiceDayRange: Service;
38
61
  /**
39
62
  * Array of mock services for list tests
40
63
  */
@@ -3,7 +3,7 @@
3
3
  * Shared mock data for booking service tests
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.mockServiceInPerson = exports.mockServiceWithDeposit = exports.mockSingleStaffMemberListConfig = exports.mockEmptyStaffMemberListConfig = exports.mockStaffMemberListConfig = exports.mockStaffMembers = exports.mockStaffMemberNoName = exports.mockStaffMemberMinimal = exports.mockStaffMember2 = exports.mockStaffMember = exports.mockServiceListConfigWithCategories = exports.mockCategories = exports.mockServiceConfig = exports.mockEmptyServiceListConfig = exports.mockServiceListConfigWithMore = exports.mockServiceListConfig = exports.mockPagingMetadataEmpty = exports.mockPagingMetadataWithMore = exports.mockPagingMetadata = exports.mockServices = exports.mockServiceMinimal = exports.mockServiceCourse = exports.mockServiceClass = exports.mockServiceNoFee = exports.mockServiceCustomPrice = exports.mockServiceVariedPrice = exports.mockService = void 0;
6
+ exports.mockServiceInPerson = exports.mockServiceWithDeposit = exports.mockSingleStaffMemberListConfig = exports.mockEmptyStaffMemberListConfig = exports.mockStaffMemberListConfig = exports.mockStaffMembers = exports.mockStaffMemberNoName = exports.mockStaffMemberMinimal = exports.mockStaffMember2 = exports.mockStaffMember = exports.mockServiceListConfigWithCategories = exports.mockCategories = exports.mockServiceConfig = exports.mockEmptyServiceListConfig = exports.mockServiceListConfigWithMore = exports.mockServiceListConfig = exports.mockPagingMetadataEmpty = exports.mockPagingMetadataWithMore = exports.mockPagingMetadata = exports.mockServices = exports.mockServiceDayRange = exports.mockServiceHourRange = exports.mockServiceFixedDuration = exports.mockServiceMinimal = exports.mockServiceCourse = exports.mockServiceClass = exports.mockServiceNoFee = exports.mockServiceCustomPrice = exports.mockServiceVariedPrice = exports.mockService = void 0;
7
7
  exports.createLargeServiceList = createLargeServiceList;
8
8
  exports.createLargeStaffMemberList = createLargeStaffMemberList;
9
9
  const auto_sdk_bookings_services_1 = require("@wix/auto_sdk_bookings_services");
@@ -175,6 +175,70 @@ exports.mockServiceMinimal = {
175
175
  name: 'Minimal Service',
176
176
  description: '',
177
177
  };
178
+ /**
179
+ * Mock service driving the fixed-duration path: a single value in
180
+ * `sessionDurations`, no `durationRange`. Drives `Service.DurationInMinutes`;
181
+ * `Service.DurationRange` renders nothing for this shape.
182
+ *
183
+ * `mockService` already carries this shape — this is a renamed copy for
184
+ * tests/examples that want to name the case they're exercising.
185
+ */
186
+ exports.mockServiceFixedDuration = {
187
+ ...exports.mockService,
188
+ _id: 'test-service-fixed-duration',
189
+ name: 'Fixed Duration Service',
190
+ schedule: {
191
+ availabilityConstraints: {
192
+ sessionDurations: [60],
193
+ },
194
+ },
195
+ };
196
+ /**
197
+ * Mock service driving the HOUR-unit DurationRange path. Mirrors the server
198
+ * payload shape: empty `sessionDurations`, range pre-computed at
199
+ * `availabilityConstraints.durationRange`. `durationRange` is not yet in the
200
+ * SDK's `AvailabilityConstraints` typing (runtime is ahead of types), so the
201
+ * service object is cast — matches the read-side cast in
202
+ * `core/service/Service.tsx`.
203
+ */
204
+ exports.mockServiceHourRange = {
205
+ ...exports.mockService,
206
+ _id: 'test-service-hour-range',
207
+ name: 'Hourly Range Service',
208
+ schedule: {
209
+ availabilityConstraints: {
210
+ sessionDurations: [],
211
+ durationRange: {
212
+ unitType: 'HOUR',
213
+ hourOptions: {
214
+ minDurationInMinutes: 120,
215
+ maxDurationInMinutes: 540,
216
+ },
217
+ },
218
+ },
219
+ },
220
+ };
221
+ /**
222
+ * Mock service driving the DAY-unit DurationRange path. Same server shape as
223
+ * {@link mockServiceHourRange}.
224
+ */
225
+ exports.mockServiceDayRange = {
226
+ ...exports.mockService,
227
+ _id: 'test-service-day-range',
228
+ name: 'Daily Range Service',
229
+ schedule: {
230
+ availabilityConstraints: {
231
+ sessionDurations: [],
232
+ durationRange: {
233
+ unitType: 'DAY',
234
+ dayOptions: {
235
+ minDurationInDays: 2,
236
+ maxDurationInDays: 5,
237
+ },
238
+ },
239
+ },
240
+ },
241
+ };
178
242
  /**
179
243
  * Array of mock services for list tests
180
244
  */
@@ -143,10 +143,10 @@ function convertPlatformFilterToApiFilter(platformFilter) {
143
143
  const businessLocationIds = [];
144
144
  for (const id of locationIds) {
145
145
  if (id === exports.SYNTHETIC_CUSTOM_ID) {
146
- syntheticTypes.push(auto_sdk_bookings_services_1.LocationType.CUSTOM);
146
+ syntheticTypes.push(auto_sdk_bookings_services_1.LocationTypeEnumLocationType.CUSTOM);
147
147
  }
148
148
  else if (id === exports.SYNTHETIC_CUSTOMER_ID) {
149
- syntheticTypes.push(auto_sdk_bookings_services_1.LocationType.CUSTOMER);
149
+ syntheticTypes.push(auto_sdk_bookings_services_1.LocationTypeEnumLocationType.CUSTOMER);
150
150
  }
151
151
  else {
152
152
  businessLocationIds.push(id);
@@ -6,7 +6,7 @@ import React from 'react';
6
6
  import { type BookingServiceConfig, type ServiceSelection, type BookingServiceActions } from '../../../services/booking/booking.js';
7
7
  import type { FormValues } from '@wix/forms/components';
8
8
  import type { TimeSlot, Resource } from '@wix/auto_sdk_bookings_availability-time-slots';
9
- import { type Service, type Location as ServiceLocationType } from '@wix/auto_sdk_bookings_services';
9
+ import { type Service, type V2Location as ServiceLocationType } from '@wix/auto_sdk_bookings_services';
10
10
  import type { PricingServiceSelection } from '../../../services/payment/payment.js';
11
11
  /**
12
12
  * Props for Booking.Root component
@@ -65,7 +65,16 @@ function Root(props) {
65
65
  function mapTimeSlotLocationToServiceLocation(timeSlotLocation) {
66
66
  // TimeSlot location has flat name/formattedAddress at top level
67
67
  // Convert to nested business/custom structure that CoreLocation expects
68
- const locationType = timeSlotLocation.locationType;
68
+ const isCustomer = timeSlotLocation.locationType === auto_sdk_bookings_services_1.LocationTypeEnumLocationType.CUSTOMER;
69
+ const isCustom = timeSlotLocation.locationType === auto_sdk_bookings_services_1.LocationTypeEnumLocationType.CUSTOM;
70
+ // The two SDKs share BUSINESS/CUSTOM/CUSTOMER but the time-slots enum also
71
+ // exposes UNKNOWN_LOCATION_TYPE, which V2Location.type does not accept.
72
+ // Default to BUSINESS for any unrecognized value.
73
+ const type = isCustomer
74
+ ? auto_sdk_bookings_services_1.LocationTypeEnumLocationType.CUSTOMER
75
+ : isCustom
76
+ ? auto_sdk_bookings_services_1.LocationTypeEnumLocationType.CUSTOM
77
+ : auto_sdk_bookings_services_1.LocationTypeEnumLocationType.BUSINESS;
69
78
  const location = {
70
79
  _id: timeSlotLocation._id ?? undefined,
71
80
  name: timeSlotLocation.name ?? undefined,
@@ -77,10 +86,10 @@ function mapTimeSlotLocationToServiceLocation(timeSlotLocation) {
77
86
  };
78
87
  return {
79
88
  _id: timeSlotLocation._id ?? undefined,
80
- type: locationType,
81
- ...(locationType === auto_sdk_bookings_services_1.LocationType.CUSTOMER
89
+ type,
90
+ ...(isCustomer
82
91
  ? null
83
- : locationType === auto_sdk_bookings_services_1.LocationType.CUSTOM
92
+ : isCustom
84
93
  ? { custom: location }
85
94
  : { business: location }),
86
95
  };
@@ -91,7 +100,7 @@ function mapTimeSlotLocationToServiceLocation(timeSlotLocation) {
91
100
  * 2. If not set, fall back to the first service selection's slot location
92
101
  */
93
102
  function resolveLocation(bookingLocation, serviceSelections) {
94
- if (bookingLocation && bookingLocation.type === auto_sdk_bookings_services_1.LocationType.BUSINESS) {
103
+ if (bookingLocation && bookingLocation.type === auto_sdk_bookings_services_1.LocationTypeEnumLocationType.BUSINESS) {
95
104
  return bookingLocation;
96
105
  }
97
106
  // Fallback to first slot's location
@@ -287,9 +296,13 @@ function PaymentData(props) {
287
296
  const { children } = props;
288
297
  const bookingService = (0, services_manager_react_1.useService)(booking_js_1.BookingServiceDefinition);
289
298
  const serviceSelections = bookingService.serviceSelections.get();
299
+ const timezone = bookingService.timezone.get();
290
300
  const pricingServiceSelections = serviceSelections.map((selection) => ({
291
301
  service: selection.service,
292
302
  lineItemId: selection.instanceId,
303
+ localStartDate: selection.timeSlot?.startDate,
304
+ localEndDate: selection.timeSlot?.endDate,
305
+ timeZone: timezone,
293
306
  }));
294
307
  return children({ pricingServiceSelections });
295
308
  }
@@ -6,7 +6,7 @@
6
6
  * @module Core/Location
7
7
  */
8
8
  import React from 'react';
9
- import { LocationType } from '@wix/auto_sdk_bookings_services';
9
+ import { LocationTypeEnumLocationType as LocationType } from '@wix/auto_sdk_bookings_services';
10
10
  import type { AddressData as AddressDataType } from '@wix/headless-components/react';
11
11
  import type { Location } from '../../../services/location-list/location-list.def.js';
12
12
  /**
@@ -90,7 +90,7 @@ function hasLocationData(location) {
90
90
  */
91
91
  function parseLocationAddress(location) {
92
92
  // Handle customer location - return null, let consumer handle
93
- if (location.type !== auto_sdk_bookings_services_1.LocationType.BUSINESS) {
93
+ if (location.type !== auto_sdk_bookings_services_1.LocationTypeEnumLocationType.BUSINESS) {
94
94
  return null;
95
95
  }
96
96
  // Get the common address from the appropriate location type
@@ -123,7 +123,7 @@ function parseLocationAddress(location) {
123
123
  * Get location type from location data
124
124
  */
125
125
  function getLocationType(location) {
126
- return location.type || auto_sdk_bookings_services_1.LocationType.BUSINESS;
126
+ return location.type || auto_sdk_bookings_services_1.LocationTypeEnumLocationType.BUSINESS;
127
127
  }
128
128
  /**
129
129
  * Computes LocationRenderProps from location with label fallbacks
@@ -132,7 +132,7 @@ function computeLocationRenderProps(rawLocation, labels) {
132
132
  // Handle no location
133
133
  if (!rawLocation) {
134
134
  return {
135
- locationType: auto_sdk_bookings_services_1.LocationType.BUSINESS,
135
+ locationType: auto_sdk_bookings_services_1.LocationTypeEnumLocationType.BUSINESS,
136
136
  address: null,
137
137
  name: undefined,
138
138
  locationId: undefined,
@@ -146,8 +146,8 @@ function computeLocationRenderProps(rawLocation, labels) {
146
146
  }
147
147
  const locationType = getLocationType(rawLocation);
148
148
  const hasData = hasLocationData(rawLocation);
149
- const isCustomLocation = locationType === auto_sdk_bookings_services_1.LocationType.CUSTOM;
150
- const isCustomerLocation = locationType === auto_sdk_bookings_services_1.LocationType.CUSTOMER;
149
+ const isCustomLocation = locationType === auto_sdk_bookings_services_1.LocationTypeEnumLocationType.CUSTOM;
150
+ const isCustomerLocation = locationType === auto_sdk_bookings_services_1.LocationTypeEnumLocationType.CUSTOMER;
151
151
  // Compute name with fallback chain:
152
152
  // 1. business.name
153
153
  // 2. custom.address.addressLine
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import React from 'react';
6
6
  import { type ServiceServiceConfig } from '../../../services/service/service.js';
7
- import type { Service, Payment, BookingPolicy, Schedule, StaffMember } from '@wix/auto_sdk_bookings_services';
7
+ import type { Service, Payment, BookingPolicy, Schedule, StaffMember, DurationRange } from '@wix/auto_sdk_bookings_services';
8
8
  import type { MoneyData } from '@wix/headless-components/react';
9
9
  /**
10
10
  * Props for Service.Root component
@@ -50,6 +50,15 @@ export interface InfoProps {
50
50
  description: string;
51
51
  tagline?: string;
52
52
  duration?: number;
53
+ /**
54
+ * Typed range of supported session durations, derived from
55
+ * `service.schedule.availabilityConstraints.sessionDurations`. Set when the
56
+ * service supports two or more distinct durations; otherwise undefined and
57
+ * the single-value `duration` field above should be used. Consumers branch
58
+ * on `range.unitType` (the SDK `UnitType` enum) and read the matching
59
+ * `range.hourOptions` / `range.dayOptions` config.
60
+ */
61
+ durationRange?: DurationRange;
53
62
  type?: string;
54
63
  category?: {
55
64
  name?: string;
@@ -96,9 +96,9 @@ function Info(props) {
96
96
  currency,
97
97
  };
98
98
  }
99
- // Extract duration from schedule.availabilityConstraints.sessionDurations
100
- // Use the first duration if multiple are available
101
- const duration = service.schedule?.availabilityConstraints?.sessionDurations?.[0];
99
+ const constraints = service.schedule?.availabilityConstraints;
100
+ const duration = constraints?.sessionDurations?.[0];
101
+ const durationRange = constraints?.durationRange;
102
102
  // Get staff members from staffMemberDetails.staffMembers
103
103
  // (available when using conditionalFields: ['STAFF_MEMBER_DETAILS'] in queryServices)
104
104
  const staff = service.staffMembers || [];
@@ -128,7 +128,8 @@ function Info(props) {
128
128
  name: service.name || '',
129
129
  description: service.description || '',
130
130
  tagline: service.tagLine || undefined,
131
- duration: duration,
131
+ duration,
132
+ durationRange,
132
133
  type: service.type,
133
134
  category: service.category
134
135
  ? {
@@ -5,7 +5,7 @@
5
5
  import React from 'react';
6
6
  import { AsChildChildren } from '@wix/headless-utils/react';
7
7
  import { MoneyData } from '@wix/headless-components/react';
8
- import { type Service, type Payment } from '@wix/auto_sdk_bookings_services';
8
+ import { type Service, type Payment, type DurationRange as DurationRangeData } from '@wix/auto_sdk_bookings_services';
9
9
  import * as ServiceMediaModule from './ServiceMedia.js';
10
10
  export declare const TestIds: {
11
11
  readonly serviceRoot: "service-root";
@@ -14,6 +14,7 @@ export declare const TestIds: {
14
14
  readonly servicePrice: "service-price";
15
15
  readonly serviceTagline: "service-tagline";
16
16
  readonly serviceDurationInMinutes: "service-duration-in-minutes";
17
+ readonly serviceDurationRange: "service-duration-range";
17
18
  readonly serviceType: "service-type";
18
19
  readonly serviceCategory: "service-category";
19
20
  readonly serviceLocations: "service-locations";
@@ -340,6 +341,72 @@ export interface DurationInMinutesProps extends Omit<React.HTMLAttributes<HTMLEl
340
341
  * ```
341
342
  */
342
343
  export declare const DurationInMinutes: React.ForwardRefExoticComponent<DurationInMinutesProps & React.RefAttributes<HTMLElement>>;
344
+ /**
345
+ * Props for Service DurationRange component
346
+ */
347
+ export interface DurationRangeProps extends Omit<React.HTMLAttributes<HTMLElement>, 'children'> {
348
+ asChild?: boolean;
349
+ children?: AsChildChildren<{
350
+ range: DurationRangeData;
351
+ }>;
352
+ }
353
+ /**
354
+ * Provides the service's supported session duration range as raw SDK data.
355
+ * Renders nothing when the service has fewer than two distinct supported
356
+ * durations — use {@link DurationInMinutes} for that case.
357
+ *
358
+ * The component is intentionally UI-agnostic: it does not pick formatting,
359
+ * units, or labels for you. The default render outputs only the raw
360
+ * `min - max` numbers (no unit text). Consumers wanting unit-aware UI use
361
+ * `asChild` with a custom render and narrow on the SDK `range` payload
362
+ * (`range.hourOptions` / `range.dayOptions` / `range.unitType`, or any
363
+ * other unit configuration the SDK adds in the future).
364
+ *
365
+ * @component
366
+ * @example
367
+ * ```tsx
368
+ * // Default usage - displays raw min/max, e.g. "120 - 540" or "2 - 5"
369
+ * <Service.DurationRange className="text-base text-secondary-foreground" />
370
+ * ```
371
+ *
372
+ * @example
373
+ * ```tsx
374
+ * // asChild with primitive element
375
+ * <Service.DurationRange asChild>
376
+ * <span className="font-semibold" />
377
+ * </Service.DurationRange>
378
+ * ```
379
+ *
380
+ * @example
381
+ * ```tsx
382
+ * // asChild with custom component - narrow on the SDK range payload to
383
+ * // decide unit-specific formatting.
384
+ * <Service.DurationRange asChild>
385
+ * {React.forwardRef(({ range, ...props }, ref) => {
386
+ * if (range.hourOptions) {
387
+ * const { minDurationInMinutes: min, maxDurationInMinutes: max } =
388
+ * range.hourOptions;
389
+ * return (
390
+ * <span ref={ref} {...props}>
391
+ * {min}-{max} min
392
+ * </span>
393
+ * );
394
+ * }
395
+ * if (range.dayOptions) {
396
+ * const { minDurationInDays: min, maxDurationInDays: max } =
397
+ * range.dayOptions;
398
+ * return (
399
+ * <span ref={ref} {...props}>
400
+ * {min}-{max} days
401
+ * </span>
402
+ * );
403
+ * }
404
+ * return <span ref={ref} {...props} />;
405
+ * })}
406
+ * </Service.DurationRange>
407
+ * ```
408
+ */
409
+ export declare const DurationRange: React.ForwardRefExoticComponent<DurationRangeProps & React.RefAttributes<HTMLElement>>;
343
410
  /**
344
411
  * Props for Service Type component
345
412
  */
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.CoverMedia = exports.MainMedia = exports.StaffMembers = exports.Locations = exports.AvailableOnline = exports.DefaultCapacity = exports.Schedule = exports.ScheduleSessionDuration = exports.ScheduleLastSessionEnd = exports.ScheduleFirstSessionStart = exports.Policy = exports.PolicyMaxParticipantsPerBooking = exports.PolicyBookAfterStartEnabled = exports.PolicyWaitlistCapacity = exports.PolicyLatestRescheduleInMinutes = exports.PolicyEarliestBookingInMinutes = exports.PolicyLatestBookingInMinutes = exports.PolicyLatestCancellationInMinutes = exports.Actions = exports.Raw = exports.StaffMemberRepeater = exports.StaffMembersList = exports.LocationRepeater = exports.LocationsList = exports.Category = exports.Type = exports.DurationInMinutes = exports.Tagline = exports.Price = exports.Description = exports.Name = exports.Root = exports.TestIds = void 0;
39
+ exports.CoverMedia = exports.MainMedia = exports.StaffMembers = exports.Locations = exports.AvailableOnline = exports.DefaultCapacity = exports.Schedule = exports.ScheduleSessionDuration = exports.ScheduleLastSessionEnd = exports.ScheduleFirstSessionStart = exports.Policy = exports.PolicyMaxParticipantsPerBooking = exports.PolicyBookAfterStartEnabled = exports.PolicyWaitlistCapacity = exports.PolicyLatestRescheduleInMinutes = exports.PolicyEarliestBookingInMinutes = exports.PolicyLatestBookingInMinutes = exports.PolicyLatestCancellationInMinutes = exports.Actions = exports.Raw = exports.StaffMemberRepeater = exports.StaffMembersList = exports.LocationRepeater = exports.LocationsList = exports.Category = exports.Type = exports.DurationRange = exports.DurationInMinutes = exports.Tagline = exports.Price = exports.Description = exports.Name = exports.Root = exports.TestIds = void 0;
40
40
  const jsx_runtime_1 = require("react/jsx-runtime");
41
41
  /**
42
42
  * Service - High-level component for displaying service information
@@ -63,6 +63,7 @@ exports.TestIds = {
63
63
  servicePrice: 'service-price',
64
64
  serviceTagline: 'service-tagline',
65
65
  serviceDurationInMinutes: 'service-duration-in-minutes',
66
+ serviceDurationRange: 'service-duration-range',
66
67
  serviceType: 'service-type',
67
68
  serviceCategory: 'service-category',
68
69
  serviceLocations: 'service-locations',
@@ -341,6 +342,85 @@ exports.DurationInMinutes = react_1.default.forwardRef((props, ref) => {
341
342
  } }));
342
343
  });
343
344
  exports.DurationInMinutes.displayName = 'Service.DurationInMinutes';
345
+ /**
346
+ * Provides the service's supported session duration range as raw SDK data.
347
+ * Renders nothing when the service has fewer than two distinct supported
348
+ * durations — use {@link DurationInMinutes} for that case.
349
+ *
350
+ * The component is intentionally UI-agnostic: it does not pick formatting,
351
+ * units, or labels for you. The default render outputs only the raw
352
+ * `min - max` numbers (no unit text). Consumers wanting unit-aware UI use
353
+ * `asChild` with a custom render and narrow on the SDK `range` payload
354
+ * (`range.hourOptions` / `range.dayOptions` / `range.unitType`, or any
355
+ * other unit configuration the SDK adds in the future).
356
+ *
357
+ * @component
358
+ * @example
359
+ * ```tsx
360
+ * // Default usage - displays raw min/max, e.g. "120 - 540" or "2 - 5"
361
+ * <Service.DurationRange className="text-base text-secondary-foreground" />
362
+ * ```
363
+ *
364
+ * @example
365
+ * ```tsx
366
+ * // asChild with primitive element
367
+ * <Service.DurationRange asChild>
368
+ * <span className="font-semibold" />
369
+ * </Service.DurationRange>
370
+ * ```
371
+ *
372
+ * @example
373
+ * ```tsx
374
+ * // asChild with custom component - narrow on the SDK range payload to
375
+ * // decide unit-specific formatting.
376
+ * <Service.DurationRange asChild>
377
+ * {React.forwardRef(({ range, ...props }, ref) => {
378
+ * if (range.hourOptions) {
379
+ * const { minDurationInMinutes: min, maxDurationInMinutes: max } =
380
+ * range.hourOptions;
381
+ * return (
382
+ * <span ref={ref} {...props}>
383
+ * {min}-{max} min
384
+ * </span>
385
+ * );
386
+ * }
387
+ * if (range.dayOptions) {
388
+ * const { minDurationInDays: min, maxDurationInDays: max } =
389
+ * range.dayOptions;
390
+ * return (
391
+ * <span ref={ref} {...props}>
392
+ * {min}-{max} days
393
+ * </span>
394
+ * );
395
+ * }
396
+ * return <span ref={ref} {...props} />;
397
+ * })}
398
+ * </Service.DurationRange>
399
+ * ```
400
+ */
401
+ exports.DurationRange = react_1.default.forwardRef((props, ref) => {
402
+ const { asChild, children, ...rest } = props;
403
+ return ((0, jsx_runtime_1.jsx)(CoreService.Info, { children: ({ durationRange }) => {
404
+ if (!durationRange)
405
+ return null;
406
+ // When `unitType` is missing or unrecognised, no default content is
407
+ // rendered — consumers can still read the raw `range` via asChild.
408
+ const { unitType, hourOptions, dayOptions } = durationRange;
409
+ let min;
410
+ let max;
411
+ if (unitType === auto_sdk_bookings_services_1.UnitType.HOUR) {
412
+ min = hourOptions?.minDurationInMinutes;
413
+ max = hourOptions?.maxDurationInMinutes;
414
+ }
415
+ else if (unitType === auto_sdk_bookings_services_1.UnitType.DAY) {
416
+ min = dayOptions?.minDurationInDays;
417
+ max = dayOptions?.maxDurationInDays;
418
+ }
419
+ const hasRange = min != null && max != null;
420
+ return ((0, jsx_runtime_1.jsx)(react_2.AsChildSlot, { ref: ref, asChild: asChild, ...rest, "data-testid": exports.TestIds.serviceDurationRange, customElement: children, customElementProps: { range: durationRange }, children: hasRange ? (0, jsx_runtime_1.jsx)("span", { children: `${min} - ${max}` }) : null }));
421
+ } }));
422
+ });
423
+ exports.DurationRange.displayName = 'Service.DurationRange';
344
424
  /**
345
425
  * Displays the service type (APPOINTMENT, CLASS, COURSE, etc.) with customizable rendering.
346
426
  *
@@ -4,7 +4,7 @@
4
4
  * Persists across page navigation in SPA until page refresh
5
5
  */
6
6
  import { type Signal } from '@wix/services-definitions/core-services/signals';
7
- import type { Service, Location as ServiceLocationType } from '@wix/auto_sdk_bookings_services';
7
+ import type { Service, V2Location as ServiceLocationType } from '@wix/auto_sdk_bookings_services';
8
8
  import type { Resource, EventInfo, Location as TimeSlotLocationType } from '@wix/auto_sdk_bookings_availability-time-slots';
9
9
  import type { FormValues } from '@wix/forms/components';
10
10
  import type { BookResult } from './book-action/types.js';
@@ -5,7 +5,7 @@
5
5
  * @module Services/LocationList/Definition
6
6
  */
7
7
  import type { Signal, ReadOnlySignal } from '@wix/services-definitions/core-services/signals';
8
- import { LocationType, type Service } from '@wix/auto_sdk_bookings_services';
8
+ import { LocationTypeEnumLocationType as LocationType, type Service } from '@wix/auto_sdk_bookings_services';
9
9
  /**
10
10
  * Location type from the SDK
11
11
  * Represents a service location (BUSINESS, CUSTOM, or CUSTOMER type)
@@ -9,7 +9,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.LocationType = exports.LocationListServiceDefinition = void 0;
10
10
  const services_definitions_1 = require("@wix/services-definitions");
11
11
  const auto_sdk_bookings_services_1 = require("@wix/auto_sdk_bookings_services");
12
- Object.defineProperty(exports, "LocationType", { enumerable: true, get: function () { return auto_sdk_bookings_services_1.LocationType; } });
12
+ Object.defineProperty(exports, "LocationType", { enumerable: true, get: function () { return auto_sdk_bookings_services_1.LocationTypeEnumLocationType; } });
13
13
  // ============================================================================
14
14
  // Service Definition
15
15
  // ============================================================================
@@ -35,13 +35,13 @@ const SYNTHETIC_CUSTOMER_ID = 'customer';
35
35
  function buildDisplayLocations(locations, hasCustomLocations, hasCustomerLocations) {
36
36
  const displayLocations = [];
37
37
  // 1. Add all BUSINESS locations directly
38
- const businessLocations = locations.filter((loc) => loc.type === auto_sdk_bookings_services_1.LocationType.BUSINESS || loc.type === undefined);
38
+ const businessLocations = locations.filter((loc) => loc.type === auto_sdk_bookings_services_1.LocationTypeEnumLocationType.BUSINESS || loc.type === undefined);
39
39
  for (const loc of businessLocations) {
40
40
  displayLocations.push(loc);
41
41
  }
42
42
  // Check for existing CUSTOM/CUSTOMER in array
43
- const customFromArray = locations.find((loc) => loc.type === auto_sdk_bookings_services_1.LocationType.CUSTOM);
44
- const customerFromArray = locations.find((loc) => loc.type === auto_sdk_bookings_services_1.LocationType.CUSTOMER);
43
+ const customFromArray = locations.find((loc) => loc.type === auto_sdk_bookings_services_1.LocationTypeEnumLocationType.CUSTOM);
44
+ const customerFromArray = locations.find((loc) => loc.type === auto_sdk_bookings_services_1.LocationTypeEnumLocationType.CUSTOMER);
45
45
  // 2. Add CUSTOM location (from array, or create placeholder)
46
46
  if (customFromArray) {
47
47
  displayLocations.push(customFromArray);
@@ -49,7 +49,7 @@ function buildDisplayLocations(locations, hasCustomLocations, hasCustomerLocatio
49
49
  else if (hasCustomLocations) {
50
50
  // Placeholder custom location (only from explicit flag, not array)
51
51
  const placeholderCustom = {
52
- type: auto_sdk_bookings_services_1.LocationType.CUSTOM,
52
+ type: auto_sdk_bookings_services_1.LocationTypeEnumLocationType.CUSTOM,
53
53
  _id: SYNTHETIC_CUSTOM_ID,
54
54
  };
55
55
  displayLocations.push(placeholderCustom);
@@ -61,7 +61,7 @@ function buildDisplayLocations(locations, hasCustomLocations, hasCustomerLocatio
61
61
  else if (hasCustomerLocations) {
62
62
  // Placeholder customer location (only from explicit flag, not array)
63
63
  const placeholderCustomer = {
64
- type: auto_sdk_bookings_services_1.LocationType.CUSTOMER,
64
+ type: auto_sdk_bookings_services_1.LocationTypeEnumLocationType.CUSTOMER,
65
65
  _id: SYNTHETIC_CUSTOMER_ID,
66
66
  };
67
67
  displayLocations.push(placeholderCustomer);
@@ -89,8 +89,8 @@ exports.LocationListService = services_definitions_1.implementService.withConfig
89
89
  // Initialize raw locations signal
90
90
  const locationsSignal = signalsService.signal(config.locations || []);
91
91
  // Auto-detect from array
92
- const hasCustomInArray = (config.locations || []).some((loc) => loc.type === auto_sdk_bookings_services_1.LocationType.CUSTOM);
93
- const hasCustomerInArray = (config.locations || []).some((loc) => loc.type === auto_sdk_bookings_services_1.LocationType.CUSTOMER);
92
+ const hasCustomInArray = (config.locations || []).some((loc) => loc.type === auto_sdk_bookings_services_1.LocationTypeEnumLocationType.CUSTOM);
93
+ const hasCustomerInArray = (config.locations || []).some((loc) => loc.type === auto_sdk_bookings_services_1.LocationTypeEnumLocationType.CUSTOMER);
94
94
  // Final flags: explicit config OR auto-detected
95
95
  const hasCustomLocationsSignal = signalsService.computed(() => config.hasCustomLocations ?? hasCustomInArray);
96
96
  const hasCustomerLocationsSignal = signalsService.computed(() => config.hasCustomerLocations ?? hasCustomerInArray);
@@ -48,6 +48,12 @@ export interface PricingServiceSelection {
48
48
  service: Service;
49
49
  /** Optional line item ID. If not provided, one will be generated. */
50
50
  lineItemId?: string;
51
+ /** Local start date of the selected slot in ISO-8601 format (e.g. "2024-01-30T13:30:00"). */
52
+ localStartDate?: string;
53
+ /** Local end date of the selected slot in ISO-8601 format (e.g. "2024-01-30T14:30:00"). */
54
+ localEndDate?: string;
55
+ /** IANA time zone identifier for the selected slot (e.g. "America/New_York"). */
56
+ timeZone?: string;
51
57
  }
52
58
  /**
53
59
  * Public config for PaymentService (SSR mode only):