@wix/headless-bookings 0.0.53 → 0.0.54
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/__mocks__/booking.js +1 -0
- package/cjs/dist/__mocks__/services.d.ts +38 -1
- package/cjs/dist/__mocks__/services.js +82 -0
- package/cjs/dist/api/query-services/index.js +5 -1
- package/cjs/dist/react/core/staff-member/StaffMember.d.ts +104 -0
- package/cjs/dist/react/core/staff-member/StaffMember.js +143 -0
- package/cjs/dist/react/core/staff-member-list/StaffMemberList.d.ts +96 -0
- package/cjs/dist/react/core/staff-member-list/StaffMemberList.js +66 -0
- package/cjs/dist/react/index.d.ts +2 -0
- package/cjs/dist/react/index.js +2 -0
- package/cjs/dist/react/location/LocationList.d.ts +19 -0
- package/cjs/dist/react/location/LocationList.js +51 -0
- package/cjs/dist/react/service/Service.d.ts +16 -44
- package/cjs/dist/react/service/Service.js +23 -37
- package/cjs/dist/react/staff-member/StaffMember.d.ts +119 -0
- package/cjs/dist/react/staff-member/StaffMember.js +147 -0
- package/cjs/dist/react/staff-member/StaffMemberList.d.ts +123 -0
- package/cjs/dist/react/staff-member/StaffMemberList.js +168 -0
- package/cjs/dist/services/booking/booking.d.ts +2 -0
- package/cjs/dist/services/booking/booking.js +15 -0
- package/cjs/dist/services/index.d.ts +1 -0
- package/cjs/dist/services/index.js +1 -0
- package/cjs/dist/services/staff-member-list/staff-member-list.d.ts +85 -0
- package/cjs/dist/services/staff-member-list/staff-member-list.def.d.ts +46 -0
- package/cjs/dist/services/staff-member-list/staff-member-list.def.js +14 -0
- package/cjs/dist/services/staff-member-list/staff-member-list.js +105 -0
- package/dist/__mocks__/booking.js +1 -0
- package/dist/__mocks__/services.d.ts +38 -1
- package/dist/__mocks__/services.js +82 -0
- package/dist/api/query-services/index.js +5 -1
- package/dist/react/core/staff-member/StaffMember.d.ts +104 -0
- package/dist/react/core/staff-member/StaffMember.js +143 -0
- package/dist/react/core/staff-member-list/StaffMemberList.d.ts +96 -0
- package/dist/react/core/staff-member-list/StaffMemberList.js +66 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.js +2 -0
- package/dist/react/location/LocationList.d.ts +19 -0
- package/dist/react/location/LocationList.js +51 -0
- package/dist/react/service/Service.d.ts +16 -44
- package/dist/react/service/Service.js +23 -37
- package/dist/react/staff-member/StaffMember.d.ts +119 -0
- package/dist/react/staff-member/StaffMember.js +147 -0
- package/dist/react/staff-member/StaffMemberList.d.ts +123 -0
- package/dist/react/staff-member/StaffMemberList.js +168 -0
- package/dist/services/booking/booking.d.ts +2 -0
- package/dist/services/booking/booking.js +15 -0
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +1 -0
- package/dist/services/staff-member-list/staff-member-list.d.ts +85 -0
- package/dist/services/staff-member-list/staff-member-list.def.d.ts +46 -0
- package/dist/services/staff-member-list/staff-member-list.def.js +14 -0
- package/dist/services/staff-member-list/staff-member-list.js +105 -0
- package/package.json +2 -2
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* StaffMemberList - High-level component for displaying staff member lists
|
|
4
|
+
* Follows the pattern from LocationList.tsx
|
|
5
|
+
*
|
|
6
|
+
* @module React/StaffMemberList
|
|
7
|
+
*/
|
|
8
|
+
import React from 'react';
|
|
9
|
+
import { GenericList, } from '@wix/headless-components/react';
|
|
10
|
+
import { AsChildSlot } from '@wix/headless-utils/react';
|
|
11
|
+
import { useService } from '@wix/services-manager-react';
|
|
12
|
+
import { BookingServiceDefinition } from '../../services/booking/booking.js';
|
|
13
|
+
import * as CoreStaffMemberList from '../core/staff-member-list/StaffMemberList.js';
|
|
14
|
+
import * as StaffMember from './StaffMember.js';
|
|
15
|
+
/** Resource type ID for staff members */
|
|
16
|
+
const STAFF_MEMBER_RESOURCE_TYPE_ID = '1cd44cf8-756f-41c3-bd90-3e2ffcaf1155';
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// TestIds
|
|
19
|
+
// ============================================================================
|
|
20
|
+
var TestIds;
|
|
21
|
+
(function (TestIds) {
|
|
22
|
+
TestIds["staffMemberListRoot"] = "staff-member-list-root";
|
|
23
|
+
TestIds["staffMemberListStaffMembers"] = "staff-member-list-staff-members";
|
|
24
|
+
TestIds["staffMemberListStaffMember"] = "staff-member-list-staff-member";
|
|
25
|
+
TestIds["staffMemberListActionClear"] = "staff-member-list-action-clear";
|
|
26
|
+
})(TestIds || (TestIds = {}));
|
|
27
|
+
/**
|
|
28
|
+
* Root component that provides the StaffMemberList service context for rendering staff member lists.
|
|
29
|
+
*
|
|
30
|
+
* @component
|
|
31
|
+
* @example
|
|
32
|
+
* ```tsx
|
|
33
|
+
* import { StaffMemberList, StaffMember } from '@wix/bookings/react';
|
|
34
|
+
*
|
|
35
|
+
* function StaffMembersPage({ staffMemberListConfig }) {
|
|
36
|
+
* return (
|
|
37
|
+
* <StaffMemberList.Root staffMemberListConfig={staffMemberListConfig}>
|
|
38
|
+
* <StaffMemberList.StaffMembers emptyState={<div>No staff members available</div>}>
|
|
39
|
+
* <StaffMemberList.StaffMemberRepeater>
|
|
40
|
+
* <StaffMember.Name />
|
|
41
|
+
* </StaffMemberList.StaffMemberRepeater>
|
|
42
|
+
* </StaffMemberList.StaffMembers>
|
|
43
|
+
* </StaffMemberList.Root>
|
|
44
|
+
* );
|
|
45
|
+
* }
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export const Root = React.forwardRef((props, ref) => {
|
|
49
|
+
const { children, staffMemberListConfig, className, variant } = props;
|
|
50
|
+
const config = staffMemberListConfig || {
|
|
51
|
+
staffMembers: [],
|
|
52
|
+
};
|
|
53
|
+
return (_jsx(CoreStaffMemberList.Root, { staffMemberListServiceConfig: config, children: _jsx(RootContent, { className: className, ref: ref, variant: variant, children: children }) }));
|
|
54
|
+
});
|
|
55
|
+
Root.displayName = 'StaffMemberList.Root';
|
|
56
|
+
/**
|
|
57
|
+
* Internal component to handle the Root content with service access
|
|
58
|
+
*/
|
|
59
|
+
const RootContent = React.forwardRef((props, ref) => {
|
|
60
|
+
const { children, className, variant } = props;
|
|
61
|
+
return (_jsx(CoreStaffMemberList.StaffMembers, { children: ({ staffMembers, isLoading }) => {
|
|
62
|
+
// Add id to each staff member for GenericList (staffMemberId equals resource id)
|
|
63
|
+
const itemsWithId = staffMembers.map((staffMember, index) => ({
|
|
64
|
+
...staffMember,
|
|
65
|
+
id: staffMember.staffMemberId || String(index),
|
|
66
|
+
}));
|
|
67
|
+
return (_jsx(GenericList.Root, { items: itemsWithId, hasMore: false, isLoading: isLoading, className: className, ref: ref, "data-testid": TestIds.staffMemberListRoot, variant: variant, children: children }));
|
|
68
|
+
} }));
|
|
69
|
+
});
|
|
70
|
+
RootContent.displayName = 'StaffMemberList.RootContent';
|
|
71
|
+
/**
|
|
72
|
+
* Container for the staff members list with empty state support.
|
|
73
|
+
* Wraps GenericList.Items internally (no separate Items export).
|
|
74
|
+
*
|
|
75
|
+
* @component
|
|
76
|
+
* @example
|
|
77
|
+
* ```tsx
|
|
78
|
+
* <StaffMemberList.StaffMembers emptyState={<div>No staff members available</div>}>
|
|
79
|
+
* <StaffMemberList.StaffMemberRepeater>
|
|
80
|
+
* <StaffMember.Name />
|
|
81
|
+
* </StaffMemberList.StaffMemberRepeater>
|
|
82
|
+
* </StaffMemberList.StaffMembers>
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export const StaffMembers = React.forwardRef((props, ref) => {
|
|
86
|
+
const { children, ...otherProps } = props;
|
|
87
|
+
return (_jsx(GenericList.Items, { ref: ref, "data-testid": TestIds.staffMemberListStaffMembers, ...otherProps, children: children }));
|
|
88
|
+
});
|
|
89
|
+
StaffMembers.displayName = 'StaffMemberList.StaffMembers';
|
|
90
|
+
export const StaffMemberRepeater = React.forwardRef((props, ref) => {
|
|
91
|
+
const { children } = props;
|
|
92
|
+
// Custom itemWrapper that wraps each item in StaffMember.Root
|
|
93
|
+
const staffMemberItemWrapper = ({ item: staffMemberWithId, children: itemChildren, }) => {
|
|
94
|
+
return (_jsx(StaffMember.Root, { staffMember: staffMemberWithId, "data-testid": TestIds.staffMemberListStaffMember, "data-staff-member-id": staffMemberWithId.id, "data-item-id": staffMemberWithId.id, children: itemChildren }, staffMemberWithId.id));
|
|
95
|
+
};
|
|
96
|
+
return (_jsx(GenericList.Repeater, { ref: ref, itemWrapper: staffMemberItemWrapper, children: children }));
|
|
97
|
+
});
|
|
98
|
+
StaffMemberRepeater.displayName = 'StaffMemberList.StaffMemberRepeater';
|
|
99
|
+
/**
|
|
100
|
+
* Displays the total count of staff members.
|
|
101
|
+
*
|
|
102
|
+
* @component
|
|
103
|
+
* @example
|
|
104
|
+
* ```tsx
|
|
105
|
+
* <StaffMemberList.Totals />
|
|
106
|
+
*
|
|
107
|
+
* // With asChild
|
|
108
|
+
* <StaffMemberList.Totals asChild>
|
|
109
|
+
* {({ count }) => <span>{count} staff members available</span>}
|
|
110
|
+
* </StaffMemberList.Totals>
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
export const Totals = React.forwardRef((props, ref) => {
|
|
114
|
+
const { asChild, children, className, ...attrs } = props;
|
|
115
|
+
return (_jsx(CoreStaffMemberList.StaffMembers, { children: ({ staffMembers, hasStaffMembers }) => {
|
|
116
|
+
const count = staffMembers.length;
|
|
117
|
+
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, customElement: children, customElementProps: { count, hasStaffMembers }, ...attrs, children: _jsx("span", { children: count }) }));
|
|
118
|
+
} }));
|
|
119
|
+
});
|
|
120
|
+
Totals.displayName = 'StaffMemberList.Totals';
|
|
121
|
+
/**
|
|
122
|
+
* Button to clear the staff member selection.
|
|
123
|
+
* Clears the staff member resource from the BookingService.
|
|
124
|
+
*
|
|
125
|
+
* @component
|
|
126
|
+
* @example
|
|
127
|
+
* ```tsx
|
|
128
|
+
* // Default button with "Clear" label
|
|
129
|
+
* <StaffMemberList.Actions.Clear />
|
|
130
|
+
*
|
|
131
|
+
* // With custom label
|
|
132
|
+
* <StaffMemberList.Actions.Clear label="Clear selection" />
|
|
133
|
+
*
|
|
134
|
+
* // With asChild
|
|
135
|
+
* <StaffMemberList.Actions.Clear asChild>
|
|
136
|
+
* <button className="btn-secondary">Clear staff</button>
|
|
137
|
+
* </StaffMemberList.Actions.Clear>
|
|
138
|
+
*
|
|
139
|
+
* // Using render prop pattern
|
|
140
|
+
* <StaffMemberList.Actions.Clear>
|
|
141
|
+
* {({ onClick }) => <button onClick={onClick}>Clear selection</button>}
|
|
142
|
+
* </StaffMemberList.Actions.Clear>
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
const Clear = React.forwardRef((props, ref) => {
|
|
146
|
+
const { asChild, children, className, label = 'Clear', onClicked } = props;
|
|
147
|
+
let bookingService = null;
|
|
148
|
+
try {
|
|
149
|
+
bookingService = useService(BookingServiceDefinition);
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
// BookingService not available - likely no ServiceManagerProvider
|
|
153
|
+
}
|
|
154
|
+
const handleClick = () => {
|
|
155
|
+
bookingService?.actions.clearResourceById(STAFF_MEMBER_RESOURCE_TYPE_ID);
|
|
156
|
+
onClicked?.();
|
|
157
|
+
};
|
|
158
|
+
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.staffMemberListActionClear, customElement: children, customElementProps: {
|
|
159
|
+
onClick: handleClick,
|
|
160
|
+
}, children: _jsx("button", { type: "button", onClick: handleClick, children: label }) }));
|
|
161
|
+
});
|
|
162
|
+
Clear.displayName = 'StaffMemberList.Actions.Clear';
|
|
163
|
+
/**
|
|
164
|
+
* Actions namespace for staff member list-level actions
|
|
165
|
+
*/
|
|
166
|
+
export const Actions = {
|
|
167
|
+
Clear,
|
|
168
|
+
};
|
|
@@ -57,6 +57,8 @@ export interface BookingServiceActions {
|
|
|
57
57
|
setResourceById(resourceId: string, resource: Resource, instanceId?: string): void;
|
|
58
58
|
/** Gets a resource by ID from a service selection. If no instanceId provided, uses the first item. */
|
|
59
59
|
getResourceById(resourceId: string, instanceId?: string): Resource | undefined;
|
|
60
|
+
/** Clears a resource by ID from a service selection. If no instanceId provided, uses the first item. */
|
|
61
|
+
clearResourceById(resourceId: string, instanceId?: string): void;
|
|
60
62
|
setLocation(location: ServiceLocationType | null): void;
|
|
61
63
|
clearLocation(): void;
|
|
62
64
|
setTimezone(timezone: string): void;
|
|
@@ -149,6 +149,21 @@ export const BookingService = implementService.withConfig()(BookingServiceDefini
|
|
|
149
149
|
return undefined;
|
|
150
150
|
return targetItem.resources.find((r) => r._id === resourceId);
|
|
151
151
|
},
|
|
152
|
+
clearResourceById(resourceId, instanceId) {
|
|
153
|
+
const current = serviceSelectionsSignal.get();
|
|
154
|
+
// If no instanceId provided, use the first item
|
|
155
|
+
const targetId = instanceId ?? current[0]?.instanceId;
|
|
156
|
+
if (!targetId)
|
|
157
|
+
return;
|
|
158
|
+
const updated = current.map((item) => {
|
|
159
|
+
if (item.instanceId !== targetId)
|
|
160
|
+
return item;
|
|
161
|
+
// Filter out the resource with matching ID
|
|
162
|
+
const newResources = item.resources.filter((r) => r._id !== resourceId);
|
|
163
|
+
return { ...item, resources: newResources };
|
|
164
|
+
});
|
|
165
|
+
serviceSelectionsSignal.set(updated);
|
|
166
|
+
},
|
|
152
167
|
// Location actions
|
|
153
168
|
setLocation(location) {
|
|
154
169
|
locationSignal.set(location);
|
package/dist/services/index.d.ts
CHANGED
|
@@ -10,3 +10,4 @@ export { executeBookAction, canBook, buildBookingRequest, buildCheckoutRequest,
|
|
|
10
10
|
export { BookingFormService, BookingFormServiceDefinition, type BookingFormServiceAPI, type BookingFormServiceConfig, type BookingFormServiceInternalAPI, type ValidationResult, } from './booking-form/booking-form.js';
|
|
11
11
|
export { PaymentService, PaymentServiceDefinition, type PaymentServiceAPI, type PaymentServiceConfig, type PaymentDetails, type SlotService, type LineItemAdditionalInfo, loadPaymentConfig, type SuccessPaymentConfigResult, type ErrorPaymentConfigResult, } from './payment/payment.js';
|
|
12
12
|
export { LocationListService, LocationListServiceDefinition, LocationType, loadLocationListServiceInitialData, locationListServiceBinding, type LocationListServiceAPI, type LocationListServiceConfig, type LocationListActions, type LocationData, type DisplayLocation, type LoadLocationListServiceResult, } from './location-list/location-list.js';
|
|
13
|
+
export { StaffMemberListService, StaffMemberListServiceDefinition, loadStaffMemberListServiceInitialData, staffMemberListServiceBinding, type StaffMemberListServiceAPI, type StaffMemberListServiceConfig, type StaffMemberListActions, type StaffMemberData, type LoadStaffMemberListServiceResult, } from './staff-member-list/staff-member-list.js';
|
package/dist/services/index.js
CHANGED
|
@@ -10,3 +10,4 @@ export { executeBookAction, canBook, buildBookingRequest, buildCheckoutRequest,
|
|
|
10
10
|
export { BookingFormService, BookingFormServiceDefinition, } from './booking-form/booking-form.js';
|
|
11
11
|
export { PaymentService, PaymentServiceDefinition, loadPaymentConfig, } from './payment/payment.js';
|
|
12
12
|
export { LocationListService, LocationListServiceDefinition, LocationType, loadLocationListServiceInitialData, locationListServiceBinding, } from './location-list/location-list.js';
|
|
13
|
+
export { StaffMemberListService, StaffMemberListServiceDefinition, loadStaffMemberListServiceInitialData, staffMemberListServiceBinding, } from './staff-member-list/staff-member-list.js';
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Staff Member List Service Implementation
|
|
3
|
+
* Manages staff member state and BookingService integration
|
|
4
|
+
*
|
|
5
|
+
* @module Services/StaffMemberList
|
|
6
|
+
*/
|
|
7
|
+
import type { ServiceFactoryConfig } from '@wix/services-definitions';
|
|
8
|
+
import { type StaffMemberData } from './staff-member-list.def.js';
|
|
9
|
+
/**
|
|
10
|
+
* Configuration interface for StaffMemberListService
|
|
11
|
+
*/
|
|
12
|
+
export interface StaffMemberListServiceConfig {
|
|
13
|
+
/** Staff members array */
|
|
14
|
+
staffMembers?: StaffMemberData[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Implementation of the StaffMemberList service
|
|
18
|
+
* Manages staff member state for display purposes
|
|
19
|
+
*/
|
|
20
|
+
export declare const StaffMemberListService: import("@wix/services-definitions").ServiceFactory<string & {
|
|
21
|
+
__api: import("./staff-member-list.def.js").StaffMemberListServiceAPI;
|
|
22
|
+
__config: {};
|
|
23
|
+
isServiceDefinition?: boolean;
|
|
24
|
+
} & import("./staff-member-list.def.js").StaffMemberListServiceAPI, StaffMemberListServiceConfig>;
|
|
25
|
+
/**
|
|
26
|
+
* Result type for SSR loader
|
|
27
|
+
*/
|
|
28
|
+
export type LoadStaffMemberListServiceResult = {
|
|
29
|
+
type: 'success';
|
|
30
|
+
config: StaffMemberListServiceConfig;
|
|
31
|
+
} | {
|
|
32
|
+
type: 'error';
|
|
33
|
+
error: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* SSR Loader: Creates configuration for server-side rendering.
|
|
37
|
+
*
|
|
38
|
+
* @param options - Optional configuration
|
|
39
|
+
* @returns Configuration result for StaffMemberListService
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* // Pass staff members directly (e.g., from service.staffMemberDetails.staffMembers)
|
|
44
|
+
* const result = await loadStaffMemberListServiceInitialData({
|
|
45
|
+
* staffMembers: service.staffMemberDetails?.staffMembers,
|
|
46
|
+
* });
|
|
47
|
+
*
|
|
48
|
+
* if (result.type === 'error') {
|
|
49
|
+
* return Astro.redirect('/500');
|
|
50
|
+
* }
|
|
51
|
+
*
|
|
52
|
+
* const staffMemberListConfig = result.config;
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare function loadStaffMemberListServiceInitialData(options?: {
|
|
56
|
+
/** Pass staff members directly */
|
|
57
|
+
staffMembers?: StaffMemberData[];
|
|
58
|
+
}): Promise<LoadStaffMemberListServiceResult>;
|
|
59
|
+
/**
|
|
60
|
+
* Service binding helper for StaffMemberListService.
|
|
61
|
+
* Bundles definition, implementation, and config for ServicesManager.
|
|
62
|
+
*
|
|
63
|
+
* @param servicesConfigs - Object containing StaffMemberListServiceDefinition config
|
|
64
|
+
* @returns Tuple of [Definition, Implementation, Config] for addService()
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* const servicesManager = createServicesManager(
|
|
69
|
+
* createServicesMap()
|
|
70
|
+
* .addService(...staffMemberListServiceBinding(configs))
|
|
71
|
+
* );
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export declare const staffMemberListServiceBinding: <T extends {
|
|
75
|
+
[key: string]: StaffMemberListServiceConfig;
|
|
76
|
+
}>(servicesConfigs: T) => readonly [string & {
|
|
77
|
+
__api: import("./staff-member-list.def.js").StaffMemberListServiceAPI;
|
|
78
|
+
__config: {};
|
|
79
|
+
isServiceDefinition?: boolean;
|
|
80
|
+
} & import("./staff-member-list.def.js").StaffMemberListServiceAPI, import("@wix/services-definitions").ServiceFactory<string & {
|
|
81
|
+
__api: import("./staff-member-list.def.js").StaffMemberListServiceAPI;
|
|
82
|
+
__config: {};
|
|
83
|
+
isServiceDefinition?: boolean;
|
|
84
|
+
} & import("./staff-member-list.def.js").StaffMemberListServiceAPI, StaffMemberListServiceConfig>, StaffMemberListServiceConfig];
|
|
85
|
+
export { StaffMemberListServiceDefinition, type StaffMemberData, type StaffMemberListActions, type StaffMemberListServiceAPI, } from './staff-member-list.def.js';
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Staff Member List Service Definition
|
|
3
|
+
* Defines types and service interface for managing staff member lists
|
|
4
|
+
*
|
|
5
|
+
* @module Services/StaffMemberList/Definition
|
|
6
|
+
*/
|
|
7
|
+
import type { Signal, ReadOnlySignal } from '@wix/services-definitions/core-services/signals';
|
|
8
|
+
import type { StaffMember } from '@wix/auto_sdk_bookings_services';
|
|
9
|
+
/**
|
|
10
|
+
* StaffMemberData type - from Service['staffMemberDetails']['staffMembers'][number]
|
|
11
|
+
* Contains staffMemberId (which equals resource id), name, and mainMedia
|
|
12
|
+
*/
|
|
13
|
+
export type StaffMemberData = StaffMember;
|
|
14
|
+
/**
|
|
15
|
+
* Actions interface for staff member list management
|
|
16
|
+
*/
|
|
17
|
+
export interface StaffMemberListActions {
|
|
18
|
+
/** Select a staff member */
|
|
19
|
+
select: (staffMember: StaffMemberData) => void;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* API interface for the StaffMemberList service
|
|
23
|
+
*/
|
|
24
|
+
export interface StaffMemberListServiceAPI {
|
|
25
|
+
/** Reactive signal containing the staff members array */
|
|
26
|
+
staffMembers: Signal<StaffMemberData[]>;
|
|
27
|
+
/** Whether there are any staff members */
|
|
28
|
+
hasStaffMembers: ReadOnlySignal<boolean>;
|
|
29
|
+
/** Reactive signal indicating if staff members are loading */
|
|
30
|
+
isLoading: Signal<boolean>;
|
|
31
|
+
/** Reactive signal containing any error message */
|
|
32
|
+
error: Signal<string | null>;
|
|
33
|
+
/** Computed signal for selected staff member */
|
|
34
|
+
selectedStaffMember: ReadOnlySignal<StaffMemberData | null>;
|
|
35
|
+
/** Actions for staff member management */
|
|
36
|
+
actions: StaffMemberListActions;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Service definition for StaffMemberList
|
|
40
|
+
*/
|
|
41
|
+
export declare const StaffMemberListServiceDefinition: string & {
|
|
42
|
+
__api: StaffMemberListServiceAPI;
|
|
43
|
+
__config: {};
|
|
44
|
+
isServiceDefinition?: boolean;
|
|
45
|
+
} & StaffMemberListServiceAPI;
|
|
46
|
+
export type { StaffMember };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Staff Member List Service Definition
|
|
3
|
+
* Defines types and service interface for managing staff member lists
|
|
4
|
+
*
|
|
5
|
+
* @module Services/StaffMemberList/Definition
|
|
6
|
+
*/
|
|
7
|
+
import { defineService } from '@wix/services-definitions';
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Service Definition
|
|
10
|
+
// ============================================================================
|
|
11
|
+
/**
|
|
12
|
+
* Service definition for StaffMemberList
|
|
13
|
+
*/
|
|
14
|
+
export const StaffMemberListServiceDefinition = defineService('staff-member-list');
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Staff Member List Service Implementation
|
|
3
|
+
* Manages staff member state and BookingService integration
|
|
4
|
+
*
|
|
5
|
+
* @module Services/StaffMemberList
|
|
6
|
+
*/
|
|
7
|
+
import { implementService } from '@wix/services-definitions';
|
|
8
|
+
import { SignalsServiceDefinition, } from '@wix/services-definitions/core-services/signals';
|
|
9
|
+
import { StaffMemberListServiceDefinition, } from './staff-member-list.def.js';
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// Service Implementation
|
|
12
|
+
// ============================================================================
|
|
13
|
+
/**
|
|
14
|
+
* Implementation of the StaffMemberList service
|
|
15
|
+
* Manages staff member state for display purposes
|
|
16
|
+
*/
|
|
17
|
+
export const StaffMemberListService = implementService.withConfig()(StaffMemberListServiceDefinition, ({ getService, config }) => {
|
|
18
|
+
const signalsService = getService(SignalsServiceDefinition);
|
|
19
|
+
// Initialize staff members signal
|
|
20
|
+
const staffMembersSignal = signalsService.signal(config.staffMembers || []);
|
|
21
|
+
// Has staff members signal
|
|
22
|
+
const hasStaffMembersSignal = signalsService.computed(() => staffMembersSignal.get().length > 0);
|
|
23
|
+
const isLoadingSignal = signalsService.signal(false);
|
|
24
|
+
const errorSignal = signalsService.signal(null);
|
|
25
|
+
// Selected staff member - managed locally
|
|
26
|
+
const selectedStaffMemberSignal = signalsService.signal(null);
|
|
27
|
+
// Actions
|
|
28
|
+
const actions = {
|
|
29
|
+
select: (staffMember) => {
|
|
30
|
+
selectedStaffMemberSignal.set(staffMember);
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
return {
|
|
34
|
+
staffMembers: staffMembersSignal,
|
|
35
|
+
hasStaffMembers: hasStaffMembersSignal,
|
|
36
|
+
isLoading: isLoadingSignal,
|
|
37
|
+
error: errorSignal,
|
|
38
|
+
selectedStaffMember: selectedStaffMemberSignal,
|
|
39
|
+
actions,
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
/**
|
|
43
|
+
* SSR Loader: Creates configuration for server-side rendering.
|
|
44
|
+
*
|
|
45
|
+
* @param options - Optional configuration
|
|
46
|
+
* @returns Configuration result for StaffMemberListService
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* // Pass staff members directly (e.g., from service.staffMemberDetails.staffMembers)
|
|
51
|
+
* const result = await loadStaffMemberListServiceInitialData({
|
|
52
|
+
* staffMembers: service.staffMemberDetails?.staffMembers,
|
|
53
|
+
* });
|
|
54
|
+
*
|
|
55
|
+
* if (result.type === 'error') {
|
|
56
|
+
* return Astro.redirect('/500');
|
|
57
|
+
* }
|
|
58
|
+
*
|
|
59
|
+
* const staffMemberListConfig = result.config;
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export async function loadStaffMemberListServiceInitialData(options) {
|
|
63
|
+
try {
|
|
64
|
+
return {
|
|
65
|
+
type: 'success',
|
|
66
|
+
config: {
|
|
67
|
+
staffMembers: options?.staffMembers || [],
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
const message = error instanceof Error ? error.message : 'Failed to load staff members';
|
|
73
|
+
console.error('loadStaffMemberListServiceInitialData error:', error);
|
|
74
|
+
return { type: 'error', error: message };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// ============================================================================
|
|
78
|
+
// Service Binding Helper
|
|
79
|
+
// ============================================================================
|
|
80
|
+
/**
|
|
81
|
+
* Service binding helper for StaffMemberListService.
|
|
82
|
+
* Bundles definition, implementation, and config for ServicesManager.
|
|
83
|
+
*
|
|
84
|
+
* @param servicesConfigs - Object containing StaffMemberListServiceDefinition config
|
|
85
|
+
* @returns Tuple of [Definition, Implementation, Config] for addService()
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* const servicesManager = createServicesManager(
|
|
90
|
+
* createServicesMap()
|
|
91
|
+
* .addService(...staffMemberListServiceBinding(configs))
|
|
92
|
+
* );
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
export const staffMemberListServiceBinding = (servicesConfigs) => {
|
|
96
|
+
return [
|
|
97
|
+
StaffMemberListServiceDefinition,
|
|
98
|
+
StaffMemberListService,
|
|
99
|
+
servicesConfigs['staff-member-list'],
|
|
100
|
+
];
|
|
101
|
+
};
|
|
102
|
+
// ============================================================================
|
|
103
|
+
// Re-exports
|
|
104
|
+
// ============================================================================
|
|
105
|
+
export { StaffMemberListServiceDefinition, } from './staff-member-list.def.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/headless-bookings",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.54",
|
|
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": "079a06fd7da27790c8fe3e4d05005528c07424a69a125f7f49da76e4"
|
|
76
76
|
}
|