@wix/headless-bookings 0.0.10 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/dist/api/index.d.ts +10 -1
- package/cjs/dist/api/index.js +10 -1
- package/cjs/dist/api/query-services/index.d.ts +78 -0
- package/cjs/dist/api/query-services/index.js +137 -0
- package/cjs/dist/react/core/location/Location.d.ts +44 -0
- package/cjs/dist/react/core/location/Location.js +78 -0
- package/cjs/dist/react/core/service/Service.d.ts +160 -17
- package/cjs/dist/react/core/service/Service.js +211 -13
- package/cjs/dist/react/core/service-list/ServiceList.d.ts +75 -0
- package/cjs/dist/react/core/service-list/ServiceList.js +58 -0
- package/cjs/dist/react/index.d.ts +2 -0
- package/cjs/dist/react/index.js +2 -0
- package/cjs/dist/react/location/Location.d.ts +77 -0
- package/cjs/dist/react/location/Location.js +89 -0
- package/cjs/dist/react/service/Service.d.ts +1036 -31
- package/cjs/dist/react/service/Service.js +1060 -47
- package/cjs/dist/react/service-list/ServiceList.d.ts +185 -0
- package/cjs/dist/react/service-list/ServiceList.js +184 -0
- package/cjs/dist/services/index.d.ts +2 -1
- package/cjs/dist/services/index.js +2 -1
- package/cjs/dist/services/service/service.d.ts +71 -18
- package/cjs/dist/services/service/service.js +186 -50
- package/cjs/dist/services/service-list/service-list.d.ts +157 -0
- package/cjs/dist/services/service-list/service-list.js +274 -0
- package/cjs/dist/utils/dateAndTime.d.ts +2 -0
- package/cjs/dist/utils/dateAndTime.js +18 -0
- package/cjs/dist/utils/money.d.ts +21 -0
- package/cjs/dist/utils/money.js +34 -0
- package/dist/api/index.d.ts +10 -1
- package/dist/api/index.js +10 -1
- package/dist/api/query-services/index.d.ts +78 -0
- package/dist/api/query-services/index.js +137 -0
- package/dist/react/core/location/Location.d.ts +44 -0
- package/dist/react/core/location/Location.js +78 -0
- package/dist/react/core/service/Service.d.ts +160 -17
- package/dist/react/core/service/Service.js +211 -13
- package/dist/react/core/service-list/ServiceList.d.ts +75 -0
- package/dist/react/core/service-list/ServiceList.js +58 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.js +2 -0
- package/dist/react/location/Location.d.ts +77 -0
- package/dist/react/location/Location.js +89 -0
- package/dist/react/service/Service.d.ts +1036 -31
- package/dist/react/service/Service.js +1060 -47
- package/dist/react/service-list/ServiceList.d.ts +185 -0
- package/dist/react/service-list/ServiceList.js +184 -0
- package/dist/services/index.d.ts +2 -1
- package/dist/services/index.js +2 -1
- package/dist/services/service/service.d.ts +71 -18
- package/dist/services/service/service.js +186 -50
- package/dist/services/service-list/service-list.d.ts +157 -0
- package/dist/services/service-list/service-list.js +274 -0
- package/dist/utils/dateAndTime.d.ts +2 -0
- package/dist/utils/dateAndTime.js +18 -0
- package/dist/utils/money.d.ts +21 -0
- package/dist/utils/money.js +34 -0
- package/package.json +2 -2
- package/cjs/dist/api/query-service/index.d.ts +0 -23
- package/cjs/dist/api/query-service/index.js +0 -41
- package/dist/api/query-service/index.d.ts +0 -23
- package/dist/api/query-service/index.js +0 -41
|
@@ -4,8 +4,14 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { defineService, implementService } from '@wix/services-definitions';
|
|
6
6
|
import { SignalsServiceDefinition, } from '@wix/services-definitions/core-services/signals';
|
|
7
|
-
import {
|
|
7
|
+
import { services } from '@wix/bookings';
|
|
8
|
+
import { getServiceById, getServiceBySlug, } from '../../api/query-services/index.js';
|
|
8
9
|
import { BookingServiceDefinition, } from '../booking/booking.js';
|
|
10
|
+
import { convertToMoneyData } from '../../utils/money.js';
|
|
11
|
+
/**
|
|
12
|
+
* Booking app ID constant
|
|
13
|
+
*/
|
|
14
|
+
const BOOKING_APP_ID = '13d21c63-b5ec-5912-8397-c3a5ddb27a97';
|
|
9
15
|
/**
|
|
10
16
|
* Service definition for the Service service.
|
|
11
17
|
* This defines the contract that the ServiceService must implement.
|
|
@@ -35,9 +41,9 @@ export const ServiceServiceDefinition = defineService('service');
|
|
|
35
41
|
*
|
|
36
42
|
* function ServiceDisplay() {
|
|
37
43
|
* const serviceService = useService(ServiceServiceDefinition);
|
|
38
|
-
* const service = serviceService.
|
|
39
|
-
* const isLoading = serviceService.
|
|
40
|
-
* const error = serviceService.
|
|
44
|
+
* const service = serviceService.serviceSignal.get();
|
|
45
|
+
* const isLoading = serviceService.isLoadingSignal.get();
|
|
46
|
+
* const error = serviceService.errorSignal.get();
|
|
41
47
|
*
|
|
42
48
|
* if (isLoading) return <div>Loading...</div>;
|
|
43
49
|
* if (error) return <div>Error: {error}</div>;
|
|
@@ -48,54 +54,170 @@ export const ServiceServiceDefinition = defineService('service');
|
|
|
48
54
|
*/
|
|
49
55
|
export const ServiceService = implementService.withConfig()(ServiceServiceDefinition, ({ getService, config }) => {
|
|
50
56
|
const signalsService = getService(SignalsServiceDefinition);
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
// Try to get BookingService (optional dependency for showcase mode)
|
|
58
|
+
let bookingService = null;
|
|
59
|
+
try {
|
|
60
|
+
bookingService = getService(BookingServiceDefinition);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// BookingService not available - showcase mode
|
|
64
|
+
bookingService = null;
|
|
65
|
+
}
|
|
66
|
+
// Initialize service signal - use empty service object if not provided
|
|
67
|
+
const initialService = config.service || {};
|
|
68
|
+
const serviceSignal = signalsService.signal(initialService);
|
|
69
|
+
const isLoadingSignal = signalsService.signal(!!config.serviceId);
|
|
70
|
+
const errorSignal = signalsService.signal(null);
|
|
71
|
+
// Default appId to BOOKING_APP_ID if not provided
|
|
72
|
+
const appId = config.appId ?? BOOKING_APP_ID;
|
|
73
|
+
// bookable signal - true if appId equals booking app ID
|
|
74
|
+
const bookableSignal = signalsService.computed(() => {
|
|
75
|
+
return appId === BOOKING_APP_ID;
|
|
76
|
+
});
|
|
77
|
+
// selected signal - true if current service is in BookingService preferences
|
|
78
|
+
const selectedSignal = signalsService.computed(() => {
|
|
79
|
+
if (!bookingService)
|
|
80
|
+
return false;
|
|
81
|
+
const currentService = serviceSignal.get();
|
|
82
|
+
if (!currentService._id)
|
|
83
|
+
return false;
|
|
84
|
+
const services = bookingService.services.get();
|
|
85
|
+
return services.some((selection) => selection.service._id === currentService._id);
|
|
86
|
+
});
|
|
87
|
+
// requiresAvailability signal - true for APPOINTMENT and CLASS types
|
|
88
|
+
const requiresAvailabilitySignal = signalsService.computed(() => {
|
|
89
|
+
const currentService = serviceSignal.get();
|
|
90
|
+
const serviceType = currentService.type;
|
|
91
|
+
return (serviceType === services.ServiceType.APPOINTMENT ||
|
|
92
|
+
serviceType === services.ServiceType.CLASS);
|
|
93
|
+
});
|
|
94
|
+
// paymentData signal - computed payment data from service
|
|
95
|
+
const paymentDataSignal = signalsService.computed(() => {
|
|
96
|
+
const service = serviceSignal.get();
|
|
97
|
+
const payment = service.payment;
|
|
98
|
+
const rateType = payment?.rateType;
|
|
99
|
+
// Initialize all price-related values
|
|
100
|
+
let money = null;
|
|
101
|
+
let minPrice = null;
|
|
102
|
+
let maxPrice = null;
|
|
103
|
+
let priceDescription = null;
|
|
104
|
+
// Extract pricing based on rate type
|
|
105
|
+
if (payment) {
|
|
106
|
+
switch (rateType) {
|
|
107
|
+
case services.RateType.FIXED:
|
|
108
|
+
// FIXED: Use payment.fixed.price
|
|
109
|
+
money = convertToMoneyData(payment.fixed?.price);
|
|
110
|
+
break;
|
|
111
|
+
case services.RateType.VARIED:
|
|
112
|
+
// VARIED: Use defaultPrice as money, plus min/max for range
|
|
113
|
+
money = convertToMoneyData(payment.varied?.defaultPrice);
|
|
114
|
+
minPrice = convertToMoneyData(payment.varied?.minPrice);
|
|
115
|
+
maxPrice = convertToMoneyData(payment.varied?.maxPrice);
|
|
116
|
+
break;
|
|
117
|
+
case services.RateType.CUSTOM:
|
|
118
|
+
// CUSTOM: Use description text (no numeric price)
|
|
119
|
+
priceDescription = payment.custom?.description || null;
|
|
120
|
+
break;
|
|
121
|
+
case services.RateType.NO_FEE:
|
|
122
|
+
// NO_FEE: Free service (amount = 0)
|
|
123
|
+
money = { amount: 0, currency: 'USD' };
|
|
124
|
+
break;
|
|
125
|
+
default:
|
|
126
|
+
// UNKNOWN_RATE_TYPE or undefined - leave all null
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Derive service capabilities
|
|
131
|
+
const hasAddOns = (service.addOnGroups?.length ?? 0) > 0;
|
|
132
|
+
const hasPricingPlans = (payment?.pricingPlanIds?.length ?? 0) > 0;
|
|
133
|
+
return {
|
|
134
|
+
servicePayment: payment,
|
|
135
|
+
rateType,
|
|
136
|
+
money,
|
|
137
|
+
minPrice,
|
|
138
|
+
maxPrice,
|
|
139
|
+
priceDescription,
|
|
140
|
+
hasAddOns,
|
|
141
|
+
hasPricingPlans,
|
|
142
|
+
};
|
|
143
|
+
});
|
|
144
|
+
const loadServiceById = async (id) => {
|
|
145
|
+
isLoadingSignal.set(true);
|
|
146
|
+
errorSignal.set(null);
|
|
147
|
+
const serviceResponse = await getServiceById(id, appId);
|
|
59
148
|
if (!serviceResponse.service) {
|
|
60
|
-
|
|
61
|
-
|
|
149
|
+
errorSignal.set('Service not found');
|
|
150
|
+
isLoadingSignal.set(false);
|
|
62
151
|
}
|
|
63
152
|
else {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
153
|
+
serviceSignal.set(serviceResponse.service);
|
|
154
|
+
errorSignal.set(null);
|
|
155
|
+
isLoadingSignal.set(false);
|
|
67
156
|
}
|
|
68
157
|
};
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const selection = { service: currentService };
|
|
83
|
-
bookingService.services.set([...selections, selection]);
|
|
158
|
+
const loadServiceBySlug = async (slug) => {
|
|
159
|
+
isLoadingSignal.set(true);
|
|
160
|
+
errorSignal.set(null);
|
|
161
|
+
const serviceResponse = await getServiceBySlug(slug, appId);
|
|
162
|
+
if (!serviceResponse.service) {
|
|
163
|
+
errorSignal.set('Service not found');
|
|
164
|
+
isLoadingSignal.set(false);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
serviceSignal.set(serviceResponse.service);
|
|
168
|
+
errorSignal.set(null);
|
|
169
|
+
isLoadingSignal.set(false);
|
|
170
|
+
}
|
|
84
171
|
};
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
172
|
+
// Auto-load if serviceId or serviceSlug is provided but no service data
|
|
173
|
+
// Priority: service > serviceSlug > serviceId
|
|
174
|
+
if (!config.service) {
|
|
175
|
+
if (config.serviceSlug) {
|
|
176
|
+
loadServiceBySlug(config.serviceSlug);
|
|
177
|
+
}
|
|
178
|
+
else if (config.serviceId) {
|
|
179
|
+
loadServiceById(config.serviceId);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// Action methods for booking - only work when bookable is true
|
|
183
|
+
const actions = {
|
|
184
|
+
select: () => {
|
|
185
|
+
if (!bookableSignal.get() || !bookingService)
|
|
186
|
+
return;
|
|
187
|
+
const currentService = serviceSignal.get();
|
|
188
|
+
const selection = {
|
|
189
|
+
service: currentService,
|
|
190
|
+
};
|
|
191
|
+
bookingService.actions.setServices([selection]);
|
|
192
|
+
},
|
|
193
|
+
add: () => {
|
|
194
|
+
if (!bookableSignal.get() || !bookingService)
|
|
195
|
+
return;
|
|
196
|
+
const currentService = serviceSignal.get();
|
|
197
|
+
const selection = {
|
|
198
|
+
service: currentService,
|
|
199
|
+
};
|
|
200
|
+
bookingService.actions.addService(selection);
|
|
201
|
+
},
|
|
202
|
+
remove: () => {
|
|
203
|
+
if (!bookableSignal.get() || !bookingService)
|
|
204
|
+
return;
|
|
205
|
+
const currentService = serviceSignal.get();
|
|
206
|
+
if (currentService._id) {
|
|
207
|
+
bookingService.actions.removeService(currentService._id);
|
|
208
|
+
}
|
|
209
|
+
},
|
|
90
210
|
};
|
|
91
211
|
return {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
212
|
+
serviceSignal,
|
|
213
|
+
isLoadingSignal,
|
|
214
|
+
errorSignal,
|
|
215
|
+
loadServiceById,
|
|
216
|
+
bookableSignal,
|
|
217
|
+
selectedSignal,
|
|
218
|
+
requiresAvailabilitySignal,
|
|
219
|
+
paymentDataSignal,
|
|
220
|
+
actions,
|
|
99
221
|
};
|
|
100
222
|
});
|
|
101
223
|
/**
|
|
@@ -103,15 +225,19 @@ export const ServiceService = implementService.withConfig()(ServiceServiceDefini
|
|
|
103
225
|
* This function is designed to be called during the build or server-side rendering phase
|
|
104
226
|
* to pre-fetch service data before the React components are hydrated on the client.
|
|
105
227
|
*
|
|
106
|
-
* @param
|
|
228
|
+
* @param params - Either `{ slug: string, appId?: string }` or `{ serviceId: string, appId?: string }`
|
|
107
229
|
* @returns A promise that resolves to either a success result with the config or a notFound result
|
|
108
230
|
*
|
|
109
231
|
* @example
|
|
110
232
|
* ```ts
|
|
111
233
|
* // In an Astro page or API route
|
|
112
|
-
* import {
|
|
234
|
+
* import { loadServiceServiceInitialData } from '@wix/headless-bookings/services';
|
|
235
|
+
*
|
|
236
|
+
* // Load by slug
|
|
237
|
+
* const serviceResult = await loadServiceServiceInitialData({ slug: 'group-trainings' });
|
|
113
238
|
*
|
|
114
|
-
*
|
|
239
|
+
* // Load by serviceId
|
|
240
|
+
* const serviceResult = await loadServiceServiceInitialData({ serviceId: 'service-id-123' });
|
|
115
241
|
*
|
|
116
242
|
* if (serviceResult.type === 'notFound') {
|
|
117
243
|
* return Astro.redirect('/404');
|
|
@@ -120,9 +246,17 @@ export const ServiceService = implementService.withConfig()(ServiceServiceDefini
|
|
|
120
246
|
* const serviceConfig = serviceResult.config;
|
|
121
247
|
* ```
|
|
122
248
|
*/
|
|
123
|
-
export async function
|
|
249
|
+
export async function loadServiceServiceInitialData(params) {
|
|
124
250
|
try {
|
|
125
|
-
|
|
251
|
+
// Default appId to BOOKING_APP_ID if not provided
|
|
252
|
+
const finalAppId = params.appId ?? BOOKING_APP_ID;
|
|
253
|
+
let serviceResponse;
|
|
254
|
+
if ('slug' in params) {
|
|
255
|
+
serviceResponse = await getServiceBySlug(params.slug, finalAppId);
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
serviceResponse = await getServiceById(params.serviceId, finalAppId);
|
|
259
|
+
}
|
|
126
260
|
if (!serviceResponse.service) {
|
|
127
261
|
return { type: 'notFound' };
|
|
128
262
|
}
|
|
@@ -130,11 +264,13 @@ export async function loadServiceServiceConfig(slug) {
|
|
|
130
264
|
type: 'success',
|
|
131
265
|
config: {
|
|
132
266
|
service: serviceResponse.service,
|
|
267
|
+
appId: finalAppId,
|
|
133
268
|
},
|
|
134
269
|
};
|
|
135
270
|
}
|
|
136
271
|
catch (error) {
|
|
137
|
-
|
|
272
|
+
const identifier = 'slug' in params ? `slug "${params.slug}"` : `id "${params.serviceId}"`;
|
|
273
|
+
console.error(`Failed to load service for ${identifier}:`, error);
|
|
138
274
|
return { type: 'notFound' };
|
|
139
275
|
}
|
|
140
276
|
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ServiceList Service - Reactive service list data management
|
|
3
|
+
* Handles querying and pagination of services list (NO selection management)
|
|
4
|
+
*/
|
|
5
|
+
import { type Signal, type ReadOnlySignal } from '@wix/services-definitions/core-services/signals';
|
|
6
|
+
import { services } from '@wix/bookings';
|
|
7
|
+
import type { QueryServicesRequest, PagingMetadata } from '../../api/query-services/index.js';
|
|
8
|
+
export type { ServiceListFilters } from '../../api/query-services/index.js';
|
|
9
|
+
/**
|
|
10
|
+
* Query options without paging metadata (user-controlled request params)
|
|
11
|
+
* Effect subscribes to changes in this signal to trigger re-fetches
|
|
12
|
+
*/
|
|
13
|
+
export type QueryOptions = Omit<QueryServicesRequest, 'pagingMetadata'>;
|
|
14
|
+
/**
|
|
15
|
+
* Configuration for the ServiceList service
|
|
16
|
+
*/
|
|
17
|
+
export interface ServiceListServiceConfig {
|
|
18
|
+
services?: services.Service[];
|
|
19
|
+
options?: QueryServicesRequest;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Actions object for service list operations
|
|
23
|
+
*/
|
|
24
|
+
export interface ServiceListActions {
|
|
25
|
+
loadMore: (count: number) => Promise<void>;
|
|
26
|
+
setQueryOptions: (options: QueryOptions) => void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* API interface for the ServiceList service
|
|
30
|
+
*/
|
|
31
|
+
export interface ServiceListServiceAPI {
|
|
32
|
+
/** Reactive signal containing the list of services */
|
|
33
|
+
servicesSignal: Signal<services.Service[]>;
|
|
34
|
+
/** Reactive signal containing current query options (appId, filters, sort) - changes trigger re-fetch */
|
|
35
|
+
queryOptionsSignal: Signal<QueryOptions>;
|
|
36
|
+
/** Reactive signal containing pagination metadata (limit, offset, count, hasNext) - updated after fetches */
|
|
37
|
+
pagingMetadataSignal: Signal<PagingMetadata>;
|
|
38
|
+
/** Reactive signal indicating if services are currently being loaded */
|
|
39
|
+
isLoadingSignal: Signal<boolean>;
|
|
40
|
+
/** Reactive signal containing any error message, or null if no error */
|
|
41
|
+
errorSignal: Signal<string | null>;
|
|
42
|
+
/** Actions object containing query actions */
|
|
43
|
+
actions: ServiceListActions;
|
|
44
|
+
/** Reactive signal indicating if there are more services to load */
|
|
45
|
+
hasMoreServicesSignal: ReadOnlySignal<boolean>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Service definition for the ServiceList service
|
|
49
|
+
*/
|
|
50
|
+
export declare const ServiceListServiceDefinition: string & {
|
|
51
|
+
__api: ServiceListServiceAPI;
|
|
52
|
+
__config: ServiceListServiceConfig;
|
|
53
|
+
isServiceDefinition?: boolean;
|
|
54
|
+
} & ServiceListServiceAPI;
|
|
55
|
+
/**
|
|
56
|
+
* Implementation of the ServiceList service that manages reactive services list data.
|
|
57
|
+
* This service provides signals for services data, query options, pagination metadata
|
|
58
|
+
* (including hasNext flag), loading state, and error handling.
|
|
59
|
+
* It automatically re-fetches services when query options change.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```tsx
|
|
63
|
+
* import { ServiceListService, ServiceListServiceDefinition } from '@wix/bookings/services';
|
|
64
|
+
* import { useService } from '@wix/services-manager-react';
|
|
65
|
+
*
|
|
66
|
+
* function ServicesComponent({ serviceListConfig }) {
|
|
67
|
+
* return (
|
|
68
|
+
* <ServiceProvider services={createServicesMap([
|
|
69
|
+
* [ServiceListServiceDefinition, ServiceListService.withConfig(serviceListConfig)]
|
|
70
|
+
* ])}>
|
|
71
|
+
* <ServicesDisplay />
|
|
72
|
+
* </ServiceProvider>
|
|
73
|
+
* );
|
|
74
|
+
* }
|
|
75
|
+
*
|
|
76
|
+
* function ServicesDisplay() {
|
|
77
|
+
* const serviceListService = useService(ServiceListServiceDefinition);
|
|
78
|
+
* const services = serviceListService.servicesSignal.get();
|
|
79
|
+
* const isLoading = serviceListService.isLoadingSignal.get();
|
|
80
|
+
* const error = serviceListService.errorSignal.get();
|
|
81
|
+
* const pagingMetadata = serviceListService.pagingMetadataSignal.get();
|
|
82
|
+
* const hasMore = serviceListService.hasMoreServicesSignal.get();
|
|
83
|
+
*
|
|
84
|
+
* if (isLoading) return <div>Loading services...</div>;
|
|
85
|
+
* if (error) return <div>Error: {error}</div>;
|
|
86
|
+
*
|
|
87
|
+
* return (
|
|
88
|
+
* <div>
|
|
89
|
+
* {services.map(service => (
|
|
90
|
+
* <div key={service._id}>
|
|
91
|
+
* <h3>{service.name}</h3>
|
|
92
|
+
* <p>{service.description}</p>
|
|
93
|
+
* </div>
|
|
94
|
+
* ))}
|
|
95
|
+
* {hasMore && (
|
|
96
|
+
* <button onClick={() => serviceListService.actions.loadMore(10)}>
|
|
97
|
+
* Load More
|
|
98
|
+
* </button>
|
|
99
|
+
* )}
|
|
100
|
+
* {pagingMetadata.hasNext && (
|
|
101
|
+
* <span>More services available</span>
|
|
102
|
+
* )}
|
|
103
|
+
* </div>
|
|
104
|
+
* );
|
|
105
|
+
* }
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
export declare const ServiceListService: import("@wix/services-definitions").ServiceFactory<string & {
|
|
109
|
+
__api: ServiceListServiceAPI;
|
|
110
|
+
__config: ServiceListServiceConfig;
|
|
111
|
+
isServiceDefinition?: boolean;
|
|
112
|
+
} & ServiceListServiceAPI, ServiceListServiceConfig>;
|
|
113
|
+
/**
|
|
114
|
+
* Result types for service list loading operations
|
|
115
|
+
*/
|
|
116
|
+
export type SuccessServiceListServiceConfigResult = {
|
|
117
|
+
type: 'success';
|
|
118
|
+
config: ServiceListServiceConfig;
|
|
119
|
+
};
|
|
120
|
+
export type ErrorServiceListServiceConfigResult = {
|
|
121
|
+
type: 'error';
|
|
122
|
+
error: Error;
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Load service list configuration for Server-Side Rendering (SSR).
|
|
126
|
+
* This function is designed to be called during the build or server-side rendering phase
|
|
127
|
+
* to pre-fetch services data before the React components are hydrated on the client.
|
|
128
|
+
* The returned config includes paging metadata with hasNext flag indicating if more services are available.
|
|
129
|
+
*
|
|
130
|
+
* @param options - Query options following QueryServicesRequest type, or a URL string (to be implemented)
|
|
131
|
+
* @returns A promise that resolves to either a success result with the config or an error result
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```ts
|
|
135
|
+
* // In an Astro page or API route
|
|
136
|
+
* import { loadServiceListServiceInitialData } from '@wix/bookings/services';
|
|
137
|
+
*
|
|
138
|
+
* // Load with query options
|
|
139
|
+
* const serviceListResult = await loadServiceListServiceInitialData({
|
|
140
|
+
* appId: '13d21c63-b5ec-5912-8397-c3a5ddb27a97',
|
|
141
|
+
* pagingMetadata: { limit: 20, offset: 0 },
|
|
142
|
+
* });
|
|
143
|
+
*
|
|
144
|
+
* if (serviceListResult.type === 'error') {
|
|
145
|
+
* console.error('Failed to load services:', serviceListResult.error);
|
|
146
|
+
* return Astro.redirect('/500');
|
|
147
|
+
* }
|
|
148
|
+
*
|
|
149
|
+
* const serviceListConfig = serviceListResult.config;
|
|
150
|
+
*
|
|
151
|
+
* // Check if more services are available
|
|
152
|
+
* if (serviceListConfig.options?.pagingMetadata?.hasNext) {
|
|
153
|
+
* // More services can be loaded
|
|
154
|
+
* }
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
export declare function loadServiceListServiceInitialData(options: QueryServicesRequest): Promise<SuccessServiceListServiceConfigResult | ErrorServiceListServiceConfigResult>;
|