@wix/headless-bookings 0.0.26 → 0.0.28
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/cjs/dist/api/create-booking/index.d.ts +42 -0
- package/cjs/dist/api/create-booking/index.js +35 -0
- package/cjs/dist/api/create-checkout/index.d.ts +40 -0
- package/cjs/dist/api/create-checkout/index.js +37 -0
- package/cjs/dist/api/fetch-availability/index.d.ts +4 -4
- package/cjs/dist/api/fetch-availability/index.js +3 -47
- package/cjs/dist/api/index.d.ts +2 -0
- package/cjs/dist/api/index.js +2 -0
- package/cjs/dist/react/core/time-slot-list/TimeSlot.d.ts +9 -143
- package/cjs/dist/react/core/time-slot-list/TimeSlot.js +32 -167
- package/cjs/dist/react/core/time-slot-list/TimeSlotList.d.ts +3 -2
- package/cjs/dist/react/core/time-slot-list/TimeSlotList.js +1 -1
- package/cjs/dist/react/time-slot-list/TimeSlot.d.ts +15 -113
- package/cjs/dist/react/time-slot-list/TimeSlot.js +26 -125
- package/cjs/dist/react/time-slot-list/TimeSlotList.d.ts +5 -34
- package/cjs/dist/react/time-slot-list/TimeSlotList.js +12 -5
- package/cjs/dist/services/booking/book-action/bookAction.d.ts +2 -2
- package/cjs/dist/services/booking/book-action/bookAction.js +7 -7
- package/cjs/dist/services/booking/book-action/buildBookingRequest.d.ts +1 -1
- package/cjs/dist/services/booking/book-action/buildCheckoutRequest.d.ts +2 -2
- package/cjs/dist/services/booking/book-action/buildCheckoutRequest.js +1 -1
- package/cjs/dist/services/index.d.ts +1 -1
- package/cjs/dist/services/time-slot-list/index.d.ts +1 -1
- package/cjs/dist/services/time-slot-list/time-slot-list.d.ts +4 -4
- package/cjs/dist/services/time-slot-list/time-slot-list.def.d.ts +5 -40
- package/cjs/dist/services/time-slot-list/time-slot-list.js +38 -167
- package/dist/api/create-booking/index.d.ts +42 -0
- package/dist/api/create-booking/index.js +35 -0
- package/dist/api/create-checkout/index.d.ts +40 -0
- package/dist/api/create-checkout/index.js +37 -0
- package/dist/api/fetch-availability/index.d.ts +4 -4
- package/dist/api/fetch-availability/index.js +3 -47
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.js +2 -0
- package/dist/react/core/time-slot-list/TimeSlot.d.ts +9 -143
- package/dist/react/core/time-slot-list/TimeSlot.js +32 -167
- package/dist/react/core/time-slot-list/TimeSlotList.d.ts +3 -2
- package/dist/react/core/time-slot-list/TimeSlotList.js +1 -1
- package/dist/react/time-slot-list/TimeSlot.d.ts +15 -113
- package/dist/react/time-slot-list/TimeSlot.js +26 -125
- package/dist/react/time-slot-list/TimeSlotList.d.ts +5 -34
- package/dist/react/time-slot-list/TimeSlotList.js +12 -5
- package/dist/services/booking/book-action/bookAction.d.ts +2 -2
- package/dist/services/booking/book-action/bookAction.js +7 -7
- package/dist/services/booking/book-action/buildBookingRequest.d.ts +1 -1
- package/dist/services/booking/book-action/buildCheckoutRequest.d.ts +2 -2
- package/dist/services/booking/book-action/buildCheckoutRequest.js +1 -1
- package/dist/services/index.d.ts +1 -1
- package/dist/services/time-slot-list/index.d.ts +1 -1
- package/dist/services/time-slot-list/time-slot-list.d.ts +4 -4
- package/dist/services/time-slot-list/time-slot-list.def.d.ts +5 -40
- package/dist/services/time-slot-list/time-slot-list.js +38 -167
- package/package.json +2 -2
|
@@ -10,37 +10,11 @@ import { BookingServiceDefinition, ANY_STAFF_MEMBER_ID, } from '../booking/booki
|
|
|
10
10
|
// ============================================================================
|
|
11
11
|
// Helpers
|
|
12
12
|
// ============================================================================
|
|
13
|
-
function getDefaultEndDate() {
|
|
14
|
-
return new Date(Date.now() + 7 * 24 * 60 * 60 * 1000);
|
|
15
|
-
}
|
|
16
13
|
function getClientTimezone() {
|
|
17
14
|
return typeof Intl !== 'undefined'
|
|
18
15
|
? Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
19
16
|
: undefined;
|
|
20
17
|
}
|
|
21
|
-
/**
|
|
22
|
-
* Merges new grouped slots with existing ones
|
|
23
|
-
* Slots with the same start time are merged
|
|
24
|
-
*/
|
|
25
|
-
function mergeGroupedSlots(existing, newSlots) {
|
|
26
|
-
const mergedMap = new Map();
|
|
27
|
-
for (const slot of existing) {
|
|
28
|
-
mergedMap.set(slot.localStartDate, slot);
|
|
29
|
-
}
|
|
30
|
-
for (const newSlot of newSlots) {
|
|
31
|
-
const key = newSlot.localStartDate;
|
|
32
|
-
const existingSlot = mergedMap.get(key);
|
|
33
|
-
if (existingSlot) {
|
|
34
|
-
// Merge staffByLocation and originalSlots
|
|
35
|
-
existingSlot.staffByLocation.push(...newSlot.staffByLocation);
|
|
36
|
-
existingSlot.originalSlots.push(...newSlot.originalSlots);
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
mergedMap.set(key, newSlot);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return Array.from(mergedMap.values());
|
|
43
|
-
}
|
|
44
18
|
// ============================================================================
|
|
45
19
|
// Service Implementation
|
|
46
20
|
// ============================================================================
|
|
@@ -48,18 +22,15 @@ export const TimeSlotListService = implementService.withConfig()(TimeSlotListSer
|
|
|
48
22
|
// Get dependent services
|
|
49
23
|
const signalsService = getService(SignalsServiceDefinition);
|
|
50
24
|
const bookingService = getService(BookingServiceDefinition);
|
|
51
|
-
// Initialize default values
|
|
52
|
-
const currentDate = new Date();
|
|
53
25
|
// Initialize Signals
|
|
54
26
|
const timeSlotsSignal = signalsService.signal(config.timeSlots || []);
|
|
55
|
-
const selectionSignal = signalsService.signal(null);
|
|
56
27
|
const isLoadingSignal = signalsService.signal(false);
|
|
57
28
|
const errorSignal = signalsService.signal(null);
|
|
58
29
|
const hasMoreSignal = signalsService.signal(false);
|
|
59
30
|
// Internal only - viewMode is auto-detected based on service types
|
|
60
31
|
const viewModeSignal = signalsService.signal(ViewMode.CLASSIC);
|
|
61
|
-
const startDateSignal = signalsService.signal(config.startDate
|
|
62
|
-
const endDateSignal = signalsService.signal(config.endDate
|
|
32
|
+
const startDateSignal = signalsService.signal(config.startDate);
|
|
33
|
+
const endDateSignal = signalsService.signal(config.endDate);
|
|
63
34
|
const cursorSignal = signalsService.signal(undefined);
|
|
64
35
|
/**
|
|
65
36
|
* Helper: Get services from config or BookingService
|
|
@@ -110,16 +81,11 @@ export const TimeSlotListService = implementService.withConfig()(TimeSlotListSer
|
|
|
110
81
|
};
|
|
111
82
|
/**
|
|
112
83
|
* Action: Select a time slot
|
|
113
|
-
*
|
|
114
|
-
* -
|
|
115
|
-
* -
|
|
116
|
-
* - Many locations + one staff → auto-select staff only
|
|
117
|
-
* - Many locations + many staff → don't auto-select anything
|
|
84
|
+
* Writes selection directly into BookingService (TimeSlotList does not track selection state)
|
|
85
|
+
* - Always sets booking location from slot.location (one location per slot)
|
|
86
|
+
* - Auto-selects staff only when there is exactly one staff option in this slot
|
|
118
87
|
*/
|
|
119
88
|
const selectSlot = (slot) => {
|
|
120
|
-
const currentSelection = selectionSignal.get();
|
|
121
|
-
if (currentSelection?.slot?.id === slot.id)
|
|
122
|
-
return;
|
|
123
89
|
const timeSlot = {
|
|
124
90
|
startDate: slot.localStartDate,
|
|
125
91
|
endDate: slot.localEndDate,
|
|
@@ -128,93 +94,34 @@ export const TimeSlotListService = implementService.withConfig()(TimeSlotListSer
|
|
|
128
94
|
scheduleId: slot.scheduleId ?? undefined,
|
|
129
95
|
eventInfo: slot.eventInfo ?? undefined,
|
|
130
96
|
};
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
else {
|
|
145
|
-
bookingService.actions.clearLocation();
|
|
146
|
-
}
|
|
147
|
-
if (hasOneStaff) {
|
|
148
|
-
const staffMember = allStaffMembers[0];
|
|
149
|
-
staffMemberId = staffMember.id;
|
|
150
|
-
bookingService.actions.updateItem({
|
|
151
|
-
timeSlot,
|
|
152
|
-
resources: [
|
|
153
|
-
{
|
|
154
|
-
_id: staffMemberId,
|
|
155
|
-
name: staffMember.name,
|
|
156
|
-
},
|
|
157
|
-
],
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
bookingService.actions.updateItem({
|
|
162
|
-
timeSlot,
|
|
163
|
-
resources: [],
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
selectionSignal.set({
|
|
167
|
-
slot,
|
|
168
|
-
locationId,
|
|
169
|
-
staffMemberId,
|
|
97
|
+
bookingService.actions.setLocation({
|
|
98
|
+
id: slot.location?._id,
|
|
99
|
+
name: slot.location?.name ?? undefined,
|
|
100
|
+
});
|
|
101
|
+
const staffMembersFromSlot = slot.availableResources[0].resources.map((r) => ({
|
|
102
|
+
id: r._id,
|
|
103
|
+
name: r.name,
|
|
104
|
+
}));
|
|
105
|
+
const resources = staffMembersFromSlot.length === 1 ? staffMembersFromSlot : [];
|
|
106
|
+
bookingService.actions.updateItem({
|
|
107
|
+
timeSlot,
|
|
108
|
+
resources,
|
|
170
109
|
});
|
|
171
|
-
};
|
|
172
|
-
/**
|
|
173
|
-
* Action: Select a location for the current slot
|
|
174
|
-
* Updates the booking service with the location
|
|
175
|
-
* If the location has only one staff member, auto-selects that staff member too
|
|
176
|
-
*/
|
|
177
|
-
const selectLocation = (locationId) => {
|
|
178
|
-
const currentSelections = selectionSignal.get();
|
|
179
|
-
if (!currentSelections?.slot)
|
|
180
|
-
return;
|
|
181
|
-
const slot = currentSelections.slot;
|
|
182
|
-
const locationEntry = slot.staffByLocation.find((loc) => loc.location.id === locationId);
|
|
183
|
-
if (!locationEntry)
|
|
184
|
-
return;
|
|
185
|
-
const { location, staffMembers } = locationEntry;
|
|
186
|
-
bookingService.actions.setLocation(location);
|
|
187
|
-
// If this location has only one staff member, auto-select them
|
|
188
|
-
const hasOneStaff = staffMembers.length === 1;
|
|
189
|
-
if (hasOneStaff) {
|
|
190
|
-
const staffMember = staffMembers[0];
|
|
191
|
-
selectionSignal.set({
|
|
192
|
-
...currentSelections,
|
|
193
|
-
locationId,
|
|
194
|
-
staffMemberId: staffMember.id,
|
|
195
|
-
});
|
|
196
|
-
bookingService.actions.updateItem({
|
|
197
|
-
resources: [
|
|
198
|
-
{
|
|
199
|
-
_id: staffMember.id,
|
|
200
|
-
name: staffMember.name,
|
|
201
|
-
},
|
|
202
|
-
],
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
else {
|
|
206
|
-
selectionSignal.set({ ...currentSelections, locationId });
|
|
207
|
-
}
|
|
208
110
|
};
|
|
209
111
|
/**
|
|
210
112
|
* Action: Select a staff member for the current slot
|
|
211
113
|
* Updates the booking service with the selected resource
|
|
212
|
-
* If the staff member is only available at one location, auto-selects that location too
|
|
213
114
|
*/
|
|
214
115
|
const selectStaffMember = (staffMemberId) => {
|
|
215
|
-
const
|
|
216
|
-
if (!
|
|
116
|
+
const selectedBookingTimeSlot = bookingService.serviceSelections.get()[0]?.timeSlot;
|
|
117
|
+
if (!selectedBookingTimeSlot)
|
|
217
118
|
return;
|
|
119
|
+
const findStaffName = (id) => {
|
|
120
|
+
const slots = timeSlotsSignal.get();
|
|
121
|
+
return (slots
|
|
122
|
+
.flatMap((slot) => slot.availableResources[0].resources)
|
|
123
|
+
.find((r) => r._id === id)?.name ?? undefined);
|
|
124
|
+
};
|
|
218
125
|
if (staffMemberId === ANY_STAFF_MEMBER_ID) {
|
|
219
126
|
bookingService.actions.updateItem({
|
|
220
127
|
resources: [
|
|
@@ -224,54 +131,24 @@ export const TimeSlotListService = implementService.withConfig()(TimeSlotListSer
|
|
|
224
131
|
},
|
|
225
132
|
],
|
|
226
133
|
});
|
|
227
|
-
selectionSignal.set({ ...currentSelections, staffMemberId });
|
|
228
134
|
return;
|
|
229
135
|
}
|
|
230
|
-
const slot = currentSelections.slot;
|
|
231
|
-
// Find all locations that have this staff member
|
|
232
|
-
const locationsWithThisStaff = slot.staffByLocation.filter((loc) => loc.staffMembers.some((s) => s.id === staffMemberId));
|
|
233
|
-
// Find the staff member info
|
|
234
|
-
const staffMember = locationsWithThisStaff[0]?.staffMembers.find((s) => s.id === staffMemberId);
|
|
235
|
-
if (!staffMember)
|
|
236
|
-
return;
|
|
237
136
|
bookingService.actions.updateItem({
|
|
238
137
|
resources: [
|
|
239
138
|
{
|
|
240
|
-
_id:
|
|
241
|
-
name:
|
|
139
|
+
_id: staffMemberId,
|
|
140
|
+
name: findStaffName(staffMemberId),
|
|
242
141
|
},
|
|
243
142
|
],
|
|
244
143
|
});
|
|
245
|
-
// If this staff member is only at one location, auto-select that location
|
|
246
|
-
const hasOneLocation = locationsWithThisStaff.length === 1;
|
|
247
|
-
if (hasOneLocation) {
|
|
248
|
-
const location = locationsWithThisStaff[0].location;
|
|
249
|
-
selectionSignal.set({
|
|
250
|
-
...currentSelections,
|
|
251
|
-
staffMemberId,
|
|
252
|
-
locationId: location.id,
|
|
253
|
-
});
|
|
254
|
-
bookingService.actions.setLocation(location);
|
|
255
|
-
}
|
|
256
|
-
else {
|
|
257
|
-
selectionSignal.set({ ...currentSelections, staffMemberId });
|
|
258
|
-
}
|
|
259
144
|
};
|
|
260
145
|
/**
|
|
261
|
-
* Action: Clear
|
|
146
|
+
* Action: Clear staff selection while keeping the selected time slot
|
|
262
147
|
*/
|
|
263
|
-
const
|
|
264
|
-
const
|
|
265
|
-
if (!
|
|
148
|
+
const clearStaffSelection = () => {
|
|
149
|
+
const selectedBookingTimeSlot = bookingService.serviceSelections.get()[0]?.timeSlot;
|
|
150
|
+
if (!selectedBookingTimeSlot)
|
|
266
151
|
return;
|
|
267
|
-
// Keep the slot, but clear location and staff selections
|
|
268
|
-
selectionSignal.set({
|
|
269
|
-
slot: currentSelection.slot,
|
|
270
|
-
locationId: null,
|
|
271
|
-
staffMemberId: null,
|
|
272
|
-
});
|
|
273
|
-
// Clear selections in booking service
|
|
274
|
-
bookingService.actions.clearLocation();
|
|
275
152
|
bookingService.actions.updateItem({
|
|
276
153
|
resources: [],
|
|
277
154
|
});
|
|
@@ -295,9 +172,10 @@ export const TimeSlotListService = implementService.withConfig()(TimeSlotListSer
|
|
|
295
172
|
viewMode: viewModeSignal.get(),
|
|
296
173
|
...config.filters,
|
|
297
174
|
});
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
175
|
+
timeSlotsSignal.set([
|
|
176
|
+
...timeSlotsSignal.get(),
|
|
177
|
+
...response.timeSlots,
|
|
178
|
+
]);
|
|
301
179
|
const nextCursor = response.cursorPagingMetadata?.cursors?.next ?? undefined;
|
|
302
180
|
cursorSignal.set(nextCursor);
|
|
303
181
|
hasMoreSignal.set(!!nextCursor);
|
|
@@ -345,7 +223,6 @@ export const TimeSlotListService = implementService.withConfig()(TimeSlotListSer
|
|
|
345
223
|
return {
|
|
346
224
|
// State Signals
|
|
347
225
|
timeSlots: timeSlotsSignal,
|
|
348
|
-
selection: selectionSignal,
|
|
349
226
|
isLoading: isLoadingSignal,
|
|
350
227
|
error: errorSignal,
|
|
351
228
|
hasMore: hasMoreSignal,
|
|
@@ -355,9 +232,8 @@ export const TimeSlotListService = implementService.withConfig()(TimeSlotListSer
|
|
|
355
232
|
// Actions
|
|
356
233
|
actions: {
|
|
357
234
|
selectSlot,
|
|
358
|
-
selectLocation,
|
|
359
235
|
selectStaffMember,
|
|
360
|
-
|
|
236
|
+
clearStaffSelection,
|
|
361
237
|
loadMore,
|
|
362
238
|
setDateRange,
|
|
363
239
|
},
|
|
@@ -385,22 +261,17 @@ export const TimeSlotListService = implementService.withConfig()(TimeSlotListSer
|
|
|
385
261
|
* ```
|
|
386
262
|
*/
|
|
387
263
|
export async function loadTimeSlotListConfig(options) {
|
|
388
|
-
const now = new Date();
|
|
389
|
-
const startDate = options.startDate || now;
|
|
390
|
-
const endDate = options.endDate || getDefaultEndDate();
|
|
391
264
|
try {
|
|
392
265
|
const response = await fetchAvailability({
|
|
393
266
|
services: options.services || [],
|
|
394
|
-
fromLocalDate: startDate,
|
|
395
|
-
toLocalDate: endDate,
|
|
267
|
+
fromLocalDate: options.startDate,
|
|
268
|
+
toLocalDate: options.endDate,
|
|
396
269
|
timeZone: options.timezone ?? getClientTimezone(),
|
|
397
270
|
...options.filters,
|
|
398
271
|
});
|
|
399
272
|
const config = {
|
|
400
273
|
...options,
|
|
401
274
|
timeSlots: response.timeSlots || [],
|
|
402
|
-
startDate,
|
|
403
|
-
endDate,
|
|
404
275
|
};
|
|
405
276
|
return { type: 'success', config };
|
|
406
277
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create Booking API
|
|
3
|
+
* Wrapper for the Wix Bookings createBooking SDK function
|
|
4
|
+
*/
|
|
5
|
+
import { type Booking, type CreateBookingResponse, type ParticipantNotification } from '@wix/auto_sdk_bookings_bookings';
|
|
6
|
+
import type { FormValues } from '@wix/form-public';
|
|
7
|
+
/**
|
|
8
|
+
* Options for creating a booking
|
|
9
|
+
*/
|
|
10
|
+
export interface CreateBookingOptions {
|
|
11
|
+
/** Notification settings for participants */
|
|
12
|
+
participantNotification?: ParticipantNotification;
|
|
13
|
+
/** Whether to send SMS reminder */
|
|
14
|
+
sendSmsReminder?: boolean;
|
|
15
|
+
/** Form submission data */
|
|
16
|
+
formSubmission?: FormValues;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Creates a booking with the specified booking data and options
|
|
20
|
+
*
|
|
21
|
+
* @param booking - The booking data
|
|
22
|
+
* @param options - Optional settings for notifications and form submission
|
|
23
|
+
* @returns Promise resolving to the created booking response
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* const response = await createBooking(
|
|
28
|
+
* {
|
|
29
|
+
* selectedPaymentOption: 'ONLINE',
|
|
30
|
+
* totalParticipants: 1,
|
|
31
|
+
* bookedEntity: { slot: { ... } }
|
|
32
|
+
* },
|
|
33
|
+
* {
|
|
34
|
+
* participantNotification: { notifyParticipants: true },
|
|
35
|
+
* sendSmsReminder: true,
|
|
36
|
+
* formSubmission: formValues
|
|
37
|
+
* }
|
|
38
|
+
* );
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare function createBooking(booking: Booking, options?: CreateBookingOptions): Promise<CreateBookingResponse>;
|
|
42
|
+
export type { Booking, CreateBookingRequest, CreateBookingResponse, ParticipantNotification, ContactDetails, } from '@wix/auto_sdk_bookings_bookings';
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create Booking API
|
|
3
|
+
* Wrapper for the Wix Bookings createBooking SDK function
|
|
4
|
+
*/
|
|
5
|
+
import { createBooking as createBookingSdk, } from '@wix/auto_sdk_bookings_bookings';
|
|
6
|
+
/**
|
|
7
|
+
* Creates a booking with the specified booking data and options
|
|
8
|
+
*
|
|
9
|
+
* @param booking - The booking data
|
|
10
|
+
* @param options - Optional settings for notifications and form submission
|
|
11
|
+
* @returns Promise resolving to the created booking response
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const response = await createBooking(
|
|
16
|
+
* {
|
|
17
|
+
* selectedPaymentOption: 'ONLINE',
|
|
18
|
+
* totalParticipants: 1,
|
|
19
|
+
* bookedEntity: { slot: { ... } }
|
|
20
|
+
* },
|
|
21
|
+
* {
|
|
22
|
+
* participantNotification: { notifyParticipants: true },
|
|
23
|
+
* sendSmsReminder: true,
|
|
24
|
+
* formSubmission: formValues
|
|
25
|
+
* }
|
|
26
|
+
* );
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export async function createBooking(booking, options) {
|
|
30
|
+
return createBookingSdk(booking, {
|
|
31
|
+
participantNotification: options?.participantNotification,
|
|
32
|
+
sendSmsReminder: options?.sendSmsReminder,
|
|
33
|
+
formSubmission: options?.formSubmission,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create Checkout API
|
|
3
|
+
* Wrapper for the Wix eCommerce createCheckout SDK function
|
|
4
|
+
*/
|
|
5
|
+
import { type CreateCheckoutRequest, type Checkout } from '@wix/auto_sdk_ecom_checkout';
|
|
6
|
+
/**
|
|
7
|
+
* Response from createCheckout API
|
|
8
|
+
*/
|
|
9
|
+
export interface CreateCheckoutResponse {
|
|
10
|
+
/** The created checkout */
|
|
11
|
+
checkout?: Checkout;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Creates a checkout session with the specified request data
|
|
15
|
+
*
|
|
16
|
+
* @param request - The checkout request data including line items and checkout info
|
|
17
|
+
* @returns Promise resolving to the created checkout response
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const response = await createCheckout({
|
|
22
|
+
* channelType: ChannelType.WEB,
|
|
23
|
+
* lineItems: [
|
|
24
|
+
* {
|
|
25
|
+
* quantity: 1,
|
|
26
|
+
* catalogReference: {
|
|
27
|
+
* catalogItemId: bookingId,
|
|
28
|
+
* appId: BOOKINGS_APP_DEF_ID,
|
|
29
|
+
* },
|
|
30
|
+
* },
|
|
31
|
+
* ],
|
|
32
|
+
* checkoutInfo: {
|
|
33
|
+
* businessLocationId,
|
|
34
|
+
* billingInfo: { ... },
|
|
35
|
+
* },
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare function createCheckout(request: CreateCheckoutRequest): Promise<CreateCheckoutResponse>;
|
|
40
|
+
export { ChannelType, type CreateCheckoutRequest, } from '@wix/auto_sdk_ecom_checkout';
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create Checkout API
|
|
3
|
+
* Wrapper for the Wix eCommerce createCheckout SDK function
|
|
4
|
+
*/
|
|
5
|
+
import { createCheckout as createCheckoutSdk, } from '@wix/auto_sdk_ecom_checkout';
|
|
6
|
+
/**
|
|
7
|
+
* Creates a checkout session with the specified request data
|
|
8
|
+
*
|
|
9
|
+
* @param request - The checkout request data including line items and checkout info
|
|
10
|
+
* @returns Promise resolving to the created checkout response
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const response = await createCheckout({
|
|
15
|
+
* channelType: ChannelType.WEB,
|
|
16
|
+
* lineItems: [
|
|
17
|
+
* {
|
|
18
|
+
* quantity: 1,
|
|
19
|
+
* catalogReference: {
|
|
20
|
+
* catalogItemId: bookingId,
|
|
21
|
+
* appId: BOOKINGS_APP_DEF_ID,
|
|
22
|
+
* },
|
|
23
|
+
* },
|
|
24
|
+
* ],
|
|
25
|
+
* checkoutInfo: {
|
|
26
|
+
* businessLocationId,
|
|
27
|
+
* billingInfo: { ... },
|
|
28
|
+
* },
|
|
29
|
+
* });
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export async function createCheckout(request) {
|
|
33
|
+
const checkout = await createCheckoutSdk(request);
|
|
34
|
+
return { checkout };
|
|
35
|
+
}
|
|
36
|
+
// Re-export types and constants that consumers may need
|
|
37
|
+
export { ChannelType, } from '@wix/auto_sdk_ecom_checkout';
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Time Slot List API
|
|
3
3
|
* Fetches available time slots for booking services from Wix Bookings
|
|
4
4
|
*/
|
|
5
|
-
import { type CursorPaging, type CursorPagingMetadata } from '@wix/auto_sdk_bookings_availability-time-slots';
|
|
5
|
+
import { type TimeSlot, type CursorPaging, type CursorPagingMetadata } from '@wix/auto_sdk_bookings_availability-time-slots';
|
|
6
6
|
import { type Service } from '@wix/auto_sdk_bookings_services';
|
|
7
|
-
import { ViewMode, type
|
|
7
|
+
import { ViewMode, type Location } from '../../services/time-slot-list/time-slot-list.def.js';
|
|
8
8
|
export interface FetchAvailabilityOptions {
|
|
9
9
|
services: Service[];
|
|
10
10
|
fromLocalDate?: string | null;
|
|
@@ -28,14 +28,14 @@ export interface FetchAvailabilityOptions {
|
|
|
28
28
|
* Response from fetchAvailability with grouped time slots
|
|
29
29
|
*/
|
|
30
30
|
export interface FetchAvailabilityResponse {
|
|
31
|
-
/**
|
|
31
|
+
/** time slots */
|
|
32
32
|
timeSlots: TimeSlot[];
|
|
33
33
|
/** Cursor pagination metadata for loading more results */
|
|
34
34
|
cursorPagingMetadata?: CursorPagingMetadata;
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
37
37
|
* Main entry point for fetching availability
|
|
38
|
-
* Detects flow type
|
|
38
|
+
* Detects flow type and calls appropriate API
|
|
39
39
|
*
|
|
40
40
|
* @param options - Fetch options including services, date range, timezone, and view mode
|
|
41
41
|
* @returns Promise with grouped time slots
|
|
@@ -29,50 +29,6 @@ function toLocalDateString(date) {
|
|
|
29
29
|
return format(date, pattern);
|
|
30
30
|
}
|
|
31
31
|
// ============================================================================
|
|
32
|
-
// Grouping Functions
|
|
33
|
-
// ============================================================================
|
|
34
|
-
/**
|
|
35
|
-
* Groups API time slots by their start time
|
|
36
|
-
* Multiple slots for the same time (different locations) are merged into one
|
|
37
|
-
*/
|
|
38
|
-
function groupTimeSlotsByTime(apiSlots) {
|
|
39
|
-
const groupedMap = new Map();
|
|
40
|
-
for (const apiSlot of apiSlots) {
|
|
41
|
-
const key = apiSlot.localStartDate;
|
|
42
|
-
if (!groupedMap.has(key)) {
|
|
43
|
-
// Create new grouped slot - omit location and availableResources
|
|
44
|
-
const { location: _location, availableResources: _availableResources, ...rest } = apiSlot;
|
|
45
|
-
groupedMap.set(key, {
|
|
46
|
-
...rest,
|
|
47
|
-
staffByLocation: [],
|
|
48
|
-
originalSlots: [],
|
|
49
|
-
id: apiSlot.localStartDate,
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
const groupedSlot = groupedMap.get(key);
|
|
53
|
-
// Extract staff members with IDs and names from availableResources
|
|
54
|
-
const staffMembers = (apiSlot.availableResources || [])
|
|
55
|
-
.flatMap((resourceGroup) => resourceGroup.resources || [])
|
|
56
|
-
.filter((resource) => resource._id && resource.name)
|
|
57
|
-
.map((resource) => ({
|
|
58
|
-
id: resource._id,
|
|
59
|
-
name: resource.name,
|
|
60
|
-
}));
|
|
61
|
-
// Add this slot's location/staff info
|
|
62
|
-
const staffByLocation = {
|
|
63
|
-
location: {
|
|
64
|
-
id: apiSlot.location?._id,
|
|
65
|
-
name: apiSlot.location?.name,
|
|
66
|
-
},
|
|
67
|
-
staffMembers,
|
|
68
|
-
};
|
|
69
|
-
groupedSlot.staffByLocation.push(staffByLocation);
|
|
70
|
-
// Store original slot for booking service
|
|
71
|
-
groupedSlot.originalSlots.push(apiSlot);
|
|
72
|
-
}
|
|
73
|
-
return Array.from(groupedMap.values());
|
|
74
|
-
}
|
|
75
|
-
// ============================================================================
|
|
76
32
|
// Internal Flow Detection
|
|
77
33
|
// ============================================================================
|
|
78
34
|
/**
|
|
@@ -98,7 +54,7 @@ function detectFlow(bookingServices, viewMode) {
|
|
|
98
54
|
}
|
|
99
55
|
/**
|
|
100
56
|
* Main entry point for fetching availability
|
|
101
|
-
* Detects flow type
|
|
57
|
+
* Detects flow type and calls appropriate API
|
|
102
58
|
*
|
|
103
59
|
* @param options - Fetch options including services, date range, timezone, and view mode
|
|
104
60
|
* @returns Promise with grouped time slots
|
|
@@ -158,7 +114,7 @@ export async function fetchAvailability({ services: selectedServices, viewMode =
|
|
|
158
114
|
timeSlotsPerDay,
|
|
159
115
|
});
|
|
160
116
|
return {
|
|
161
|
-
timeSlots:
|
|
117
|
+
timeSlots: response.timeSlots || [],
|
|
162
118
|
cursorPagingMetadata: response.cursorPagingMetadata,
|
|
163
119
|
};
|
|
164
120
|
}
|
|
@@ -188,7 +144,7 @@ export async function fetchAvailability({ services: selectedServices, viewMode =
|
|
|
188
144
|
maxSlotsPerDay: timeSlotsPerDay,
|
|
189
145
|
});
|
|
190
146
|
return {
|
|
191
|
-
timeSlots:
|
|
147
|
+
timeSlots: response.timeSlots || [],
|
|
192
148
|
cursorPagingMetadata: response.pagingMetadata,
|
|
193
149
|
};
|
|
194
150
|
}
|
package/dist/api/index.d.ts
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export { getServiceById, getServiceBySlug, queryServices, type PagingMetadata, type ServiceListFilters, type QueryServicesRequest, } from './query-services/index.js';
|
|
8
8
|
export { fetchAvailability } from './fetch-availability/index.js';
|
|
9
|
+
export { createBooking, type CreateBookingOptions, type Booking, type CreateBookingRequest, type CreateBookingResponse, type ParticipantNotification, type ContactDetails, } from './create-booking/index.js';
|
|
10
|
+
export { createCheckout, ChannelType, type CreateCheckoutRequest, type CreateCheckoutResponse, } from './create-checkout/index.js';
|
|
9
11
|
/**
|
|
10
12
|
* PagingMetadata includes:
|
|
11
13
|
* - limit: Number of items per page
|
package/dist/api/index.js
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export { getServiceById, getServiceBySlug, queryServices, } from './query-services/index.js';
|
|
8
8
|
export { fetchAvailability } from './fetch-availability/index.js';
|
|
9
|
+
export { createBooking, } from './create-booking/index.js';
|
|
10
|
+
export { createCheckout, ChannelType, } from './create-checkout/index.js';
|
|
9
11
|
/**
|
|
10
12
|
* PagingMetadata includes:
|
|
11
13
|
* - limit: Number of items per page
|