@wix/headless-bookings 0.0.1 → 0.0.2
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/ServiceList.d.ts +50 -0
- package/cjs/dist/react/ServiceList.js +100 -0
- package/cjs/dist/react/ServiceListSort.d.ts +37 -0
- package/cjs/dist/react/ServiceListSort.js +35 -0
- package/cjs/dist/react/core/Service.d.ts +91 -0
- package/cjs/dist/react/core/Service.js +73 -0
- package/cjs/dist/react/core/ServiceList.d.ts +218 -0
- package/cjs/dist/react/core/ServiceList.js +199 -0
- package/cjs/dist/react/index.d.ts +4 -0
- package/cjs/dist/react/index.js +5 -0
- package/cjs/dist/react/test-ids.d.ts +18 -0
- package/cjs/dist/react/test-ids.js +24 -0
- package/cjs/dist/react/types.d.ts +52 -0
- package/cjs/dist/react/types.js +1 -0
- package/cjs/dist/services/index.d.ts +1 -0
- package/cjs/dist/services/index.js +1 -0
- package/cjs/dist/services/service-service.d.ts +136 -0
- package/cjs/dist/services/service-service.js +140 -0
- package/cjs/dist/services/services-list-service.d.ts +184 -0
- package/cjs/dist/services/services-list-service.js +168 -0
- package/cjs/package.json +3 -0
- package/dist/react/ServiceList.d.ts +50 -0
- package/dist/react/ServiceList.js +100 -0
- package/dist/react/ServiceListSort.d.ts +37 -0
- package/dist/react/ServiceListSort.js +35 -0
- package/dist/react/core/Service.d.ts +91 -0
- package/dist/react/core/Service.js +73 -0
- package/dist/react/core/ServiceList.d.ts +218 -0
- package/dist/react/core/ServiceList.js +199 -0
- package/dist/react/index.d.ts +4 -0
- package/dist/react/index.js +5 -0
- package/dist/react/test-ids.d.ts +18 -0
- package/dist/react/test-ids.js +24 -0
- package/dist/react/types.d.ts +52 -0
- package/dist/react/types.js +1 -0
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +1 -0
- package/dist/services/service-service.d.ts +136 -0
- package/dist/services/service-service.js +140 -0
- package/dist/services/services-list-service.d.ts +184 -0
- package/dist/services/services-list-service.js +168 -0
- package/package.json +58 -13
- package/react/package.json +4 -0
- package/services/package.json +4 -0
- package/src/react/index.tsx +0 -3
- package/tsconfig.json +0 -25
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useService, WixServices } from '@wix/services-manager-react';
|
|
3
|
+
import { createServicesMap } from '@wix/services-manager';
|
|
4
|
+
import { ServiceService, ServiceServiceDefinition, } from '../../services/service-service.js';
|
|
5
|
+
import { WixMediaImage } from '@wix/headless-media/react';
|
|
6
|
+
function Content(props) {
|
|
7
|
+
const serviceService = useService(ServiceServiceDefinition);
|
|
8
|
+
const service = serviceService.service.get();
|
|
9
|
+
return props.children({ service });
|
|
10
|
+
}
|
|
11
|
+
function Loading(props) {
|
|
12
|
+
const serviceService = useService(ServiceServiceDefinition);
|
|
13
|
+
const isLoading = serviceService.isLoading.get();
|
|
14
|
+
return props.children({ isLoading });
|
|
15
|
+
}
|
|
16
|
+
export function Name(props) {
|
|
17
|
+
const serviceService = useService(ServiceServiceDefinition);
|
|
18
|
+
const service = serviceService.service.get();
|
|
19
|
+
if (!service)
|
|
20
|
+
return null;
|
|
21
|
+
return props.children({ name: service.name || '' });
|
|
22
|
+
}
|
|
23
|
+
export function Description(props) {
|
|
24
|
+
const serviceService = useService(ServiceServiceDefinition);
|
|
25
|
+
const service = serviceService.service.get();
|
|
26
|
+
if (!service)
|
|
27
|
+
return null;
|
|
28
|
+
return props.children({ description: service.description || null });
|
|
29
|
+
}
|
|
30
|
+
export function Price(props) {
|
|
31
|
+
const serviceService = useService(ServiceServiceDefinition);
|
|
32
|
+
const service = serviceService.service.get();
|
|
33
|
+
if (!service)
|
|
34
|
+
return null;
|
|
35
|
+
const price = service.payment?.fixed?.price
|
|
36
|
+
? {
|
|
37
|
+
value: Number(service.payment.fixed.price.value),
|
|
38
|
+
currency: service.payment.fixed.price.currency || '',
|
|
39
|
+
}
|
|
40
|
+
: null;
|
|
41
|
+
return props.children({ price });
|
|
42
|
+
}
|
|
43
|
+
export function Image() {
|
|
44
|
+
const serviceService = useService(ServiceServiceDefinition);
|
|
45
|
+
const service = serviceService.service.get();
|
|
46
|
+
if (!service || !service.media?.mainMedia?.image)
|
|
47
|
+
return null;
|
|
48
|
+
//WA until the issue with media will be solved
|
|
49
|
+
const image = service.media?.mainMedia?.image?.replace(/v1\/[\w-]+\//, 'v1/');
|
|
50
|
+
return _jsx(WixMediaImage, { media: { image }, alt: service.name || '' });
|
|
51
|
+
}
|
|
52
|
+
export function Root(props) {
|
|
53
|
+
const { serviceConfig, children } = props;
|
|
54
|
+
const services = createServicesMap().addService(ServiceServiceDefinition, ServiceService, serviceConfig);
|
|
55
|
+
return _jsx(WixServices, { servicesMap: services, children: children });
|
|
56
|
+
}
|
|
57
|
+
// Set display names for components
|
|
58
|
+
Root.displayName = 'Service.Root';
|
|
59
|
+
Content.displayName = 'Service.Content';
|
|
60
|
+
Loading.displayName = 'Service.Loading';
|
|
61
|
+
Name.displayName = 'Service.Name';
|
|
62
|
+
Description.displayName = 'Service.Description';
|
|
63
|
+
Price.displayName = 'Service.Price';
|
|
64
|
+
Image.displayName = 'Service.Image';
|
|
65
|
+
export const Service = {
|
|
66
|
+
Root,
|
|
67
|
+
Content,
|
|
68
|
+
Loading,
|
|
69
|
+
Name,
|
|
70
|
+
Description,
|
|
71
|
+
Price,
|
|
72
|
+
Image,
|
|
73
|
+
};
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { type ServicesListServiceConfig } from '../../services/services-list-service.js';
|
|
2
|
+
import { services } from '@wix/bookings';
|
|
3
|
+
/**
|
|
4
|
+
* Props for Root headless component
|
|
5
|
+
*/
|
|
6
|
+
export interface RootProps {
|
|
7
|
+
/** Child components that will have access to the ServiceList service */
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
/** Configuration for the ServiceList service */
|
|
10
|
+
servicesListConfig: ServicesListServiceConfig;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Root component that provides ServiceList service context to its children.
|
|
14
|
+
* This component sets up the necessary services for managing services list state,
|
|
15
|
+
* including filtering, sorting, and pagination functionality.
|
|
16
|
+
*
|
|
17
|
+
* @order 1
|
|
18
|
+
* @component
|
|
19
|
+
* @example
|
|
20
|
+
* ```tsx
|
|
21
|
+
* import { ServiceList, Service } from '@wix/headless-services/react';
|
|
22
|
+
*
|
|
23
|
+
* function ServiceListPage() {
|
|
24
|
+
* return (
|
|
25
|
+
* <ServiceList.Root
|
|
26
|
+
* servicesListConfig={{
|
|
27
|
+
* services: myServices,
|
|
28
|
+
* searchOptions: {
|
|
29
|
+
* cursorPaging: { limit: 10 },
|
|
30
|
+
* sort: [{ fieldName: 'name', order: 'ASC' }]
|
|
31
|
+
* },
|
|
32
|
+
* pagingMetadata: { count: 10, hasNext: true }
|
|
33
|
+
* }}
|
|
34
|
+
* >
|
|
35
|
+
* <ServiceList.Options>
|
|
36
|
+
* <ServiceList.ServiceRepeater>
|
|
37
|
+
* <Service.Name>
|
|
38
|
+
* {({ name }) => <h3>{name}</h3>}
|
|
39
|
+
* </Service.Name>
|
|
40
|
+
* <Service.Price>
|
|
41
|
+
* {({ price }) => price && <div>{price.value} {price.currency}</div>}
|
|
42
|
+
* </Service.Price>
|
|
43
|
+
* </ServiceList.ServiceRepeater>
|
|
44
|
+
* </ServiceList.Options>
|
|
45
|
+
* </ServiceList.Root>
|
|
46
|
+
* );
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function Root(props: RootProps): React.ReactNode;
|
|
51
|
+
/**
|
|
52
|
+
* Props for EmptyState headless component
|
|
53
|
+
*/
|
|
54
|
+
export interface EmptyStateProps {
|
|
55
|
+
/** Content to display when services list is empty (can be a render function or ReactNode) */
|
|
56
|
+
children: ((props: EmptyStateRenderProps) => React.ReactNode) | React.ReactNode;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Render props for EmptyState component
|
|
60
|
+
*/
|
|
61
|
+
export interface EmptyStateRenderProps {
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Component that renders content when the services list is empty.
|
|
65
|
+
* Only displays its children when there are no services, no loading state, and no errors.
|
|
66
|
+
*
|
|
67
|
+
* @component
|
|
68
|
+
* @example
|
|
69
|
+
* ```tsx
|
|
70
|
+
* import { ServiceList } from '@wix/headless-services/react';
|
|
71
|
+
*
|
|
72
|
+
* function EmptyServicesMessage() {
|
|
73
|
+
* return (
|
|
74
|
+
* <ServiceList.EmptyState>
|
|
75
|
+
* {() => (
|
|
76
|
+
* <div className="empty-state">
|
|
77
|
+
* <h3>No services found</h3>
|
|
78
|
+
* <p>Try adjusting your search or filter criteria</p>
|
|
79
|
+
* <button>Clear Filters</button>
|
|
80
|
+
* </div>
|
|
81
|
+
* )}
|
|
82
|
+
* </ServiceList.EmptyState>
|
|
83
|
+
* );
|
|
84
|
+
* }
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export declare function EmptyState(props: EmptyStateProps): React.ReactNode;
|
|
88
|
+
/**
|
|
89
|
+
* Props for Loading headless component
|
|
90
|
+
*/
|
|
91
|
+
export interface LoadingProps {
|
|
92
|
+
/** Content to display during loading (can be a render function or ReactNode) */
|
|
93
|
+
children: ((props: LoadingRenderProps) => React.ReactNode) | React.ReactNode;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Render props for Loading component
|
|
97
|
+
*/
|
|
98
|
+
export interface LoadingRenderProps {
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Component that renders content during loading state.
|
|
102
|
+
* Only displays its children when the services list is currently loading.
|
|
103
|
+
*
|
|
104
|
+
* @component
|
|
105
|
+
* @example
|
|
106
|
+
* ```tsx
|
|
107
|
+
* import { ServiceList } from '@wix/headless-services/react';
|
|
108
|
+
*
|
|
109
|
+
* function ServicesLoading() {
|
|
110
|
+
* return (
|
|
111
|
+
* <ServiceList.Loading>
|
|
112
|
+
* {() => (
|
|
113
|
+
* <div className="loading-spinner">
|
|
114
|
+
* <div>Loading services...</div>
|
|
115
|
+
* <div className="spinner"></div>
|
|
116
|
+
* </div>
|
|
117
|
+
* )}
|
|
118
|
+
* </ServiceList.Loading>
|
|
119
|
+
* );
|
|
120
|
+
* }
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
export declare function Loading(props: LoadingProps): React.ReactNode;
|
|
124
|
+
/**
|
|
125
|
+
* Props for Error headless component
|
|
126
|
+
*/
|
|
127
|
+
export interface ErrorProps {
|
|
128
|
+
/** Content to display during error state (can be a render function or ReactNode) */
|
|
129
|
+
children: ((props: ErrorRenderProps) => React.ReactNode) | React.ReactNode;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Render props for Error component
|
|
133
|
+
*/
|
|
134
|
+
export interface ErrorRenderProps {
|
|
135
|
+
/** Error message */
|
|
136
|
+
error: string | null;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Component that renders content when there's an error loading services.
|
|
140
|
+
* Only displays its children when an error has occurred.
|
|
141
|
+
*
|
|
142
|
+
* @component
|
|
143
|
+
* @example
|
|
144
|
+
* ```tsx
|
|
145
|
+
* import { ServiceList } from '@wix/headless-services/react';
|
|
146
|
+
*
|
|
147
|
+
* function ServicesError() {
|
|
148
|
+
* return (
|
|
149
|
+
* <ServiceList.Error>
|
|
150
|
+
* {({ error }) => (
|
|
151
|
+
* <div className="error-state">
|
|
152
|
+
* <h3>Error loading services</h3>
|
|
153
|
+
* <p>{error}</p>
|
|
154
|
+
* <button onClick={() => window.location.reload()}>
|
|
155
|
+
* Try Again
|
|
156
|
+
* </button>
|
|
157
|
+
* </div>
|
|
158
|
+
* )}
|
|
159
|
+
* </ServiceList.Error>
|
|
160
|
+
* );
|
|
161
|
+
* }
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
export declare function Error(props: ErrorProps): React.ReactNode;
|
|
165
|
+
/**
|
|
166
|
+
* Props for ItemContent headless component
|
|
167
|
+
*/
|
|
168
|
+
export interface ItemContentProps {
|
|
169
|
+
/** Content to display for each service (can be a render function receiving service data or ReactNode) */
|
|
170
|
+
children: ((props: ItemContentRenderProps) => React.ReactNode) | React.ReactNode;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Render props for ItemContent component
|
|
174
|
+
*/
|
|
175
|
+
export interface ItemContentRenderProps {
|
|
176
|
+
/** Service data */
|
|
177
|
+
service: services.Service;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Component that renders content for each service in the list.
|
|
181
|
+
* Maps over all services and provides each service through a service context.
|
|
182
|
+
* Only renders when services are successfully loaded (not loading, no error, and has services).
|
|
183
|
+
*
|
|
184
|
+
* @component
|
|
185
|
+
* @example
|
|
186
|
+
* ```tsx
|
|
187
|
+
* import { ServiceList, Service } from '@wix/headless-services/react';
|
|
188
|
+
*
|
|
189
|
+
* function ServicesGrid() {
|
|
190
|
+
* return (
|
|
191
|
+
* <ServiceList.ItemContent>
|
|
192
|
+
* {({ service }) => (
|
|
193
|
+
* <div className="service-card">
|
|
194
|
+
* <Service.Image>
|
|
195
|
+
* {({ image, alt }) => <img src={image} alt={alt} />}
|
|
196
|
+
* </Service.Image>
|
|
197
|
+
* <Service.Name>
|
|
198
|
+
* {({ name }) => <h3>{name}</h3>}
|
|
199
|
+
* </Service.Name>
|
|
200
|
+
* <Service.Price>
|
|
201
|
+
* {({ price }) => price && <p>{price.value} {price.currency}</p>}
|
|
202
|
+
* </Service.Price>
|
|
203
|
+
* <button>Book Now</button>
|
|
204
|
+
* </div>
|
|
205
|
+
* )}
|
|
206
|
+
* </ServiceList.ItemContent>
|
|
207
|
+
* );
|
|
208
|
+
* }
|
|
209
|
+
* ```
|
|
210
|
+
*/
|
|
211
|
+
export declare function ItemContent(props: ItemContentProps): React.ReactNode;
|
|
212
|
+
export type ItemsProps = {
|
|
213
|
+
children: ((props: ItemsRenderProps) => React.ReactNode) | React.ReactNode;
|
|
214
|
+
};
|
|
215
|
+
export type ItemsRenderProps = {
|
|
216
|
+
services: services.Service[];
|
|
217
|
+
};
|
|
218
|
+
export declare function Items(props: ItemsProps): import("react").ReactNode;
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useService, WixServices } from '@wix/services-manager-react';
|
|
3
|
+
import { createServicesMap } from '@wix/services-manager';
|
|
4
|
+
import { ServicesListService, ServicesListServiceDefinition, } from '../../services/services-list-service.js';
|
|
5
|
+
/**
|
|
6
|
+
* Root component that provides ServiceList service context to its children.
|
|
7
|
+
* This component sets up the necessary services for managing services list state,
|
|
8
|
+
* including filtering, sorting, and pagination functionality.
|
|
9
|
+
*
|
|
10
|
+
* @order 1
|
|
11
|
+
* @component
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* import { ServiceList, Service } from '@wix/headless-services/react';
|
|
15
|
+
*
|
|
16
|
+
* function ServiceListPage() {
|
|
17
|
+
* return (
|
|
18
|
+
* <ServiceList.Root
|
|
19
|
+
* servicesListConfig={{
|
|
20
|
+
* services: myServices,
|
|
21
|
+
* searchOptions: {
|
|
22
|
+
* cursorPaging: { limit: 10 },
|
|
23
|
+
* sort: [{ fieldName: 'name', order: 'ASC' }]
|
|
24
|
+
* },
|
|
25
|
+
* pagingMetadata: { count: 10, hasNext: true }
|
|
26
|
+
* }}
|
|
27
|
+
* >
|
|
28
|
+
* <ServiceList.Options>
|
|
29
|
+
* <ServiceList.ServiceRepeater>
|
|
30
|
+
* <Service.Name>
|
|
31
|
+
* {({ name }) => <h3>{name}</h3>}
|
|
32
|
+
* </Service.Name>
|
|
33
|
+
* <Service.Price>
|
|
34
|
+
* {({ price }) => price && <div>{price.value} {price.currency}</div>}
|
|
35
|
+
* </Service.Price>
|
|
36
|
+
* </ServiceList.ServiceRepeater>
|
|
37
|
+
* </ServiceList.Options>
|
|
38
|
+
* </ServiceList.Root>
|
|
39
|
+
* );
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export function Root(props) {
|
|
44
|
+
return (_jsx(WixServices, { servicesMap: createServicesMap().addService(ServicesListServiceDefinition, ServicesListService, props.servicesListConfig), children: props.children }));
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Component that renders content when the services list is empty.
|
|
48
|
+
* Only displays its children when there are no services, no loading state, and no errors.
|
|
49
|
+
*
|
|
50
|
+
* @component
|
|
51
|
+
* @example
|
|
52
|
+
* ```tsx
|
|
53
|
+
* import { ServiceList } from '@wix/headless-services/react';
|
|
54
|
+
*
|
|
55
|
+
* function EmptyServicesMessage() {
|
|
56
|
+
* return (
|
|
57
|
+
* <ServiceList.EmptyState>
|
|
58
|
+
* {() => (
|
|
59
|
+
* <div className="empty-state">
|
|
60
|
+
* <h3>No services found</h3>
|
|
61
|
+
* <p>Try adjusting your search or filter criteria</p>
|
|
62
|
+
* <button>Clear Filters</button>
|
|
63
|
+
* </div>
|
|
64
|
+
* )}
|
|
65
|
+
* </ServiceList.EmptyState>
|
|
66
|
+
* );
|
|
67
|
+
* }
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export function EmptyState(props) {
|
|
71
|
+
const { isLoading, error, services: servicesList, } = useService(ServicesListServiceDefinition);
|
|
72
|
+
const isLoadingValue = isLoading.get();
|
|
73
|
+
const errorValue = error.get();
|
|
74
|
+
const servicesValue = servicesList.get();
|
|
75
|
+
if (!isLoadingValue && !errorValue && servicesValue.length === 0) {
|
|
76
|
+
return typeof props.children === 'function'
|
|
77
|
+
? props.children({})
|
|
78
|
+
: props.children;
|
|
79
|
+
}
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Component that renders content during loading state.
|
|
84
|
+
* Only displays its children when the services list is currently loading.
|
|
85
|
+
*
|
|
86
|
+
* @component
|
|
87
|
+
* @example
|
|
88
|
+
* ```tsx
|
|
89
|
+
* import { ServiceList } from '@wix/headless-services/react';
|
|
90
|
+
*
|
|
91
|
+
* function ServicesLoading() {
|
|
92
|
+
* return (
|
|
93
|
+
* <ServiceList.Loading>
|
|
94
|
+
* {() => (
|
|
95
|
+
* <div className="loading-spinner">
|
|
96
|
+
* <div>Loading services...</div>
|
|
97
|
+
* <div className="spinner"></div>
|
|
98
|
+
* </div>
|
|
99
|
+
* )}
|
|
100
|
+
* </ServiceList.Loading>
|
|
101
|
+
* );
|
|
102
|
+
* }
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
export function Loading(props) {
|
|
106
|
+
const { isLoading } = useService(ServicesListServiceDefinition);
|
|
107
|
+
const isLoadingValue = isLoading.get();
|
|
108
|
+
if (isLoadingValue) {
|
|
109
|
+
return typeof props.children === 'function'
|
|
110
|
+
? props.children({})
|
|
111
|
+
: props.children;
|
|
112
|
+
}
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Component that renders content when there's an error loading services.
|
|
117
|
+
* Only displays its children when an error has occurred.
|
|
118
|
+
*
|
|
119
|
+
* @component
|
|
120
|
+
* @example
|
|
121
|
+
* ```tsx
|
|
122
|
+
* import { ServiceList } from '@wix/headless-services/react';
|
|
123
|
+
*
|
|
124
|
+
* function ServicesError() {
|
|
125
|
+
* return (
|
|
126
|
+
* <ServiceList.Error>
|
|
127
|
+
* {({ error }) => (
|
|
128
|
+
* <div className="error-state">
|
|
129
|
+
* <h3>Error loading services</h3>
|
|
130
|
+
* <p>{error}</p>
|
|
131
|
+
* <button onClick={() => window.location.reload()}>
|
|
132
|
+
* Try Again
|
|
133
|
+
* </button>
|
|
134
|
+
* </div>
|
|
135
|
+
* )}
|
|
136
|
+
* </ServiceList.Error>
|
|
137
|
+
* );
|
|
138
|
+
* }
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
export function Error(props) {
|
|
142
|
+
const { error } = useService(ServicesListServiceDefinition);
|
|
143
|
+
const errorValue = error.get();
|
|
144
|
+
if (errorValue) {
|
|
145
|
+
return typeof props.children === 'function'
|
|
146
|
+
? props.children({ error: errorValue })
|
|
147
|
+
: props.children;
|
|
148
|
+
}
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Component that renders content for each service in the list.
|
|
153
|
+
* Maps over all services and provides each service through a service context.
|
|
154
|
+
* Only renders when services are successfully loaded (not loading, no error, and has services).
|
|
155
|
+
*
|
|
156
|
+
* @component
|
|
157
|
+
* @example
|
|
158
|
+
* ```tsx
|
|
159
|
+
* import { ServiceList, Service } from '@wix/headless-services/react';
|
|
160
|
+
*
|
|
161
|
+
* function ServicesGrid() {
|
|
162
|
+
* return (
|
|
163
|
+
* <ServiceList.ItemContent>
|
|
164
|
+
* {({ service }) => (
|
|
165
|
+
* <div className="service-card">
|
|
166
|
+
* <Service.Image>
|
|
167
|
+
* {({ image, alt }) => <img src={image} alt={alt} />}
|
|
168
|
+
* </Service.Image>
|
|
169
|
+
* <Service.Name>
|
|
170
|
+
* {({ name }) => <h3>{name}</h3>}
|
|
171
|
+
* </Service.Name>
|
|
172
|
+
* <Service.Price>
|
|
173
|
+
* {({ price }) => price && <p>{price.value} {price.currency}</p>}
|
|
174
|
+
* </Service.Price>
|
|
175
|
+
* <button>Book Now</button>
|
|
176
|
+
* </div>
|
|
177
|
+
* )}
|
|
178
|
+
* </ServiceList.ItemContent>
|
|
179
|
+
* );
|
|
180
|
+
* }
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
183
|
+
export function ItemContent(props) {
|
|
184
|
+
const { services: servicesList, isLoading, error, } = useService(ServicesListServiceDefinition);
|
|
185
|
+
const servicesValue = servicesList.get();
|
|
186
|
+
if (isLoading.get() || error.get() || servicesValue.length === 0) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
return servicesValue.map((service) => (_jsx(WixServices, { servicesMap: createServicesMap(), children: typeof props.children === 'function'
|
|
190
|
+
? props.children({ service })
|
|
191
|
+
: props.children }, service._id)));
|
|
192
|
+
}
|
|
193
|
+
export function Items(props) {
|
|
194
|
+
const { services: servicesList } = useService(ServicesListServiceDefinition);
|
|
195
|
+
const servicesValue = servicesList.get();
|
|
196
|
+
return typeof props.children === 'function'
|
|
197
|
+
? props.children({ services: servicesValue })
|
|
198
|
+
: props.children;
|
|
199
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare enum TestIds {
|
|
2
|
+
servicesList = "services-list",
|
|
3
|
+
servicesOptions = "services-options",
|
|
4
|
+
serviceRepeater = "service-repeater",
|
|
5
|
+
serviceRoot = "service-root",
|
|
6
|
+
serviceName = "service-name",
|
|
7
|
+
serviceDescription = "service-description",
|
|
8
|
+
servicePrice = "service-price",
|
|
9
|
+
serviceDuration = "service-duration",
|
|
10
|
+
serviceImage = "service-image",
|
|
11
|
+
serviceCategory = "service-category",
|
|
12
|
+
serviceError = "service-error",
|
|
13
|
+
serviceLoadMore = "service-load-more",
|
|
14
|
+
serviceTotalsDisplayed = "service-totals-displayed",
|
|
15
|
+
serviceSort = "service-sort",
|
|
16
|
+
serviceFilter = "service-filter",
|
|
17
|
+
serviceFilterResetTrigger = "service-filter-reset-trigger"
|
|
18
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export var TestIds;
|
|
2
|
+
(function (TestIds) {
|
|
3
|
+
// Container Level
|
|
4
|
+
TestIds["servicesList"] = "services-list";
|
|
5
|
+
// List Container Level
|
|
6
|
+
TestIds["servicesOptions"] = "services-options";
|
|
7
|
+
// Repeater Level
|
|
8
|
+
TestIds["serviceRepeater"] = "service-repeater";
|
|
9
|
+
// Entity Root and Components
|
|
10
|
+
TestIds["serviceRoot"] = "service-root";
|
|
11
|
+
TestIds["serviceName"] = "service-name";
|
|
12
|
+
TestIds["serviceDescription"] = "service-description";
|
|
13
|
+
TestIds["servicePrice"] = "service-price";
|
|
14
|
+
TestIds["serviceDuration"] = "service-duration";
|
|
15
|
+
TestIds["serviceImage"] = "service-image";
|
|
16
|
+
TestIds["serviceCategory"] = "service-category";
|
|
17
|
+
// Additional Components
|
|
18
|
+
TestIds["serviceError"] = "service-error";
|
|
19
|
+
TestIds["serviceLoadMore"] = "service-load-more";
|
|
20
|
+
TestIds["serviceTotalsDisplayed"] = "service-totals-displayed";
|
|
21
|
+
TestIds["serviceSort"] = "service-sort";
|
|
22
|
+
TestIds["serviceFilter"] = "service-filter";
|
|
23
|
+
TestIds["serviceFilterResetTrigger"] = "service-filter-reset-trigger";
|
|
24
|
+
})(TestIds || (TestIds = {}));
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { services } from '@wix/bookings';
|
|
2
|
+
export interface ServiceListConfig {
|
|
3
|
+
services: services.Service[];
|
|
4
|
+
searchOptions: {
|
|
5
|
+
cursorPaging: {
|
|
6
|
+
limit: number;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
pagingMetadata: {
|
|
10
|
+
count: number;
|
|
11
|
+
};
|
|
12
|
+
aggregations: {
|
|
13
|
+
results: any[];
|
|
14
|
+
};
|
|
15
|
+
customizations: any[];
|
|
16
|
+
}
|
|
17
|
+
export interface ServiceContextValue {
|
|
18
|
+
service: services.Service;
|
|
19
|
+
}
|
|
20
|
+
export interface ServiceListRenderProps {
|
|
21
|
+
services: services.Service[];
|
|
22
|
+
}
|
|
23
|
+
export interface ServiceRenderProps {
|
|
24
|
+
service: services.Service;
|
|
25
|
+
}
|
|
26
|
+
export interface ErrorRenderProps {
|
|
27
|
+
error: string | null;
|
|
28
|
+
}
|
|
29
|
+
export interface ServiceListState {
|
|
30
|
+
services: services.Service[];
|
|
31
|
+
pagingMetadata: {
|
|
32
|
+
count: number;
|
|
33
|
+
};
|
|
34
|
+
filters: Record<string, any>;
|
|
35
|
+
error: string | null;
|
|
36
|
+
}
|
|
37
|
+
export interface ServiceListServiceValue {
|
|
38
|
+
services: {
|
|
39
|
+
get: () => services.Service[];
|
|
40
|
+
};
|
|
41
|
+
pagingMetadata: {
|
|
42
|
+
get: () => {
|
|
43
|
+
count: number;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
filters: {
|
|
47
|
+
get: () => Record<string, any>;
|
|
48
|
+
};
|
|
49
|
+
error: {
|
|
50
|
+
get: () => string | null;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './services-list-service.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './services-list-service.js';
|