@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
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* which provides the TimeSlotProvider context.
|
|
7
7
|
*/
|
|
8
8
|
import React from 'react';
|
|
9
|
-
import {
|
|
9
|
+
import type { TimeSlot as TimeSlotType } from '@wix/auto_sdk_bookings_availability-time-slots';
|
|
10
10
|
/**
|
|
11
11
|
* Context value for TimeSlot components
|
|
12
12
|
*/
|
|
@@ -35,30 +35,6 @@ export interface TimeSlotProviderProps {
|
|
|
35
35
|
* Not used directly by consumers - only by TimeSlotList.TimeSlotRepeater.
|
|
36
36
|
*/
|
|
37
37
|
export declare function TimeSlotProvider(props: TimeSlotProviderProps): React.ReactNode;
|
|
38
|
-
/**
|
|
39
|
-
* Context value for Location components
|
|
40
|
-
*/
|
|
41
|
-
export interface LocationContextValue {
|
|
42
|
-
location: LocationData;
|
|
43
|
-
selectLocation: () => void;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Hook to access Location context
|
|
47
|
-
* @throws Error if used outside of LocationProvider
|
|
48
|
-
*/
|
|
49
|
-
export declare function useLocationContext(): LocationContextValue;
|
|
50
|
-
/**
|
|
51
|
-
* Props for LocationProvider
|
|
52
|
-
*/
|
|
53
|
-
export interface LocationProviderProps {
|
|
54
|
-
children: React.ReactNode;
|
|
55
|
-
location: LocationData;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Provider component used by LocationRepeater to provide context.
|
|
59
|
-
* Not used directly by consumers - only by TimeSlot.LocationRepeater.
|
|
60
|
-
*/
|
|
61
|
-
export declare function LocationProvider(props: LocationProviderProps): React.ReactNode;
|
|
62
38
|
/**
|
|
63
39
|
* Context value for StaffMember components
|
|
64
40
|
*/
|
|
@@ -94,6 +70,8 @@ export interface InfoProps {
|
|
|
94
70
|
endDate: Date;
|
|
95
71
|
/** Calculated duration in minutes */
|
|
96
72
|
durationInMinutes: number;
|
|
73
|
+
/** Location name */
|
|
74
|
+
locationName: string;
|
|
97
75
|
/** Whether the timeSlot is bookable */
|
|
98
76
|
bookable: boolean;
|
|
99
77
|
/** Whether this timeSlot is currently selected */
|
|
@@ -127,8 +105,8 @@ export interface ActionsProps {
|
|
|
127
105
|
children: (data: {
|
|
128
106
|
/** Action to select this timeSlot */
|
|
129
107
|
selectTimeSlot: () => void;
|
|
130
|
-
/** Action to clear
|
|
131
|
-
|
|
108
|
+
/** Action to clear staff selection */
|
|
109
|
+
clearStaffSelection?: () => void;
|
|
132
110
|
/** The raw timeSlot object */
|
|
133
111
|
timeSlot: TimeSlotType;
|
|
134
112
|
/** Whether the timeSlot is bookable */
|
|
@@ -158,112 +136,6 @@ export interface ActionsProps {
|
|
|
158
136
|
* ```
|
|
159
137
|
*/
|
|
160
138
|
export declare function Actions(props: ActionsProps): React.ReactNode;
|
|
161
|
-
/**
|
|
162
|
-
* Location data with selection state
|
|
163
|
-
*/
|
|
164
|
-
export interface LocationData {
|
|
165
|
-
/** Location ID */
|
|
166
|
-
id: string;
|
|
167
|
-
/** Location name */
|
|
168
|
-
name: string;
|
|
169
|
-
/** Whether this location is currently selected */
|
|
170
|
-
isSelected: boolean;
|
|
171
|
-
/** Whether this location is selectable (compatible with selected staff, or no staff selected) */
|
|
172
|
-
isSelectable: boolean;
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Props for Locations render prop component
|
|
176
|
-
*/
|
|
177
|
-
export interface LocationsProps {
|
|
178
|
-
children: (data: {
|
|
179
|
-
/** Array of locations with selection state */
|
|
180
|
-
locations: LocationData[];
|
|
181
|
-
/** Action to select a location */
|
|
182
|
-
selectLocation: (locationId: string) => void;
|
|
183
|
-
}) => React.ReactNode;
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* Core component that provides access to time slot locations via render props.
|
|
187
|
-
* Extracts locations from slot.staffByLocation and enriches with name from originalSlots.
|
|
188
|
-
* Each location includes isSelected and isSelectable based on current selection state.
|
|
189
|
-
*
|
|
190
|
-
* Returns null if there's only 1 location (nothing to choose from).
|
|
191
|
-
*
|
|
192
|
-
* @component
|
|
193
|
-
* @example
|
|
194
|
-
* ```tsx
|
|
195
|
-
* <CoreTimeSlot.Locations>
|
|
196
|
-
* {({ locations, locationsCount, selectLocation }) => (
|
|
197
|
-
* <GenericList.Root items={locations}>
|
|
198
|
-
* {children}
|
|
199
|
-
* </GenericList.Root>
|
|
200
|
-
* )}
|
|
201
|
-
* </CoreTimeSlot.Locations>
|
|
202
|
-
* ```
|
|
203
|
-
*/
|
|
204
|
-
export declare function Locations(props: LocationsProps): React.ReactNode;
|
|
205
|
-
/**
|
|
206
|
-
* Props for LocationInfo render prop component
|
|
207
|
-
*/
|
|
208
|
-
export interface LocationInfoProps {
|
|
209
|
-
children: (data: {
|
|
210
|
-
/** Location name */
|
|
211
|
-
name: string;
|
|
212
|
-
/** Whether this location is currently selected */
|
|
213
|
-
isSelected: boolean;
|
|
214
|
-
/** Whether this location is selectable */
|
|
215
|
-
isSelectable: boolean;
|
|
216
|
-
/** The raw location object */
|
|
217
|
-
location: LocationData;
|
|
218
|
-
}) => React.ReactNode;
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* Core component that provides access to location info via render props.
|
|
222
|
-
* Must be used within LocationProvider.
|
|
223
|
-
*
|
|
224
|
-
* @component
|
|
225
|
-
* @example
|
|
226
|
-
* ```tsx
|
|
227
|
-
* <LocationInfo>
|
|
228
|
-
* {({ name, isSelected, isSelectable }) => (
|
|
229
|
-
* <span>{name}</span>
|
|
230
|
-
* )}
|
|
231
|
-
* </LocationInfo>
|
|
232
|
-
* ```
|
|
233
|
-
*/
|
|
234
|
-
export declare function LocationInfo(props: LocationInfoProps): React.ReactNode;
|
|
235
|
-
/**
|
|
236
|
-
* Props for LocationActions render prop component
|
|
237
|
-
*/
|
|
238
|
-
export interface LocationActionsProps {
|
|
239
|
-
children: (data: {
|
|
240
|
-
/** Action to select this location */
|
|
241
|
-
selectLocation: () => void;
|
|
242
|
-
/** Whether this location is currently selected */
|
|
243
|
-
isSelected: boolean;
|
|
244
|
-
/** Whether this location is selectable */
|
|
245
|
-
isSelectable: boolean;
|
|
246
|
-
/** The raw location object */
|
|
247
|
-
location: LocationData;
|
|
248
|
-
}) => React.ReactNode;
|
|
249
|
-
}
|
|
250
|
-
/**
|
|
251
|
-
* Core component that provides location actions via render props.
|
|
252
|
-
* Must be used within LocationProvider.
|
|
253
|
-
*
|
|
254
|
-
* @component
|
|
255
|
-
* @example
|
|
256
|
-
* ```tsx
|
|
257
|
-
* <LocationActions>
|
|
258
|
-
* {({ selectLocation, isSelected, isSelectable }) => (
|
|
259
|
-
* <button onClick={selectLocation} disabled={!isSelectable}>
|
|
260
|
-
* {isSelected ? 'Selected' : 'Select'}
|
|
261
|
-
* </button>
|
|
262
|
-
* )}
|
|
263
|
-
* </LocationActions>
|
|
264
|
-
* ```
|
|
265
|
-
*/
|
|
266
|
-
export declare function LocationActions(props: LocationActionsProps): React.ReactNode;
|
|
267
139
|
/**
|
|
268
140
|
* Staff member data with selection state
|
|
269
141
|
*/
|
|
@@ -274,8 +146,6 @@ export interface StaffMemberData {
|
|
|
274
146
|
name: string;
|
|
275
147
|
/** Whether this staff member is currently selected */
|
|
276
148
|
isSelected: boolean;
|
|
277
|
-
/** Whether this staff member is selectable (works at selected location, or no location selected) */
|
|
278
|
-
isSelectable: boolean;
|
|
279
149
|
}
|
|
280
150
|
/**
|
|
281
151
|
* Props for StaffMembers render prop component
|
|
@@ -291,7 +161,7 @@ export interface StaffMembersProps {
|
|
|
291
161
|
/**
|
|
292
162
|
* Core component that provides access to time slot staff members via render props.
|
|
293
163
|
* Extracts unique staff members from slot.staffByLocation (names already included).
|
|
294
|
-
* Each staff member includes isSelected
|
|
164
|
+
* Each staff member includes isSelected based on current selection state.
|
|
295
165
|
*
|
|
296
166
|
* Returns null if there's only 1 staff member (nothing to choose from).
|
|
297
167
|
*
|
|
@@ -317,8 +187,6 @@ export interface StaffMemberInfoProps {
|
|
|
317
187
|
name: string;
|
|
318
188
|
/** Whether this staff member is currently selected */
|
|
319
189
|
isSelected: boolean;
|
|
320
|
-
/** Whether this staff member is selectable */
|
|
321
|
-
isSelectable: boolean;
|
|
322
190
|
/** The raw staff member object */
|
|
323
191
|
staffMember: StaffMemberData;
|
|
324
192
|
}) => React.ReactNode;
|
|
@@ -331,7 +199,7 @@ export interface StaffMemberInfoProps {
|
|
|
331
199
|
* @example
|
|
332
200
|
* ```tsx
|
|
333
201
|
* <StaffMemberInfo>
|
|
334
|
-
* {({ name, isSelected
|
|
202
|
+
* {({ name, isSelected }) => (
|
|
335
203
|
* <span>{name}</span>
|
|
336
204
|
* )}
|
|
337
205
|
* </StaffMemberInfo>
|
|
@@ -347,8 +215,6 @@ export interface StaffMemberActionsProps {
|
|
|
347
215
|
selectStaffMember: () => void;
|
|
348
216
|
/** Whether this staff member is currently selected */
|
|
349
217
|
isSelected: boolean;
|
|
350
|
-
/** Whether this staff member is selectable */
|
|
351
|
-
isSelectable: boolean;
|
|
352
218
|
/** The raw staff member object */
|
|
353
219
|
staffMember: StaffMemberData;
|
|
354
220
|
}) => React.ReactNode;
|
|
@@ -361,8 +227,8 @@ export interface StaffMemberActionsProps {
|
|
|
361
227
|
* @example
|
|
362
228
|
* ```tsx
|
|
363
229
|
* <StaffMemberActions>
|
|
364
|
-
* {({ selectStaffMember, isSelected
|
|
365
|
-
* <button onClick={selectStaffMember}
|
|
230
|
+
* {({ selectStaffMember, isSelected }) => (
|
|
231
|
+
* <button onClick={selectStaffMember}>
|
|
366
232
|
* {isSelected ? 'Selected' : 'Select'}
|
|
367
233
|
* </button>
|
|
368
234
|
* )}
|
|
@@ -8,8 +8,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
8
8
|
*/
|
|
9
9
|
import React from 'react';
|
|
10
10
|
import { useService } from '@wix/services-manager-react';
|
|
11
|
-
import { TimeSlotListServiceDefinition
|
|
12
|
-
import { ANY_STAFF_MEMBER_ID } from '../../../services/booking/booking.js';
|
|
11
|
+
import { TimeSlotListServiceDefinition } from '../../../services/time-slot-list/time-slot-list.def.js';
|
|
12
|
+
import { ANY_STAFF_MEMBER_ID, BookingServiceDefinition, } from '../../../services/booking/booking.js';
|
|
13
13
|
const TimeSlotContext = React.createContext(null);
|
|
14
14
|
/**
|
|
15
15
|
* Hook to access TimeSlot context
|
|
@@ -29,8 +29,11 @@ export function useTimeSlotContext() {
|
|
|
29
29
|
export function TimeSlotProvider(props) {
|
|
30
30
|
const { children, timeSlot } = props;
|
|
31
31
|
const service = useService(TimeSlotListServiceDefinition);
|
|
32
|
-
const
|
|
33
|
-
const
|
|
32
|
+
const bookingService = useService(BookingServiceDefinition);
|
|
33
|
+
const selectedTimeSlot = bookingService.serviceSelections.get()[0]?.timeSlot;
|
|
34
|
+
const selectedLocationId = bookingService.location.get()?.id;
|
|
35
|
+
const isSelected = selectedTimeSlot?.startDate === timeSlot.localStartDate &&
|
|
36
|
+
selectedLocationId === timeSlot.location?._id;
|
|
34
37
|
const selectTimeSlot = () => {
|
|
35
38
|
service.actions.selectSlot(timeSlot);
|
|
36
39
|
};
|
|
@@ -41,34 +44,6 @@ export function TimeSlotProvider(props) {
|
|
|
41
44
|
};
|
|
42
45
|
return (_jsx(TimeSlotContext.Provider, { value: contextValue, children: children }));
|
|
43
46
|
}
|
|
44
|
-
const LocationContext = React.createContext(null);
|
|
45
|
-
/**
|
|
46
|
-
* Hook to access Location context
|
|
47
|
-
* @throws Error if used outside of LocationProvider
|
|
48
|
-
*/
|
|
49
|
-
export function useLocationContext() {
|
|
50
|
-
const context = React.useContext(LocationContext);
|
|
51
|
-
if (!context) {
|
|
52
|
-
throw new Error('Location components must be used within LocationProvider');
|
|
53
|
-
}
|
|
54
|
-
return context;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Provider component used by LocationRepeater to provide context.
|
|
58
|
-
* Not used directly by consumers - only by TimeSlot.LocationRepeater.
|
|
59
|
-
*/
|
|
60
|
-
export function LocationProvider(props) {
|
|
61
|
-
const { children, location } = props;
|
|
62
|
-
const service = useService(TimeSlotListServiceDefinition);
|
|
63
|
-
const selectLocation = () => {
|
|
64
|
-
service.actions.selectLocation(location.id);
|
|
65
|
-
};
|
|
66
|
-
const contextValue = {
|
|
67
|
-
location,
|
|
68
|
-
selectLocation,
|
|
69
|
-
};
|
|
70
|
-
return (_jsx(LocationContext.Provider, { value: contextValue, children: children }));
|
|
71
|
-
}
|
|
72
47
|
const StaffMemberContext = React.createContext(null);
|
|
73
48
|
/**
|
|
74
49
|
* Hook to access StaffMember context
|
|
@@ -118,6 +93,7 @@ export function Info(props) {
|
|
|
118
93
|
const { timeSlot, isSelected } = useTimeSlotContext();
|
|
119
94
|
const startDate = new Date(timeSlot.localStartDate);
|
|
120
95
|
const endDate = new Date(timeSlot.localEndDate);
|
|
96
|
+
const locationName = timeSlot.location?.name ?? '';
|
|
121
97
|
const bookable = timeSlot.bookable ?? false;
|
|
122
98
|
// Calculate duration from start and end dates
|
|
123
99
|
const durationInMinutes = Math.round((endDate.getTime() - startDate.getTime()) / (1000 * 60));
|
|
@@ -125,6 +101,7 @@ export function Info(props) {
|
|
|
125
101
|
startDate,
|
|
126
102
|
endDate,
|
|
127
103
|
durationInMinutes,
|
|
104
|
+
locationName,
|
|
128
105
|
bookable,
|
|
129
106
|
isSelected,
|
|
130
107
|
timeSlot,
|
|
@@ -153,128 +130,26 @@ export function Info(props) {
|
|
|
153
130
|
export function Actions(props) {
|
|
154
131
|
const { selectTimeSlot, timeSlot, isSelected } = useTimeSlotContext();
|
|
155
132
|
const service = useService(TimeSlotListServiceDefinition);
|
|
156
|
-
const
|
|
133
|
+
const bookingService = useService(BookingServiceDefinition);
|
|
157
134
|
const bookable = timeSlot.bookable ?? false;
|
|
158
|
-
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
const hasMultipleOptions = locationCount > 1 || staffCount > 1;
|
|
164
|
-
const shouldShowClearPreferences = hasPreferenceSelected && hasMultipleOptions;
|
|
165
|
-
const clearPreferences = shouldShowClearPreferences
|
|
166
|
-
? service.actions.clearPreferences
|
|
135
|
+
const selectedStaffMemberId = bookingService.serviceSelections.get()[0]?.resources?.[0]?._id;
|
|
136
|
+
const staffFromSlot = timeSlot.availableResources[0].resources.map((r) => r._id);
|
|
137
|
+
const shouldShowClearStaffSelection = !!selectedStaffMemberId && staffFromSlot.length > 1;
|
|
138
|
+
const clearStaffSelection = shouldShowClearStaffSelection
|
|
139
|
+
? service.actions.clearStaffSelection
|
|
167
140
|
: undefined;
|
|
168
141
|
return props.children({
|
|
169
142
|
selectTimeSlot,
|
|
170
|
-
|
|
143
|
+
clearStaffSelection,
|
|
171
144
|
timeSlot,
|
|
172
145
|
bookable,
|
|
173
146
|
isSelected,
|
|
174
147
|
});
|
|
175
148
|
}
|
|
176
|
-
/**
|
|
177
|
-
* Core component that provides access to time slot locations via render props.
|
|
178
|
-
* Extracts locations from slot.staffByLocation and enriches with name from originalSlots.
|
|
179
|
-
* Each location includes isSelected and isSelectable based on current selection state.
|
|
180
|
-
*
|
|
181
|
-
* Returns null if there's only 1 location (nothing to choose from).
|
|
182
|
-
*
|
|
183
|
-
* @component
|
|
184
|
-
* @example
|
|
185
|
-
* ```tsx
|
|
186
|
-
* <CoreTimeSlot.Locations>
|
|
187
|
-
* {({ locations, locationsCount, selectLocation }) => (
|
|
188
|
-
* <GenericList.Root items={locations}>
|
|
189
|
-
* {children}
|
|
190
|
-
* </GenericList.Root>
|
|
191
|
-
* )}
|
|
192
|
-
* </CoreTimeSlot.Locations>
|
|
193
|
-
* ```
|
|
194
|
-
*/
|
|
195
|
-
export function Locations(props) {
|
|
196
|
-
const { timeSlot } = useTimeSlotContext();
|
|
197
|
-
const service = useService(TimeSlotListServiceDefinition);
|
|
198
|
-
const selection = service.selection.get();
|
|
199
|
-
const selectedLocationId = selection?.locationId ?? null;
|
|
200
|
-
const selectedStaffMemberId = selection?.staffMemberId ?? null;
|
|
201
|
-
const isAnyStaffMemberSelected = selectedStaffMemberId === ANY_STAFF_MEMBER_ID;
|
|
202
|
-
// Build locations array from staffByLocation (names already included)
|
|
203
|
-
const locations = timeSlot.staffByLocation.map(({ location, staffMembers }) => {
|
|
204
|
-
// Check if this location is selectable based on selected staff
|
|
205
|
-
// If no staff selected, all locations are selectable
|
|
206
|
-
// If staff selected, only locations where that staff works are selectable
|
|
207
|
-
const isSelectable = !isAnyStaffMemberSelected && selectedStaffMemberId
|
|
208
|
-
? staffMembers.some((s) => s.id === selectedStaffMemberId)
|
|
209
|
-
: true;
|
|
210
|
-
return {
|
|
211
|
-
id: location.id,
|
|
212
|
-
name: location.name,
|
|
213
|
-
isSelected: selectedLocationId === location.id,
|
|
214
|
-
isSelectable,
|
|
215
|
-
};
|
|
216
|
-
});
|
|
217
|
-
// Return null if only 1 location - nothing to choose from
|
|
218
|
-
if (locations.length <= 1) {
|
|
219
|
-
return null;
|
|
220
|
-
}
|
|
221
|
-
return props.children({
|
|
222
|
-
locations,
|
|
223
|
-
selectLocation: service.actions.selectLocation,
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* Core component that provides access to location info via render props.
|
|
228
|
-
* Must be used within LocationProvider.
|
|
229
|
-
*
|
|
230
|
-
* @component
|
|
231
|
-
* @example
|
|
232
|
-
* ```tsx
|
|
233
|
-
* <LocationInfo>
|
|
234
|
-
* {({ name, isSelected, isSelectable }) => (
|
|
235
|
-
* <span>{name}</span>
|
|
236
|
-
* )}
|
|
237
|
-
* </LocationInfo>
|
|
238
|
-
* ```
|
|
239
|
-
*/
|
|
240
|
-
export function LocationInfo(props) {
|
|
241
|
-
const { location } = useLocationContext();
|
|
242
|
-
return props.children({
|
|
243
|
-
name: location.name,
|
|
244
|
-
isSelected: location.isSelected,
|
|
245
|
-
isSelectable: location.isSelectable,
|
|
246
|
-
location,
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* Core component that provides location actions via render props.
|
|
251
|
-
* Must be used within LocationProvider.
|
|
252
|
-
*
|
|
253
|
-
* @component
|
|
254
|
-
* @example
|
|
255
|
-
* ```tsx
|
|
256
|
-
* <LocationActions>
|
|
257
|
-
* {({ selectLocation, isSelected, isSelectable }) => (
|
|
258
|
-
* <button onClick={selectLocation} disabled={!isSelectable}>
|
|
259
|
-
* {isSelected ? 'Selected' : 'Select'}
|
|
260
|
-
* </button>
|
|
261
|
-
* )}
|
|
262
|
-
* </LocationActions>
|
|
263
|
-
* ```
|
|
264
|
-
*/
|
|
265
|
-
export function LocationActions(props) {
|
|
266
|
-
const { location, selectLocation } = useLocationContext();
|
|
267
|
-
return props.children({
|
|
268
|
-
selectLocation,
|
|
269
|
-
isSelected: location.isSelected,
|
|
270
|
-
isSelectable: location.isSelectable,
|
|
271
|
-
location,
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
149
|
/**
|
|
275
150
|
* Core component that provides access to time slot staff members via render props.
|
|
276
151
|
* Extracts unique staff members from slot.staffByLocation (names already included).
|
|
277
|
-
* Each staff member includes isSelected
|
|
152
|
+
* Each staff member includes isSelected based on current selection state.
|
|
278
153
|
*
|
|
279
154
|
* Returns null if there's only 1 staff member (nothing to choose from).
|
|
280
155
|
*
|
|
@@ -293,33 +168,25 @@ export function LocationActions(props) {
|
|
|
293
168
|
export function StaffMembers(props) {
|
|
294
169
|
const { timeSlot } = useTimeSlotContext();
|
|
295
170
|
const service = useService(TimeSlotListServiceDefinition);
|
|
296
|
-
const
|
|
297
|
-
const selectedStaffMemberId =
|
|
298
|
-
const
|
|
299
|
-
//
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
const
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
isSelected: selectedStaffMemberId === id,
|
|
308
|
-
isSelectable: !selectedLocationId ||
|
|
309
|
-
entries.some((e) => e.locationId === selectedLocationId),
|
|
171
|
+
const bookingService = useService(BookingServiceDefinition);
|
|
172
|
+
const selectedStaffMemberId = bookingService.serviceSelections.get()[0]?.resources?.[0]?._id;
|
|
173
|
+
const staffMembers = timeSlot.availableResources[0].resources;
|
|
174
|
+
// Return null if only 1 staff member - nothing to choose from
|
|
175
|
+
if (staffMembers.length <= 1) {
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
const staffMembersData = staffMembers.map((s) => ({
|
|
179
|
+
id: s._id,
|
|
180
|
+
name: s.name,
|
|
181
|
+
isSelected: selectedStaffMemberId === s._id,
|
|
310
182
|
}));
|
|
311
183
|
const anyStaffOption = {
|
|
312
184
|
id: ANY_STAFF_MEMBER_ID,
|
|
313
185
|
name: 'Any staff member',
|
|
314
186
|
isSelected: selectedStaffMemberId === ANY_STAFF_MEMBER_ID,
|
|
315
|
-
isSelectable: true,
|
|
316
187
|
};
|
|
317
|
-
// Return null if only 1 staff member - nothing to choose from
|
|
318
|
-
if (staffMembers.length <= 1) {
|
|
319
|
-
return null;
|
|
320
|
-
}
|
|
321
188
|
return props.children({
|
|
322
|
-
staffMembers: [anyStaffOption, ...
|
|
189
|
+
staffMembers: [anyStaffOption, ...staffMembersData],
|
|
323
190
|
selectStaffMember: service.actions.selectStaffMember,
|
|
324
191
|
});
|
|
325
192
|
}
|
|
@@ -331,7 +198,7 @@ export function StaffMembers(props) {
|
|
|
331
198
|
* @example
|
|
332
199
|
* ```tsx
|
|
333
200
|
* <StaffMemberInfo>
|
|
334
|
-
* {({ name, isSelected
|
|
201
|
+
* {({ name, isSelected }) => (
|
|
335
202
|
* <span>{name}</span>
|
|
336
203
|
* )}
|
|
337
204
|
* </StaffMemberInfo>
|
|
@@ -342,7 +209,6 @@ export function StaffMemberInfo(props) {
|
|
|
342
209
|
return props.children({
|
|
343
210
|
name: staffMember.name,
|
|
344
211
|
isSelected: staffMember.isSelected,
|
|
345
|
-
isSelectable: staffMember.isSelectable,
|
|
346
212
|
staffMember,
|
|
347
213
|
});
|
|
348
214
|
}
|
|
@@ -354,8 +220,8 @@ export function StaffMemberInfo(props) {
|
|
|
354
220
|
* @example
|
|
355
221
|
* ```tsx
|
|
356
222
|
* <StaffMemberActions>
|
|
357
|
-
* {({ selectStaffMember, isSelected
|
|
358
|
-
* <button onClick={selectStaffMember}
|
|
223
|
+
* {({ selectStaffMember, isSelected }) => (
|
|
224
|
+
* <button onClick={selectStaffMember}>
|
|
359
225
|
* {isSelected ? 'Selected' : 'Select'}
|
|
360
226
|
* </button>
|
|
361
227
|
* )}
|
|
@@ -367,7 +233,6 @@ export function StaffMemberActions(props) {
|
|
|
367
233
|
return props.children({
|
|
368
234
|
selectStaffMember,
|
|
369
235
|
isSelected: staffMember.isSelected,
|
|
370
|
-
isSelectable: staffMember.isSelectable,
|
|
371
236
|
staffMember,
|
|
372
237
|
});
|
|
373
238
|
}
|
|
@@ -3,13 +3,14 @@
|
|
|
3
3
|
* Provides low-level access to TimeSlotListService via render props
|
|
4
4
|
*/
|
|
5
5
|
import React from 'react';
|
|
6
|
-
import { type TimeSlotListServiceConfig
|
|
6
|
+
import { type TimeSlotListServiceConfig } from '../../../services/time-slot-list/index.js';
|
|
7
|
+
import type { TimeSlot } from '@wix/auto_sdk_bookings_availability-time-slots';
|
|
7
8
|
/**
|
|
8
9
|
* Props for Root component
|
|
9
10
|
*/
|
|
10
11
|
export interface RootProps {
|
|
11
12
|
children: React.ReactNode;
|
|
12
|
-
config
|
|
13
|
+
config: TimeSlotListServiceConfig;
|
|
13
14
|
}
|
|
14
15
|
/**
|
|
15
16
|
* Root component that provides TimeSlotListService context to its children.
|
|
@@ -15,7 +15,7 @@ import { BookingServiceDefinition } from '../../../services/booking/booking.js';
|
|
|
15
15
|
* ```
|
|
16
16
|
*/
|
|
17
17
|
export function Root(props) {
|
|
18
|
-
return (_jsx(WixServices, { servicesMap: createServicesMap().addService(TimeSlotListServiceDefinition, TimeSlotListService, props.config
|
|
18
|
+
return (_jsx(WixServices, { servicesMap: createServicesMap().addService(TimeSlotListServiceDefinition, TimeSlotListService, props.config), children: props.children }));
|
|
19
19
|
}
|
|
20
20
|
// ============================================================================
|
|
21
21
|
// Timezone Component
|