@wix/headless-bookings 0.0.37 → 0.0.39
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/react/core/time-slot-list/TimeSlot.d.ts +14 -22
- package/cjs/dist/react/core/time-slot-list/TimeSlot.js +30 -34
- package/cjs/dist/react/time-slot-list/TimeSlot.d.ts +24 -2
- package/cjs/dist/react/time-slot-list/TimeSlot.js +18 -2
- package/cjs/dist/react/time-slot-list/TimeSlotList.js +3 -5
- package/cjs/dist/services/index.d.ts +1 -1
- package/cjs/dist/services/index.js +1 -1
- package/cjs/dist/services/time-slot-list/index.d.ts +1 -0
- package/cjs/dist/services/time-slot-list/index.js +1 -0
- package/cjs/dist/services/time-slot-list/time-slot-list.js +7 -1
- package/cjs/dist/services/time-slot-list/time-slot.d.ts +35 -0
- package/cjs/dist/services/time-slot-list/time-slot.js +20 -0
- package/dist/react/core/time-slot-list/TimeSlot.d.ts +14 -22
- package/dist/react/core/time-slot-list/TimeSlot.js +30 -34
- package/dist/react/time-slot-list/TimeSlot.d.ts +24 -2
- package/dist/react/time-slot-list/TimeSlot.js +18 -2
- package/dist/react/time-slot-list/TimeSlotList.js +3 -5
- package/dist/services/index.d.ts +1 -1
- package/dist/services/index.js +1 -1
- package/dist/services/time-slot-list/index.d.ts +1 -0
- package/dist/services/time-slot-list/index.js +1 -0
- package/dist/services/time-slot-list/time-slot-list.js +7 -1
- package/dist/services/time-slot-list/time-slot.d.ts +35 -0
- package/dist/services/time-slot-list/time-slot.js +20 -0
- package/package.json +2 -2
|
@@ -7,34 +7,26 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import React from 'react';
|
|
9
9
|
import type { TimeSlot as TimeSlotType } from '@wix/auto_sdk_bookings_availability-time-slots';
|
|
10
|
+
import { type TimeSlotServiceConfig } from '../../../services/time-slot-list/time-slot.js';
|
|
10
11
|
/**
|
|
11
|
-
*
|
|
12
|
+
* Props for TimeSlot.Root component
|
|
12
13
|
*/
|
|
13
|
-
export interface
|
|
14
|
-
/** The current time slot data */
|
|
15
|
-
timeSlot: TimeSlotType;
|
|
16
|
-
/** Whether this time slot is currently selected */
|
|
17
|
-
isSelected: boolean;
|
|
18
|
-
/** Action to select this time slot */
|
|
19
|
-
selectTimeSlot: () => void;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Hook to access TimeSlot context
|
|
23
|
-
* @throws Error if used outside of TimeSlotProvider
|
|
24
|
-
*/
|
|
25
|
-
export declare function useTimeSlotContext(): TimeSlotContextValue;
|
|
26
|
-
/**
|
|
27
|
-
* Props for TimeSlotProvider
|
|
28
|
-
*/
|
|
29
|
-
export interface TimeSlotProviderProps {
|
|
14
|
+
export interface RootProps {
|
|
30
15
|
children: React.ReactNode;
|
|
31
|
-
|
|
16
|
+
config: TimeSlotServiceConfig;
|
|
32
17
|
}
|
|
33
18
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
19
|
+
* Root component that provides TimeSlot context.
|
|
20
|
+
*
|
|
21
|
+
* @component
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* <TimeSlot.Root config={{ timeSlot }}>
|
|
25
|
+
* {children}
|
|
26
|
+
* </TimeSlot.Root>
|
|
27
|
+
* ```
|
|
36
28
|
*/
|
|
37
|
-
export declare function
|
|
29
|
+
export declare function Root(props: RootProps): React.ReactNode;
|
|
38
30
|
/**
|
|
39
31
|
* Context value for StaffMember components
|
|
40
32
|
*/
|
|
@@ -7,41 +7,24 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
7
7
|
* which provides the TimeSlotProvider context.
|
|
8
8
|
*/
|
|
9
9
|
import React from 'react';
|
|
10
|
-
import { useService } from '@wix/services-manager-react';
|
|
10
|
+
import { useService, WixServices } from '@wix/services-manager-react';
|
|
11
|
+
import { createServicesMap } from '@wix/services-manager';
|
|
11
12
|
import { TimeSlotListServiceDefinition } from '../../../services/time-slot-list/time-slot-list.def.js';
|
|
12
13
|
import { ANY_STAFF_MEMBER_ID, BookingServiceDefinition, } from '../../../services/booking/booking.js';
|
|
13
|
-
|
|
14
|
+
import { TimeSlotServiceDefinition, TimeSlotService, } from '../../../services/time-slot-list/time-slot.js';
|
|
14
15
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Provider component used by TimeSlotRepeater to provide context.
|
|
27
|
-
* Not used directly by consumers - only by TimeSlotList.TimeSlotRepeater.
|
|
16
|
+
* Root component that provides TimeSlot context.
|
|
17
|
+
*
|
|
18
|
+
* @component
|
|
19
|
+
* @example
|
|
20
|
+
* ```tsx
|
|
21
|
+
* <TimeSlot.Root config={{ timeSlot }}>
|
|
22
|
+
* {children}
|
|
23
|
+
* </TimeSlot.Root>
|
|
24
|
+
* ```
|
|
28
25
|
*/
|
|
29
|
-
export function
|
|
30
|
-
|
|
31
|
-
const service = useService(TimeSlotListServiceDefinition);
|
|
32
|
-
const bookingService = useService(BookingServiceDefinition);
|
|
33
|
-
const selectedTimeSlot = bookingService.serviceSelections.get()[0]?.timeSlot;
|
|
34
|
-
const isSelected = selectedTimeSlot?.startDate === timeSlot.localStartDate &&
|
|
35
|
-
selectedTimeSlot?.location?._id === timeSlot.location?._id;
|
|
36
|
-
const selectTimeSlot = () => {
|
|
37
|
-
service.actions.selectSlot(timeSlot);
|
|
38
|
-
};
|
|
39
|
-
const contextValue = {
|
|
40
|
-
timeSlot,
|
|
41
|
-
isSelected,
|
|
42
|
-
selectTimeSlot,
|
|
43
|
-
};
|
|
44
|
-
return (_jsx(TimeSlotContext.Provider, { value: contextValue, children: children }));
|
|
26
|
+
export function Root(props) {
|
|
27
|
+
return (_jsx(WixServices, { servicesMap: createServicesMap().addService(TimeSlotServiceDefinition, TimeSlotService, props.config), children: props.children }));
|
|
45
28
|
}
|
|
46
29
|
const StaffMemberContext = React.createContext(null);
|
|
47
30
|
/**
|
|
@@ -89,7 +72,12 @@ export function StaffMemberProvider(props) {
|
|
|
89
72
|
* ```
|
|
90
73
|
*/
|
|
91
74
|
export function Info(props) {
|
|
92
|
-
const
|
|
75
|
+
const timeSlotService = useService(TimeSlotServiceDefinition);
|
|
76
|
+
const timeSlot = timeSlotService.timeSlotSignal.get();
|
|
77
|
+
const bookingService = useService(BookingServiceDefinition);
|
|
78
|
+
const selectedTimeSlot = bookingService.serviceSelections.get()[0]?.timeSlot;
|
|
79
|
+
const isSelected = selectedTimeSlot?.startDate === timeSlot.localStartDate &&
|
|
80
|
+
selectedTimeSlot?.location?._id === timeSlot.location?._id;
|
|
93
81
|
const startDate = new Date(timeSlot.localStartDate);
|
|
94
82
|
const endDate = new Date(timeSlot.localEndDate);
|
|
95
83
|
const locationName = timeSlot.location?.name ?? '';
|
|
@@ -127,9 +115,16 @@ export function Info(props) {
|
|
|
127
115
|
* ```
|
|
128
116
|
*/
|
|
129
117
|
export function Actions(props) {
|
|
130
|
-
const
|
|
118
|
+
const timeSlotService = useService(TimeSlotServiceDefinition);
|
|
119
|
+
const timeSlot = timeSlotService.timeSlotSignal.get();
|
|
131
120
|
const service = useService(TimeSlotListServiceDefinition);
|
|
132
121
|
const bookingService = useService(BookingServiceDefinition);
|
|
122
|
+
const selectedTimeSlot = bookingService.serviceSelections.get()[0]?.timeSlot;
|
|
123
|
+
const isSelected = selectedTimeSlot?.startDate === timeSlot.localStartDate &&
|
|
124
|
+
selectedTimeSlot?.location?._id === timeSlot.location?._id;
|
|
125
|
+
const selectTimeSlot = () => {
|
|
126
|
+
service.actions.selectSlot(timeSlot);
|
|
127
|
+
};
|
|
133
128
|
const bookable = timeSlot.bookable ?? false;
|
|
134
129
|
const selectedStaffMemberId = bookingService.serviceSelections.get()[0]?.timeSlot?.resources?.[0]?._id;
|
|
135
130
|
const staffFromSlot = timeSlot.availableResources[0].resources.map((r) => r._id);
|
|
@@ -165,7 +160,8 @@ export function Actions(props) {
|
|
|
165
160
|
* ```
|
|
166
161
|
*/
|
|
167
162
|
export function StaffMembers(props) {
|
|
168
|
-
const
|
|
163
|
+
const timeSlotService = useService(TimeSlotServiceDefinition);
|
|
164
|
+
const timeSlot = timeSlotService.timeSlotSignal.get();
|
|
169
165
|
const service = useService(TimeSlotListServiceDefinition);
|
|
170
166
|
const bookingService = useService(BookingServiceDefinition);
|
|
171
167
|
const selectedStaffMemberId = bookingService.serviceSelections.get()[0]?.timeSlot?.resources?.[0]?._id;
|
|
@@ -7,9 +7,31 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import React from 'react';
|
|
9
9
|
import { AsChildChildren } from '@wix/headless-utils/react';
|
|
10
|
-
|
|
11
|
-
export type { TimeSlotProviderProps } from '../core/time-slot-list/TimeSlot.js';
|
|
10
|
+
import type { TimeSlot as TimeSlotType } from '@wix/auto_sdk_bookings_availability-time-slots';
|
|
12
11
|
export type { StaffMemberData } from '../core/time-slot-list/TimeSlot.js';
|
|
12
|
+
/**
|
|
13
|
+
* Props for TimeSlot.Root component
|
|
14
|
+
*/
|
|
15
|
+
export interface RootProps {
|
|
16
|
+
children?: React.ReactNode;
|
|
17
|
+
timeSlot: TimeSlotType;
|
|
18
|
+
asChild?: boolean;
|
|
19
|
+
className?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Root component that provides time slot context.
|
|
23
|
+
*
|
|
24
|
+
* @order 1
|
|
25
|
+
* @component
|
|
26
|
+
* @example
|
|
27
|
+
* ```tsx
|
|
28
|
+
* <TimeSlot.Root timeSlot={timeSlot}>
|
|
29
|
+
* <TimeSlot.StartDate />
|
|
30
|
+
* <TimeSlot.Duration />
|
|
31
|
+
* </TimeSlot.Root>
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare const Root: React.ForwardRefExoticComponent<RootProps & React.RefAttributes<HTMLElement>>;
|
|
13
35
|
/**
|
|
14
36
|
* Props for TimeSlot.StartDate component
|
|
15
37
|
*/
|
|
@@ -10,8 +10,24 @@ import React from 'react';
|
|
|
10
10
|
import { GenericList } from '@wix/headless-components/react';
|
|
11
11
|
import { AsChildSlot } from '@wix/headless-utils/react';
|
|
12
12
|
import * as CoreTimeSlot from '../core/time-slot-list/TimeSlot.js';
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Root component that provides time slot context.
|
|
15
|
+
*
|
|
16
|
+
* @order 1
|
|
17
|
+
* @component
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* <TimeSlot.Root timeSlot={timeSlot}>
|
|
21
|
+
* <TimeSlot.StartDate />
|
|
22
|
+
* <TimeSlot.Duration />
|
|
23
|
+
* </TimeSlot.Root>
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export const Root = React.forwardRef((props, ref) => {
|
|
27
|
+
const { children, timeSlot, asChild, className, ...attrs } = props;
|
|
28
|
+
return (_jsx(CoreTimeSlot.Root, { config: { timeSlot }, children: _jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, customElement: children, ...attrs, children: children }) }));
|
|
29
|
+
});
|
|
30
|
+
Root.displayName = 'TimeSlot.Root';
|
|
15
31
|
// ============================================================================
|
|
16
32
|
// TestIds
|
|
17
33
|
// ============================================================================
|
|
@@ -7,8 +7,8 @@ import React from 'react';
|
|
|
7
7
|
import { GenericList } from '@wix/headless-components/react';
|
|
8
8
|
import { AsChildSlot } from '@wix/headless-utils/react';
|
|
9
9
|
import * as CoreTimeSlotList from '../core/time-slot-list/TimeSlotList.js';
|
|
10
|
-
import
|
|
11
|
-
import { StartDate as TimeSlotStartDate, EndDate as TimeSlotEndDate, Duration, Actions as TimeSlotActions, Location, StaffMembers, StaffMemberRepeater, StaffMember, } from './TimeSlot.js';
|
|
10
|
+
import * as CoreTimeSlot from '../core/time-slot-list/TimeSlot.js';
|
|
11
|
+
import { StartDate as TimeSlotStartDate, EndDate as TimeSlotEndDate, Duration, Actions as TimeSlotActions, Location, StaffMembers, StaffMemberRepeater, StaffMember, Root as TimeSlotRoot, } from './TimeSlot.js';
|
|
12
12
|
// ============================================================================
|
|
13
13
|
// Utilities
|
|
14
14
|
// ============================================================================
|
|
@@ -122,9 +122,7 @@ TimeSlots.displayName = 'TimeSlotList.TimeSlots';
|
|
|
122
122
|
* Supports both ReactNode and function children patterns.
|
|
123
123
|
*/
|
|
124
124
|
const TimeSlotItemWrapper = ({ timeSlot, children, }) => {
|
|
125
|
-
return (_jsx(
|
|
126
|
-
return (_jsx("div", { "data-testid": TestIds.timeSlotListTimeSlot, "data-bookable": props.bookable, "data-selected": props.isSelected, children: typeof children === 'function' ? children(props) : children }));
|
|
127
|
-
} }) }));
|
|
125
|
+
return (_jsx(TimeSlotRoot, { timeSlot: timeSlot, children: _jsx(CoreTimeSlot.Info, { children: (props) => (_jsx("div", { "data-testid": TestIds.timeSlotListTimeSlot, "data-bookable": props.bookable, "data-selected": props.isSelected, children: typeof children === 'function' ? children(props) : children })) }) }));
|
|
128
126
|
};
|
|
129
127
|
/**
|
|
130
128
|
* Repeater component that renders each time slot.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export { ServiceService, ServiceServiceDefinition, type ServiceServiceAPI, type ServiceServiceConfig, type ServiceActions, type ServicePaymentData, loadServiceServiceInitialData, type SuccessServiceServiceConfigResult, type NotFoundServiceServiceConfigResult, } from './service/service.js';
|
|
6
6
|
export { BookingService, BookingServiceDefinition, type BookingServiceConfig, type BookingServiceActions, type ServiceSelection, type ServiceSelectionTimeSlot, } from './booking/booking.js';
|
|
7
|
-
export { TimeSlotListService, TimeSlotListServiceDefinition, ViewMode, loadTimeSlotListConfig, type TimeSlotListServiceAPI, type TimeSlotListServiceActions, type TimeSlotListServiceConfig, type LoadTimeSlotListConfigOptions, type LoadTimeSlotListConfigResult, } from './time-slot-list/index.js';
|
|
7
|
+
export { TimeSlotListService, TimeSlotListServiceDefinition, TimeSlotService, TimeSlotServiceDefinition, ViewMode, loadTimeSlotListConfig, type TimeSlotListServiceAPI, type TimeSlotListServiceActions, type TimeSlotListServiceConfig, type TimeSlotServiceAPI, type TimeSlotServiceConfig, type LoadTimeSlotListConfigOptions, type LoadTimeSlotListConfigResult, } from './time-slot-list/index.js';
|
|
8
8
|
export { ServiceListService, ServiceListServiceDefinition, type ServiceListServiceAPI, type ServiceListServiceConfig, type ServiceListFilters, type ServiceListActions, type QueryOptions, loadServiceListServiceInitialData, type SuccessServiceListServiceConfigResult, type ErrorServiceListServiceConfigResult, } from './service-list/service-list.js';
|
|
9
9
|
export { executeBookAction, canBook, buildBookingRequest, buildCheckoutRequest, type CanBookParams, type BookResult, type BookingError, type BookActionParams, type BookChildProps, type BookProps, type BuildCheckoutParams, } from './booking/book-action/index.js';
|
|
10
10
|
export { BookingFormService, BookingFormServiceDefinition, type BookingFormServiceAPI, type BookingFormServiceConfig, type BookingFormServiceInternalAPI, type ValidationResult, } from './booking-form/booking-form.js';
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export { ServiceService, ServiceServiceDefinition, loadServiceServiceInitialData, } from './service/service.js';
|
|
6
6
|
export { BookingService, BookingServiceDefinition, } from './booking/booking.js';
|
|
7
|
-
export { TimeSlotListService, TimeSlotListServiceDefinition, ViewMode, loadTimeSlotListConfig, } from './time-slot-list/index.js';
|
|
7
|
+
export { TimeSlotListService, TimeSlotListServiceDefinition, TimeSlotService, TimeSlotServiceDefinition, ViewMode, loadTimeSlotListConfig, } from './time-slot-list/index.js';
|
|
8
8
|
export { ServiceListService, ServiceListServiceDefinition, loadServiceListServiceInitialData, } from './service-list/service-list.js';
|
|
9
9
|
export { executeBookAction, canBook, buildBookingRequest, buildCheckoutRequest, } from './booking/book-action/index.js';
|
|
10
10
|
export { BookingFormService, BookingFormServiceDefinition, } from './booking-form/booking-form.js';
|
|
@@ -4,3 +4,4 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export { TimeSlotListServiceDefinition, ViewMode, type DateRange, type TimeSlotListServiceAPI, type TimeSlotListServiceActions, type TimeSlotListServiceConfig, type TimeSlotsFilters, } from './time-slot-list.def.js';
|
|
6
6
|
export { TimeSlotListService, loadTimeSlotListConfig, type LoadTimeSlotListConfigOptions, type LoadTimeSlotListConfigResult, } from './time-slot-list.js';
|
|
7
|
+
export { TimeSlotService, TimeSlotServiceDefinition, type TimeSlotServiceAPI, type TimeSlotServiceConfig, } from './time-slot.js';
|
|
@@ -34,7 +34,6 @@ export const TimeSlotListService = implementService.withConfig()(TimeSlotListSer
|
|
|
34
34
|
end: config.endDate,
|
|
35
35
|
});
|
|
36
36
|
const cursorSignal = signalsService.signal(undefined);
|
|
37
|
-
// Helper functions using peek() - no subscriptions created
|
|
38
37
|
const getServices = () => {
|
|
39
38
|
const serviceSelections = bookingService.serviceSelections.peek();
|
|
40
39
|
return serviceSelections.length
|
|
@@ -195,12 +194,19 @@ export const TimeSlotListService = implementService.withConfig()(TimeSlotListSer
|
|
|
195
194
|
}
|
|
196
195
|
dateRangeSignal.set({ start: newStartDate, end: newEndDate });
|
|
197
196
|
};
|
|
197
|
+
const preSelectedStaffMemberId = signalsService.computed(() => {
|
|
198
|
+
const serviceSelections = bookingService.serviceSelections.peek();
|
|
199
|
+
return serviceSelections.length
|
|
200
|
+
? (serviceSelections[0]?.resources?.[0]?._id ?? undefined)
|
|
201
|
+
: undefined;
|
|
202
|
+
});
|
|
198
203
|
let isFirstRun = true;
|
|
199
204
|
signalsService.effect(() => {
|
|
200
205
|
// Dependencies - trigger refetch when these change
|
|
201
206
|
dateRangeSignal.get();
|
|
202
207
|
bookingService.timezone.get();
|
|
203
208
|
bookingService.location.get();
|
|
209
|
+
preSelectedStaffMemberId.get();
|
|
204
210
|
if (isFirstRun) {
|
|
205
211
|
isFirstRun = false;
|
|
206
212
|
if (config.timeSlots) {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TimeSlot Service
|
|
3
|
+
* Manages individual time slot data
|
|
4
|
+
*/
|
|
5
|
+
import { type Signal } from '@wix/services-definitions/core-services/signals';
|
|
6
|
+
import type { TimeSlot } from '@wix/auto_sdk_bookings_availability-time-slots';
|
|
7
|
+
/**
|
|
8
|
+
* API interface for the TimeSlot service
|
|
9
|
+
*/
|
|
10
|
+
export interface TimeSlotServiceAPI {
|
|
11
|
+
/** Reactive signal containing the time slot data */
|
|
12
|
+
timeSlotSignal: Signal<TimeSlot>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Service definition for TimeSlot
|
|
16
|
+
*/
|
|
17
|
+
export declare const TimeSlotServiceDefinition: string & {
|
|
18
|
+
__api: TimeSlotServiceAPI;
|
|
19
|
+
__config: {};
|
|
20
|
+
isServiceDefinition?: boolean;
|
|
21
|
+
} & TimeSlotServiceAPI;
|
|
22
|
+
/**
|
|
23
|
+
* Configuration for TimeSlotService
|
|
24
|
+
*/
|
|
25
|
+
export interface TimeSlotServiceConfig {
|
|
26
|
+
timeSlot: TimeSlot;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Implementation of TimeSlotService
|
|
30
|
+
*/
|
|
31
|
+
export declare const TimeSlotService: import("@wix/services-definitions").ServiceFactory<string & {
|
|
32
|
+
__api: TimeSlotServiceAPI;
|
|
33
|
+
__config: {};
|
|
34
|
+
isServiceDefinition?: boolean;
|
|
35
|
+
} & TimeSlotServiceAPI, TimeSlotServiceConfig>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TimeSlot Service
|
|
3
|
+
* Manages individual time slot data
|
|
4
|
+
*/
|
|
5
|
+
import { defineService, implementService } from '@wix/services-definitions';
|
|
6
|
+
import { SignalsServiceDefinition, } from '@wix/services-definitions/core-services/signals';
|
|
7
|
+
/**
|
|
8
|
+
* Service definition for TimeSlot
|
|
9
|
+
*/
|
|
10
|
+
export const TimeSlotServiceDefinition = defineService('time-slot');
|
|
11
|
+
/**
|
|
12
|
+
* Implementation of TimeSlotService
|
|
13
|
+
*/
|
|
14
|
+
export const TimeSlotService = implementService.withConfig()(TimeSlotServiceDefinition, ({ getService, config }) => {
|
|
15
|
+
const signalsService = getService(SignalsServiceDefinition);
|
|
16
|
+
const timeSlotSignal = signalsService.signal(config.timeSlot);
|
|
17
|
+
return {
|
|
18
|
+
timeSlotSignal,
|
|
19
|
+
};
|
|
20
|
+
});
|
|
@@ -7,34 +7,26 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import React from 'react';
|
|
9
9
|
import type { TimeSlot as TimeSlotType } from '@wix/auto_sdk_bookings_availability-time-slots';
|
|
10
|
+
import { type TimeSlotServiceConfig } from '../../../services/time-slot-list/time-slot.js';
|
|
10
11
|
/**
|
|
11
|
-
*
|
|
12
|
+
* Props for TimeSlot.Root component
|
|
12
13
|
*/
|
|
13
|
-
export interface
|
|
14
|
-
/** The current time slot data */
|
|
15
|
-
timeSlot: TimeSlotType;
|
|
16
|
-
/** Whether this time slot is currently selected */
|
|
17
|
-
isSelected: boolean;
|
|
18
|
-
/** Action to select this time slot */
|
|
19
|
-
selectTimeSlot: () => void;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Hook to access TimeSlot context
|
|
23
|
-
* @throws Error if used outside of TimeSlotProvider
|
|
24
|
-
*/
|
|
25
|
-
export declare function useTimeSlotContext(): TimeSlotContextValue;
|
|
26
|
-
/**
|
|
27
|
-
* Props for TimeSlotProvider
|
|
28
|
-
*/
|
|
29
|
-
export interface TimeSlotProviderProps {
|
|
14
|
+
export interface RootProps {
|
|
30
15
|
children: React.ReactNode;
|
|
31
|
-
|
|
16
|
+
config: TimeSlotServiceConfig;
|
|
32
17
|
}
|
|
33
18
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
19
|
+
* Root component that provides TimeSlot context.
|
|
20
|
+
*
|
|
21
|
+
* @component
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* <TimeSlot.Root config={{ timeSlot }}>
|
|
25
|
+
* {children}
|
|
26
|
+
* </TimeSlot.Root>
|
|
27
|
+
* ```
|
|
36
28
|
*/
|
|
37
|
-
export declare function
|
|
29
|
+
export declare function Root(props: RootProps): React.ReactNode;
|
|
38
30
|
/**
|
|
39
31
|
* Context value for StaffMember components
|
|
40
32
|
*/
|
|
@@ -7,41 +7,24 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
7
7
|
* which provides the TimeSlotProvider context.
|
|
8
8
|
*/
|
|
9
9
|
import React from 'react';
|
|
10
|
-
import { useService } from '@wix/services-manager-react';
|
|
10
|
+
import { useService, WixServices } from '@wix/services-manager-react';
|
|
11
|
+
import { createServicesMap } from '@wix/services-manager';
|
|
11
12
|
import { TimeSlotListServiceDefinition } from '../../../services/time-slot-list/time-slot-list.def.js';
|
|
12
13
|
import { ANY_STAFF_MEMBER_ID, BookingServiceDefinition, } from '../../../services/booking/booking.js';
|
|
13
|
-
|
|
14
|
+
import { TimeSlotServiceDefinition, TimeSlotService, } from '../../../services/time-slot-list/time-slot.js';
|
|
14
15
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Provider component used by TimeSlotRepeater to provide context.
|
|
27
|
-
* Not used directly by consumers - only by TimeSlotList.TimeSlotRepeater.
|
|
16
|
+
* Root component that provides TimeSlot context.
|
|
17
|
+
*
|
|
18
|
+
* @component
|
|
19
|
+
* @example
|
|
20
|
+
* ```tsx
|
|
21
|
+
* <TimeSlot.Root config={{ timeSlot }}>
|
|
22
|
+
* {children}
|
|
23
|
+
* </TimeSlot.Root>
|
|
24
|
+
* ```
|
|
28
25
|
*/
|
|
29
|
-
export function
|
|
30
|
-
|
|
31
|
-
const service = useService(TimeSlotListServiceDefinition);
|
|
32
|
-
const bookingService = useService(BookingServiceDefinition);
|
|
33
|
-
const selectedTimeSlot = bookingService.serviceSelections.get()[0]?.timeSlot;
|
|
34
|
-
const isSelected = selectedTimeSlot?.startDate === timeSlot.localStartDate &&
|
|
35
|
-
selectedTimeSlot?.location?._id === timeSlot.location?._id;
|
|
36
|
-
const selectTimeSlot = () => {
|
|
37
|
-
service.actions.selectSlot(timeSlot);
|
|
38
|
-
};
|
|
39
|
-
const contextValue = {
|
|
40
|
-
timeSlot,
|
|
41
|
-
isSelected,
|
|
42
|
-
selectTimeSlot,
|
|
43
|
-
};
|
|
44
|
-
return (_jsx(TimeSlotContext.Provider, { value: contextValue, children: children }));
|
|
26
|
+
export function Root(props) {
|
|
27
|
+
return (_jsx(WixServices, { servicesMap: createServicesMap().addService(TimeSlotServiceDefinition, TimeSlotService, props.config), children: props.children }));
|
|
45
28
|
}
|
|
46
29
|
const StaffMemberContext = React.createContext(null);
|
|
47
30
|
/**
|
|
@@ -89,7 +72,12 @@ export function StaffMemberProvider(props) {
|
|
|
89
72
|
* ```
|
|
90
73
|
*/
|
|
91
74
|
export function Info(props) {
|
|
92
|
-
const
|
|
75
|
+
const timeSlotService = useService(TimeSlotServiceDefinition);
|
|
76
|
+
const timeSlot = timeSlotService.timeSlotSignal.get();
|
|
77
|
+
const bookingService = useService(BookingServiceDefinition);
|
|
78
|
+
const selectedTimeSlot = bookingService.serviceSelections.get()[0]?.timeSlot;
|
|
79
|
+
const isSelected = selectedTimeSlot?.startDate === timeSlot.localStartDate &&
|
|
80
|
+
selectedTimeSlot?.location?._id === timeSlot.location?._id;
|
|
93
81
|
const startDate = new Date(timeSlot.localStartDate);
|
|
94
82
|
const endDate = new Date(timeSlot.localEndDate);
|
|
95
83
|
const locationName = timeSlot.location?.name ?? '';
|
|
@@ -127,9 +115,16 @@ export function Info(props) {
|
|
|
127
115
|
* ```
|
|
128
116
|
*/
|
|
129
117
|
export function Actions(props) {
|
|
130
|
-
const
|
|
118
|
+
const timeSlotService = useService(TimeSlotServiceDefinition);
|
|
119
|
+
const timeSlot = timeSlotService.timeSlotSignal.get();
|
|
131
120
|
const service = useService(TimeSlotListServiceDefinition);
|
|
132
121
|
const bookingService = useService(BookingServiceDefinition);
|
|
122
|
+
const selectedTimeSlot = bookingService.serviceSelections.get()[0]?.timeSlot;
|
|
123
|
+
const isSelected = selectedTimeSlot?.startDate === timeSlot.localStartDate &&
|
|
124
|
+
selectedTimeSlot?.location?._id === timeSlot.location?._id;
|
|
125
|
+
const selectTimeSlot = () => {
|
|
126
|
+
service.actions.selectSlot(timeSlot);
|
|
127
|
+
};
|
|
133
128
|
const bookable = timeSlot.bookable ?? false;
|
|
134
129
|
const selectedStaffMemberId = bookingService.serviceSelections.get()[0]?.timeSlot?.resources?.[0]?._id;
|
|
135
130
|
const staffFromSlot = timeSlot.availableResources[0].resources.map((r) => r._id);
|
|
@@ -165,7 +160,8 @@ export function Actions(props) {
|
|
|
165
160
|
* ```
|
|
166
161
|
*/
|
|
167
162
|
export function StaffMembers(props) {
|
|
168
|
-
const
|
|
163
|
+
const timeSlotService = useService(TimeSlotServiceDefinition);
|
|
164
|
+
const timeSlot = timeSlotService.timeSlotSignal.get();
|
|
169
165
|
const service = useService(TimeSlotListServiceDefinition);
|
|
170
166
|
const bookingService = useService(BookingServiceDefinition);
|
|
171
167
|
const selectedStaffMemberId = bookingService.serviceSelections.get()[0]?.timeSlot?.resources?.[0]?._id;
|
|
@@ -7,9 +7,31 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import React from 'react';
|
|
9
9
|
import { AsChildChildren } from '@wix/headless-utils/react';
|
|
10
|
-
|
|
11
|
-
export type { TimeSlotProviderProps } from '../core/time-slot-list/TimeSlot.js';
|
|
10
|
+
import type { TimeSlot as TimeSlotType } from '@wix/auto_sdk_bookings_availability-time-slots';
|
|
12
11
|
export type { StaffMemberData } from '../core/time-slot-list/TimeSlot.js';
|
|
12
|
+
/**
|
|
13
|
+
* Props for TimeSlot.Root component
|
|
14
|
+
*/
|
|
15
|
+
export interface RootProps {
|
|
16
|
+
children?: React.ReactNode;
|
|
17
|
+
timeSlot: TimeSlotType;
|
|
18
|
+
asChild?: boolean;
|
|
19
|
+
className?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Root component that provides time slot context.
|
|
23
|
+
*
|
|
24
|
+
* @order 1
|
|
25
|
+
* @component
|
|
26
|
+
* @example
|
|
27
|
+
* ```tsx
|
|
28
|
+
* <TimeSlot.Root timeSlot={timeSlot}>
|
|
29
|
+
* <TimeSlot.StartDate />
|
|
30
|
+
* <TimeSlot.Duration />
|
|
31
|
+
* </TimeSlot.Root>
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare const Root: React.ForwardRefExoticComponent<RootProps & React.RefAttributes<HTMLElement>>;
|
|
13
35
|
/**
|
|
14
36
|
* Props for TimeSlot.StartDate component
|
|
15
37
|
*/
|
|
@@ -10,8 +10,24 @@ import React from 'react';
|
|
|
10
10
|
import { GenericList } from '@wix/headless-components/react';
|
|
11
11
|
import { AsChildSlot } from '@wix/headless-utils/react';
|
|
12
12
|
import * as CoreTimeSlot from '../core/time-slot-list/TimeSlot.js';
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Root component that provides time slot context.
|
|
15
|
+
*
|
|
16
|
+
* @order 1
|
|
17
|
+
* @component
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* <TimeSlot.Root timeSlot={timeSlot}>
|
|
21
|
+
* <TimeSlot.StartDate />
|
|
22
|
+
* <TimeSlot.Duration />
|
|
23
|
+
* </TimeSlot.Root>
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export const Root = React.forwardRef((props, ref) => {
|
|
27
|
+
const { children, timeSlot, asChild, className, ...attrs } = props;
|
|
28
|
+
return (_jsx(CoreTimeSlot.Root, { config: { timeSlot }, children: _jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, customElement: children, ...attrs, children: children }) }));
|
|
29
|
+
});
|
|
30
|
+
Root.displayName = 'TimeSlot.Root';
|
|
15
31
|
// ============================================================================
|
|
16
32
|
// TestIds
|
|
17
33
|
// ============================================================================
|
|
@@ -7,8 +7,8 @@ import React from 'react';
|
|
|
7
7
|
import { GenericList } from '@wix/headless-components/react';
|
|
8
8
|
import { AsChildSlot } from '@wix/headless-utils/react';
|
|
9
9
|
import * as CoreTimeSlotList from '../core/time-slot-list/TimeSlotList.js';
|
|
10
|
-
import
|
|
11
|
-
import { StartDate as TimeSlotStartDate, EndDate as TimeSlotEndDate, Duration, Actions as TimeSlotActions, Location, StaffMembers, StaffMemberRepeater, StaffMember, } from './TimeSlot.js';
|
|
10
|
+
import * as CoreTimeSlot from '../core/time-slot-list/TimeSlot.js';
|
|
11
|
+
import { StartDate as TimeSlotStartDate, EndDate as TimeSlotEndDate, Duration, Actions as TimeSlotActions, Location, StaffMembers, StaffMemberRepeater, StaffMember, Root as TimeSlotRoot, } from './TimeSlot.js';
|
|
12
12
|
// ============================================================================
|
|
13
13
|
// Utilities
|
|
14
14
|
// ============================================================================
|
|
@@ -122,9 +122,7 @@ TimeSlots.displayName = 'TimeSlotList.TimeSlots';
|
|
|
122
122
|
* Supports both ReactNode and function children patterns.
|
|
123
123
|
*/
|
|
124
124
|
const TimeSlotItemWrapper = ({ timeSlot, children, }) => {
|
|
125
|
-
return (_jsx(
|
|
126
|
-
return (_jsx("div", { "data-testid": TestIds.timeSlotListTimeSlot, "data-bookable": props.bookable, "data-selected": props.isSelected, children: typeof children === 'function' ? children(props) : children }));
|
|
127
|
-
} }) }));
|
|
125
|
+
return (_jsx(TimeSlotRoot, { timeSlot: timeSlot, children: _jsx(CoreTimeSlot.Info, { children: (props) => (_jsx("div", { "data-testid": TestIds.timeSlotListTimeSlot, "data-bookable": props.bookable, "data-selected": props.isSelected, children: typeof children === 'function' ? children(props) : children })) }) }));
|
|
128
126
|
};
|
|
129
127
|
/**
|
|
130
128
|
* Repeater component that renders each time slot.
|
package/dist/services/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export { ServiceService, ServiceServiceDefinition, type ServiceServiceAPI, type ServiceServiceConfig, type ServiceActions, type ServicePaymentData, loadServiceServiceInitialData, type SuccessServiceServiceConfigResult, type NotFoundServiceServiceConfigResult, } from './service/service.js';
|
|
6
6
|
export { BookingService, BookingServiceDefinition, type BookingServiceConfig, type BookingServiceActions, type ServiceSelection, type ServiceSelectionTimeSlot, } from './booking/booking.js';
|
|
7
|
-
export { TimeSlotListService, TimeSlotListServiceDefinition, ViewMode, loadTimeSlotListConfig, type TimeSlotListServiceAPI, type TimeSlotListServiceActions, type TimeSlotListServiceConfig, type LoadTimeSlotListConfigOptions, type LoadTimeSlotListConfigResult, } from './time-slot-list/index.js';
|
|
7
|
+
export { TimeSlotListService, TimeSlotListServiceDefinition, TimeSlotService, TimeSlotServiceDefinition, ViewMode, loadTimeSlotListConfig, type TimeSlotListServiceAPI, type TimeSlotListServiceActions, type TimeSlotListServiceConfig, type TimeSlotServiceAPI, type TimeSlotServiceConfig, type LoadTimeSlotListConfigOptions, type LoadTimeSlotListConfigResult, } from './time-slot-list/index.js';
|
|
8
8
|
export { ServiceListService, ServiceListServiceDefinition, type ServiceListServiceAPI, type ServiceListServiceConfig, type ServiceListFilters, type ServiceListActions, type QueryOptions, loadServiceListServiceInitialData, type SuccessServiceListServiceConfigResult, type ErrorServiceListServiceConfigResult, } from './service-list/service-list.js';
|
|
9
9
|
export { executeBookAction, canBook, buildBookingRequest, buildCheckoutRequest, type CanBookParams, type BookResult, type BookingError, type BookActionParams, type BookChildProps, type BookProps, type BuildCheckoutParams, } from './booking/book-action/index.js';
|
|
10
10
|
export { BookingFormService, BookingFormServiceDefinition, type BookingFormServiceAPI, type BookingFormServiceConfig, type BookingFormServiceInternalAPI, type ValidationResult, } from './booking-form/booking-form.js';
|
package/dist/services/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export { ServiceService, ServiceServiceDefinition, loadServiceServiceInitialData, } from './service/service.js';
|
|
6
6
|
export { BookingService, BookingServiceDefinition, } from './booking/booking.js';
|
|
7
|
-
export { TimeSlotListService, TimeSlotListServiceDefinition, ViewMode, loadTimeSlotListConfig, } from './time-slot-list/index.js';
|
|
7
|
+
export { TimeSlotListService, TimeSlotListServiceDefinition, TimeSlotService, TimeSlotServiceDefinition, ViewMode, loadTimeSlotListConfig, } from './time-slot-list/index.js';
|
|
8
8
|
export { ServiceListService, ServiceListServiceDefinition, loadServiceListServiceInitialData, } from './service-list/service-list.js';
|
|
9
9
|
export { executeBookAction, canBook, buildBookingRequest, buildCheckoutRequest, } from './booking/book-action/index.js';
|
|
10
10
|
export { BookingFormService, BookingFormServiceDefinition, } from './booking-form/booking-form.js';
|
|
@@ -4,3 +4,4 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export { TimeSlotListServiceDefinition, ViewMode, type DateRange, type TimeSlotListServiceAPI, type TimeSlotListServiceActions, type TimeSlotListServiceConfig, type TimeSlotsFilters, } from './time-slot-list.def.js';
|
|
6
6
|
export { TimeSlotListService, loadTimeSlotListConfig, type LoadTimeSlotListConfigOptions, type LoadTimeSlotListConfigResult, } from './time-slot-list.js';
|
|
7
|
+
export { TimeSlotService, TimeSlotServiceDefinition, type TimeSlotServiceAPI, type TimeSlotServiceConfig, } from './time-slot.js';
|
|
@@ -34,7 +34,6 @@ export const TimeSlotListService = implementService.withConfig()(TimeSlotListSer
|
|
|
34
34
|
end: config.endDate,
|
|
35
35
|
});
|
|
36
36
|
const cursorSignal = signalsService.signal(undefined);
|
|
37
|
-
// Helper functions using peek() - no subscriptions created
|
|
38
37
|
const getServices = () => {
|
|
39
38
|
const serviceSelections = bookingService.serviceSelections.peek();
|
|
40
39
|
return serviceSelections.length
|
|
@@ -195,12 +194,19 @@ export const TimeSlotListService = implementService.withConfig()(TimeSlotListSer
|
|
|
195
194
|
}
|
|
196
195
|
dateRangeSignal.set({ start: newStartDate, end: newEndDate });
|
|
197
196
|
};
|
|
197
|
+
const preSelectedStaffMemberId = signalsService.computed(() => {
|
|
198
|
+
const serviceSelections = bookingService.serviceSelections.peek();
|
|
199
|
+
return serviceSelections.length
|
|
200
|
+
? (serviceSelections[0]?.resources?.[0]?._id ?? undefined)
|
|
201
|
+
: undefined;
|
|
202
|
+
});
|
|
198
203
|
let isFirstRun = true;
|
|
199
204
|
signalsService.effect(() => {
|
|
200
205
|
// Dependencies - trigger refetch when these change
|
|
201
206
|
dateRangeSignal.get();
|
|
202
207
|
bookingService.timezone.get();
|
|
203
208
|
bookingService.location.get();
|
|
209
|
+
preSelectedStaffMemberId.get();
|
|
204
210
|
if (isFirstRun) {
|
|
205
211
|
isFirstRun = false;
|
|
206
212
|
if (config.timeSlots) {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TimeSlot Service
|
|
3
|
+
* Manages individual time slot data
|
|
4
|
+
*/
|
|
5
|
+
import { type Signal } from '@wix/services-definitions/core-services/signals';
|
|
6
|
+
import type { TimeSlot } from '@wix/auto_sdk_bookings_availability-time-slots';
|
|
7
|
+
/**
|
|
8
|
+
* API interface for the TimeSlot service
|
|
9
|
+
*/
|
|
10
|
+
export interface TimeSlotServiceAPI {
|
|
11
|
+
/** Reactive signal containing the time slot data */
|
|
12
|
+
timeSlotSignal: Signal<TimeSlot>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Service definition for TimeSlot
|
|
16
|
+
*/
|
|
17
|
+
export declare const TimeSlotServiceDefinition: string & {
|
|
18
|
+
__api: TimeSlotServiceAPI;
|
|
19
|
+
__config: {};
|
|
20
|
+
isServiceDefinition?: boolean;
|
|
21
|
+
} & TimeSlotServiceAPI;
|
|
22
|
+
/**
|
|
23
|
+
* Configuration for TimeSlotService
|
|
24
|
+
*/
|
|
25
|
+
export interface TimeSlotServiceConfig {
|
|
26
|
+
timeSlot: TimeSlot;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Implementation of TimeSlotService
|
|
30
|
+
*/
|
|
31
|
+
export declare const TimeSlotService: import("@wix/services-definitions").ServiceFactory<string & {
|
|
32
|
+
__api: TimeSlotServiceAPI;
|
|
33
|
+
__config: {};
|
|
34
|
+
isServiceDefinition?: boolean;
|
|
35
|
+
} & TimeSlotServiceAPI, TimeSlotServiceConfig>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TimeSlot Service
|
|
3
|
+
* Manages individual time slot data
|
|
4
|
+
*/
|
|
5
|
+
import { defineService, implementService } from '@wix/services-definitions';
|
|
6
|
+
import { SignalsServiceDefinition, } from '@wix/services-definitions/core-services/signals';
|
|
7
|
+
/**
|
|
8
|
+
* Service definition for TimeSlot
|
|
9
|
+
*/
|
|
10
|
+
export const TimeSlotServiceDefinition = defineService('time-slot');
|
|
11
|
+
/**
|
|
12
|
+
* Implementation of TimeSlotService
|
|
13
|
+
*/
|
|
14
|
+
export const TimeSlotService = implementService.withConfig()(TimeSlotServiceDefinition, ({ getService, config }) => {
|
|
15
|
+
const signalsService = getService(SignalsServiceDefinition);
|
|
16
|
+
const timeSlotSignal = signalsService.signal(config.timeSlot);
|
|
17
|
+
return {
|
|
18
|
+
timeSlotSignal,
|
|
19
|
+
};
|
|
20
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/headless-bookings",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.39",
|
|
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": "
|
|
75
|
+
"falconPackageHash": "574164cdca2a1370455fe932ba12ff19571eba0e2ffa0134bd90afc0"
|
|
76
76
|
}
|