@wix/headless-bookings 0.0.62 → 0.0.64

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 (57) hide show
  1. package/cjs/dist/__mocks__/time-slots.js +1 -0
  2. package/cjs/dist/api/index.d.ts +2 -2
  3. package/cjs/dist/api/index.js +2 -2
  4. package/cjs/dist/api/query-locations/index.d.ts +14 -0
  5. package/cjs/dist/api/query-locations/index.js +27 -0
  6. package/cjs/dist/api/query-services/index.d.ts +5 -0
  7. package/cjs/dist/api/query-services/index.js +2 -2
  8. package/cjs/dist/react/core/location/Location.d.ts +2 -0
  9. package/cjs/dist/react/core/location/Location.js +14 -1
  10. package/cjs/dist/react/core/time-slot-list/TimeSlot.js +0 -2
  11. package/cjs/dist/react/core/time-slot-list/TimeSlotList.d.ts +4 -2
  12. package/cjs/dist/react/core/time-slot-list/TimeSlotList.js +19 -8
  13. package/cjs/dist/react/index.d.ts +0 -1
  14. package/cjs/dist/react/index.js +1 -1
  15. package/cjs/dist/react/location/Location.d.ts +4 -0
  16. package/cjs/dist/react/location/Location.js +20 -2
  17. package/cjs/dist/react/location/LocationList.d.ts +4 -0
  18. package/cjs/dist/react/location/LocationList.js +33 -7
  19. package/cjs/dist/react/time-slot-list/TimeSlotList.d.ts +5 -3
  20. package/cjs/dist/react/time-slot-list/TimeSlotList.js +2 -6
  21. package/cjs/dist/services/index.d.ts +2 -1
  22. package/cjs/dist/services/index.js +2 -1
  23. package/cjs/dist/services/location-list/location-list.d.ts +1 -0
  24. package/cjs/dist/services/location-list/location-list.js +3 -2
  25. package/cjs/dist/services/time-slot-list/time-slot-list.def.d.ts +1 -0
  26. package/cjs/dist/services/time-slot-list/time-slot-list.js +2 -9
  27. package/cjs/dist/utils/navigation.d.ts +11 -1
  28. package/cjs/dist/utils/navigation.js +53 -22
  29. package/dist/__mocks__/time-slots.js +1 -0
  30. package/dist/api/index.d.ts +2 -2
  31. package/dist/api/index.js +2 -2
  32. package/dist/api/query-locations/index.d.ts +14 -0
  33. package/dist/api/query-locations/index.js +27 -0
  34. package/dist/api/query-services/index.d.ts +5 -0
  35. package/dist/api/query-services/index.js +2 -2
  36. package/dist/react/core/location/Location.d.ts +2 -0
  37. package/dist/react/core/location/Location.js +14 -1
  38. package/dist/react/core/time-slot-list/TimeSlot.js +0 -2
  39. package/dist/react/core/time-slot-list/TimeSlotList.d.ts +4 -2
  40. package/dist/react/core/time-slot-list/TimeSlotList.js +19 -8
  41. package/dist/react/index.d.ts +0 -1
  42. package/dist/react/index.js +1 -1
  43. package/dist/react/location/Location.d.ts +4 -0
  44. package/dist/react/location/Location.js +20 -2
  45. package/dist/react/location/LocationList.d.ts +4 -0
  46. package/dist/react/location/LocationList.js +33 -7
  47. package/dist/react/time-slot-list/TimeSlotList.d.ts +5 -3
  48. package/dist/react/time-slot-list/TimeSlotList.js +2 -6
  49. package/dist/services/index.d.ts +2 -1
  50. package/dist/services/index.js +2 -1
  51. package/dist/services/location-list/location-list.d.ts +1 -0
  52. package/dist/services/location-list/location-list.js +3 -2
  53. package/dist/services/time-slot-list/time-slot-list.def.d.ts +1 -0
  54. package/dist/services/time-slot-list/time-slot-list.js +2 -9
  55. package/dist/utils/navigation.d.ts +11 -1
  56. package/dist/utils/navigation.js +53 -22
  57. package/package.json +2 -2
@@ -19,15 +19,12 @@ function getClientTimezone() {
19
19
  // Service Implementation
20
20
  // ============================================================================
21
21
  export const TimeSlotListService = implementService.withConfig()(TimeSlotListServiceDefinition, ({ getService, config }) => {
22
- // Get dependent services
23
22
  const signalsService = getService(SignalsServiceDefinition);
24
23
  const bookingService = getService(BookingServiceDefinition);
25
- // Initialize Signals
26
24
  const timeSlotsSignal = signalsService.signal(config.timeSlots || []);
27
25
  const isLoadingSignal = signalsService.signal(false);
28
26
  const errorSignal = signalsService.signal(null);
29
27
  const hasMoreSignal = signalsService.signal(false);
30
- // Internal only - viewMode is auto-detected based on service types
31
28
  const viewModeSignal = signalsService.signal(ViewMode.CLASSIC);
32
29
  const dateRangeSignal = signalsService.signal({
33
30
  start: config.startDate,
@@ -201,8 +198,7 @@ export const TimeSlotListService = implementService.withConfig()(TimeSlotListSer
201
198
  : undefined;
202
199
  });
203
200
  let isFirstRun = true;
204
- signalsService.effect(() => {
205
- // Dependencies - trigger refetch when these change
201
+ const dispose = signalsService.effect(() => {
206
202
  dateRangeSignal.get();
207
203
  bookingService.timezone.get();
208
204
  bookingService.location.get();
@@ -215,16 +211,12 @@ export const TimeSlotListService = implementService.withConfig()(TimeSlotListSer
215
211
  }
216
212
  fetchTimeSlots();
217
213
  });
218
- // Return service API
219
214
  return {
220
- // State Signals
221
215
  timeSlots: timeSlotsSignal,
222
216
  isLoading: isLoadingSignal,
223
217
  error: errorSignal,
224
218
  hasMore: hasMoreSignal,
225
- // Configuration Signals (viewMode is internal only)
226
219
  dateRange: dateRangeSignal,
227
- // Actions
228
220
  actions: {
229
221
  selectSlot,
230
222
  selectStaffMember,
@@ -232,6 +224,7 @@ export const TimeSlotListService = implementService.withConfig()(TimeSlotListSer
232
224
  loadMore,
233
225
  setDateRange,
234
226
  },
227
+ dispose,
235
228
  };
236
229
  });
237
230
  /**
@@ -1,7 +1,17 @@
1
1
  import type { ServiceSelectionTimeSlot } from '../services/booking/booking.js';
2
2
  import type { Service } from '@wix/auto_sdk_bookings_services';
3
3
  export declare function navigateToCheckout(checkoutId: string): Promise<void>;
4
- export declare function navigateToBookingForm({ timeSlot, service, }: {
4
+ /**
5
+ * Cleans a redirect URL by extracting the redirectUrl param and removing:
6
+ * - The 'origin' query parameter
7
+ * - Any query parameters with empty values
8
+ *
9
+ * @param fullUrl - The full URL containing the redirectUrl query parameter
10
+ * @returns The cleaned redirect URL
11
+ */
12
+ export declare function cleanRedirectUrl(fullUrl: string): string;
13
+ export declare function navigateToBookingForm({ timeSlot, service, timezone, }: {
5
14
  timeSlot: ServiceSelectionTimeSlot;
6
15
  service: Service;
16
+ timezone?: string;
7
17
  }): Promise<void>;
@@ -27,7 +27,32 @@ function mapTimeSlotLocationToBookingLocation(timeSlotLocationType) {
27
27
  return BookingsLocationType.UNDEFINED;
28
28
  }
29
29
  }
30
- export async function navigateToBookingForm({ timeSlot, service, }) {
30
+ /**
31
+ * Cleans a redirect URL by extracting the redirectUrl param and removing:
32
+ * - The 'origin' query parameter
33
+ * - Any query parameters with empty values
34
+ *
35
+ * @param fullUrl - The full URL containing the redirectUrl query parameter
36
+ * @returns The cleaned redirect URL
37
+ */
38
+ export function cleanRedirectUrl(fullUrl) {
39
+ const url = new URL(fullUrl);
40
+ const redirectUrl = url.searchParams.get('redirectUrl');
41
+ if (!redirectUrl) {
42
+ return fullUrl;
43
+ }
44
+ const redirectParsed = new URL(redirectUrl);
45
+ // Remove origin param
46
+ redirectParsed.searchParams.delete('origin');
47
+ // Remove empty params
48
+ for (const [key, value] of [...redirectParsed.searchParams.entries()]) {
49
+ if (!value) {
50
+ redirectParsed.searchParams.delete(key);
51
+ }
52
+ }
53
+ return redirectParsed.toString();
54
+ }
55
+ export async function navigateToBookingForm({ timeSlot, service, timezone, }) {
31
56
  if (!timeSlot) {
32
57
  throw new Error('No time slot provided');
33
58
  }
@@ -36,30 +61,36 @@ export async function navigateToBookingForm({ timeSlot, service, }) {
36
61
  }
37
62
  // Get the first resource (staff member) if available
38
63
  const selectedResource = timeSlot.resources?.[0];
64
+ // Destructure to exclude properties we handle separately (location has incompatible types)
65
+ const { location: _location, resources: _resources, ...restTimeSlot } = timeSlot;
66
+ // Build slot object, only including optional properties when they have values
67
+ const slot = {
68
+ ...restTimeSlot,
69
+ scheduleId: timeSlot.scheduleId,
70
+ startDate: timeSlot.startDate,
71
+ endDate: timeSlot.endDate,
72
+ ...(service._id && { serviceId: service._id }),
73
+ ...(timezone && { timezone }),
74
+ ...(selectedResource && {
75
+ resource: {
76
+ _id: selectedResource._id,
77
+ name: selectedResource.name,
78
+ },
79
+ }),
80
+ ...(timeSlot.location && {
81
+ location: {
82
+ _id: timeSlot.location._id,
83
+ name: timeSlot.location.name,
84
+ formattedAddress: timeSlot.location.formattedAddress,
85
+ locationType: mapTimeSlotLocationToBookingLocation(timeSlot.location.locationType),
86
+ },
87
+ }),
88
+ };
39
89
  const { redirectSession } = await redirects.createRedirectSession({
40
90
  bookingsCheckout: {
41
91
  slotAvailability: {
42
92
  bookable: true,
43
- slot: {
44
- ...timeSlot,
45
- serviceId: service._id ?? undefined,
46
- scheduleId: timeSlot.scheduleId,
47
- startDate: timeSlot.startDate,
48
- endDate: timeSlot.endDate,
49
- timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
50
- resource: selectedResource
51
- ? {
52
- _id: selectedResource._id,
53
- name: selectedResource.name,
54
- }
55
- : undefined,
56
- location: {
57
- _id: timeSlot.location?._id,
58
- name: timeSlot.location?.name,
59
- formattedAddress: timeSlot.location?.formattedAddress,
60
- locationType: mapTimeSlotLocationToBookingLocation(timeSlot.location?.locationType),
61
- },
62
- },
93
+ slot,
63
94
  },
64
95
  },
65
96
  callbacks: {
@@ -67,7 +98,7 @@ export async function navigateToBookingForm({ timeSlot, service, }) {
67
98
  },
68
99
  });
69
100
  if (redirectSession?.fullUrl) {
70
- window.location.href = redirectSession.fullUrl;
101
+ window.location.href = cleanRedirectUrl(redirectSession.fullUrl);
71
102
  }
72
103
  else {
73
104
  throw new Error('Failed to create redirect session');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/headless-bookings",
3
- "version": "0.0.62",
3
+ "version": "0.0.64",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -72,5 +72,5 @@
72
72
  "groupId": "com.wixpress.headless-components"
73
73
  }
74
74
  },
75
- "falconPackageHash": "a7ee3575b035403add534d60cde7f1bc57053324c9c08aa82811ca8b"
75
+ "falconPackageHash": "8011be143d4873e29873f1d8216f8638894a024f49336de8a215b152"
76
76
  }