@wix/headless-bookings 0.0.56 → 0.0.58
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/booking/Booking.js +1 -1
- package/cjs/dist/react/booking-form/BookingForm.d.ts +117 -17
- package/cjs/dist/react/booking-form/BookingForm.js +149 -15
- package/cjs/dist/react/core/booking/Booking.d.ts +3 -3
- package/cjs/dist/react/core/booking/Booking.js +2 -2
- package/cjs/dist/react/core/booking-form/BookingForm.d.ts +112 -10
- package/cjs/dist/react/core/booking-form/BookingForm.js +204 -64
- package/cjs/dist/react/core/payment/Payment.d.ts +84 -5
- package/cjs/dist/react/core/payment/Payment.js +102 -4
- package/cjs/dist/react/payment/Payment.d.ts +64 -58
- package/cjs/dist/react/payment/Payment.js +66 -80
- package/cjs/dist/services/booking-form/booking-form.d.ts +22 -13
- package/cjs/dist/services/booking-form/booking-form.js +67 -25
- package/cjs/dist/services/booking-form/utils.d.ts +52 -0
- package/cjs/dist/services/booking-form/utils.js +47 -0
- package/cjs/dist/services/index.d.ts +1 -1
- package/cjs/dist/services/payment/payment.d.ts +4 -4
- package/cjs/dist/services/payment/payment.def.d.ts +4 -4
- package/cjs/dist/services/payment/payment.js +26 -18
- package/dist/react/booking/Booking.js +1 -1
- package/dist/react/booking-form/BookingForm.d.ts +117 -17
- package/dist/react/booking-form/BookingForm.js +149 -15
- package/dist/react/core/booking/Booking.d.ts +3 -3
- package/dist/react/core/booking/Booking.js +2 -2
- package/dist/react/core/booking-form/BookingForm.d.ts +112 -10
- package/dist/react/core/booking-form/BookingForm.js +204 -64
- package/dist/react/core/payment/Payment.d.ts +84 -5
- package/dist/react/core/payment/Payment.js +102 -4
- package/dist/react/payment/Payment.d.ts +64 -58
- package/dist/react/payment/Payment.js +66 -80
- package/dist/services/booking-form/booking-form.d.ts +22 -13
- package/dist/services/booking-form/booking-form.js +67 -25
- package/dist/services/booking-form/utils.d.ts +52 -0
- package/dist/services/booking-form/utils.js +47 -0
- package/dist/services/index.d.ts +1 -1
- package/dist/services/payment/payment.d.ts +4 -4
- package/dist/services/payment/payment.def.d.ts +4 -4
- package/dist/services/payment/payment.js +26 -18
- package/package.json +3 -3
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
import { defineService, implementService } from '@wix/services-definitions';
|
|
11
11
|
import { SignalsServiceDefinition, } from '@wix/services-definitions/core-services/signals';
|
|
12
12
|
import { FormServiceDefinition } from '@wix/headless-forms/services';
|
|
13
|
+
import { BookingServiceDefinition, } from '../booking/booking.js';
|
|
14
|
+
import { hasForm, extractFormIdFromConfig } from './utils.js';
|
|
13
15
|
// ============================================================================
|
|
14
16
|
// Constants
|
|
15
17
|
// ============================================================================
|
|
@@ -18,22 +20,25 @@ import { FormServiceDefinition } from '@wix/headless-forms/services';
|
|
|
18
20
|
* All booking forms must belong to this namespace.
|
|
19
21
|
*/
|
|
20
22
|
export const BOOKING_FORM_NAMESPACE = 'wix.bookings.v2.bookings';
|
|
21
|
-
// ============================================================================
|
|
22
|
-
// Helper Types
|
|
23
|
-
// ============================================================================
|
|
24
|
-
/**
|
|
25
|
-
* Type guard to check if config has formId
|
|
26
|
-
*/
|
|
27
|
-
export function hasFormId(config) {
|
|
28
|
-
return 'formId' in config;
|
|
29
|
-
}
|
|
30
23
|
/**
|
|
31
|
-
*
|
|
24
|
+
* Error thrown when BookingFormService cannot be initialized due to missing configuration.
|
|
25
|
+
* This occurs when:
|
|
26
|
+
* - No config (formId or form) was provided
|
|
27
|
+
* - AND the component is not wrapped with Booking.Root (no BookingService available)
|
|
32
28
|
*/
|
|
33
|
-
export
|
|
34
|
-
|
|
29
|
+
export class BookingFormConfigurationError extends Error {
|
|
30
|
+
constructor(message) {
|
|
31
|
+
super(message ||
|
|
32
|
+
'BookingFormService: Cannot initialize - no formId or form provided in config and no BookingService available. ' +
|
|
33
|
+
'Either provide a formId/form in the config, or wrap with Booking.Root.');
|
|
34
|
+
this.name = 'BookingFormConfigurationError';
|
|
35
|
+
}
|
|
35
36
|
}
|
|
36
37
|
// ============================================================================
|
|
38
|
+
// Re-export utilities
|
|
39
|
+
// ============================================================================
|
|
40
|
+
export { hasFormId, hasForm, extractFormIdFromForm, extractFormIdFromConfig, } from './utils.js';
|
|
41
|
+
// ============================================================================
|
|
37
42
|
// Service Definition
|
|
38
43
|
// ============================================================================
|
|
39
44
|
/**
|
|
@@ -64,20 +69,21 @@ function validateBookingFormNamespace(form) {
|
|
|
64
69
|
}
|
|
65
70
|
}
|
|
66
71
|
/**
|
|
67
|
-
* Extracts the form ID from either config type.
|
|
68
|
-
* @param config The service config
|
|
72
|
+
* Extracts the form ID from either config type or from services.
|
|
73
|
+
* @param config The service config (optional)
|
|
74
|
+
* @param services The list of services to extract formId from if config is not provided
|
|
69
75
|
* @returns The form ID
|
|
70
76
|
*/
|
|
71
|
-
function extractFormId(config) {
|
|
72
|
-
|
|
73
|
-
|
|
77
|
+
function extractFormId(config, services) {
|
|
78
|
+
// Try to extract from config first
|
|
79
|
+
let formId = extractFormIdFromConfig(config);
|
|
80
|
+
// Fallback to extracting from services
|
|
81
|
+
if (!formId) {
|
|
82
|
+
formId = services.find((s) => s.form?._id)?.form?._id;
|
|
74
83
|
}
|
|
75
|
-
// Extract from form object - forms typically have an 'id' or '_id' property
|
|
76
|
-
const form = config.form;
|
|
77
|
-
const formId = form.id ||
|
|
78
|
-
form._id;
|
|
79
84
|
if (!formId) {
|
|
80
|
-
throw new
|
|
85
|
+
throw new BookingFormConfigurationError('BookingFormService: no formId found in config or services. ' +
|
|
86
|
+
'Either provide a formId in the config, or ensure Booking.Root has selected services with a form.');
|
|
81
87
|
}
|
|
82
88
|
return formId;
|
|
83
89
|
}
|
|
@@ -120,14 +126,38 @@ function extractFormId(config) {
|
|
|
120
126
|
export const BookingFormService = implementService.withConfig()(BookingFormServiceDefinition, ({ getService, config }) => {
|
|
121
127
|
const signalsService = getService(SignalsServiceDefinition);
|
|
122
128
|
const formService = getService(FormServiceDefinition);
|
|
129
|
+
// BookingService is optional - may not be available if not wrapped with Booking.Root
|
|
130
|
+
let bookingService = null;
|
|
131
|
+
try {
|
|
132
|
+
bookingService = getService(BookingServiceDefinition);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
// BookingService not available - that's ok if formId was provided explicitly
|
|
136
|
+
bookingService = null;
|
|
137
|
+
}
|
|
138
|
+
const getServices = () => {
|
|
139
|
+
if (!bookingService) {
|
|
140
|
+
return [];
|
|
141
|
+
}
|
|
142
|
+
const serviceSelections = bookingService.serviceSelections.peek();
|
|
143
|
+
return serviceSelections.length
|
|
144
|
+
? serviceSelections.map((s) => s.service)
|
|
145
|
+
: [];
|
|
146
|
+
};
|
|
147
|
+
// Validate that we have either config or bookingService with serviceSelections
|
|
148
|
+
// If neither is available, we can't extract formId and can't initialize the service
|
|
149
|
+
const hasServiceSelections = getServices().length > 0;
|
|
150
|
+
if (!config && (!bookingService || !hasServiceSelections)) {
|
|
151
|
+
throw new BookingFormConfigurationError();
|
|
152
|
+
}
|
|
123
153
|
// Determine if we have a pre-loaded form
|
|
124
|
-
const hasPreloadedForm =
|
|
154
|
+
const hasPreloadedForm = hasForm(config);
|
|
125
155
|
// If form is provided, validate namespace
|
|
126
156
|
if (hasPreloadedForm) {
|
|
127
157
|
validateBookingFormNamespace(config.form);
|
|
128
158
|
}
|
|
129
159
|
// Extract formId from config (either directly or from form object)
|
|
130
|
-
const formIdValue = extractFormId(config);
|
|
160
|
+
const formIdValue = extractFormId(config, getServices());
|
|
131
161
|
// Initialize formSubmission signal (stores form data to be submitted)
|
|
132
162
|
const formSubmission = signalsService.signal(null);
|
|
133
163
|
// Initialize submissionId signal (for future use)
|
|
@@ -135,7 +165,7 @@ export const BookingFormService = implementService.withConfig()(BookingFormServi
|
|
|
135
165
|
// formId signal - readonly
|
|
136
166
|
const formId = signalsService.signal(formIdValue);
|
|
137
167
|
// form signal - contains pre-loaded form if provided
|
|
138
|
-
const form = signalsService.signal(
|
|
168
|
+
const form = signalsService.signal(hasForm(config) ? config.form : null);
|
|
139
169
|
// Internal: Store validate callback (set by core component, not exposed publicly)
|
|
140
170
|
let _validateCallback = null;
|
|
141
171
|
// Internal: Register validate callback (called by core component via closure)
|
|
@@ -155,6 +185,18 @@ export const BookingFormService = implementService.withConfig()(BookingFormServi
|
|
|
155
185
|
}
|
|
156
186
|
return _validateCallback();
|
|
157
187
|
};
|
|
188
|
+
// Auto-sync formValues to BookingService.formSubmission (client-side only)
|
|
189
|
+
// This keeps Booking.Data.formSubmission updated as the user types
|
|
190
|
+
// and ensures the book action gets the latest form values
|
|
191
|
+
// Only set up sync if BookingService is available
|
|
192
|
+
if (bookingService) {
|
|
193
|
+
signalsService.effect(() => {
|
|
194
|
+
const formValues = formService.formValuesSignal.get();
|
|
195
|
+
if (formValues && Object.keys(formValues).length > 0) {
|
|
196
|
+
bookingService.actions.setFormSubmission(formValues);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
}
|
|
158
200
|
// Public API (what's exposed in BookingFormServiceAPI interface)
|
|
159
201
|
const publicApi = {
|
|
160
202
|
formValues: formService.formValuesSignal,
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for BookingForm
|
|
3
|
+
*
|
|
4
|
+
* Note: This file should not import from booking-form.ts to avoid circular dependencies.
|
|
5
|
+
* Type guards use generic types that will be compatible with BookingFormServiceConfig.
|
|
6
|
+
*/
|
|
7
|
+
import { forms } from '@wix/forms';
|
|
8
|
+
/**
|
|
9
|
+
* Type guard to check if config has formId
|
|
10
|
+
*/
|
|
11
|
+
export declare function hasFormId<T extends {
|
|
12
|
+
formId: string;
|
|
13
|
+
serviceIds?: string[];
|
|
14
|
+
} | {
|
|
15
|
+
form: forms.Form;
|
|
16
|
+
}>(config: T | undefined): config is T & {
|
|
17
|
+
formId: string;
|
|
18
|
+
serviceIds?: string[];
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Type guard to check if config has pre-loaded form
|
|
22
|
+
*/
|
|
23
|
+
export declare function hasForm<T extends {
|
|
24
|
+
formId: string;
|
|
25
|
+
serviceIds?: string[];
|
|
26
|
+
} | {
|
|
27
|
+
form: forms.Form;
|
|
28
|
+
}>(config: T | undefined): config is T & {
|
|
29
|
+
form: forms.Form;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Extracts the form ID from a form object.
|
|
33
|
+
* @param form The form object to extract ID from
|
|
34
|
+
* @returns The form ID or undefined if not found
|
|
35
|
+
*/
|
|
36
|
+
export declare function extractFormIdFromForm(form: forms.Form): string | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Configuration object that may contain formId or form.
|
|
39
|
+
* Used by extractFormIdFromConfig.
|
|
40
|
+
*/
|
|
41
|
+
export type FormIdConfig = {
|
|
42
|
+
formId: string;
|
|
43
|
+
serviceIds?: string[];
|
|
44
|
+
} | {
|
|
45
|
+
form: forms.Form;
|
|
46
|
+
} | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Extracts the form ID from a config object (either formId directly or from form object).
|
|
49
|
+
* @param config The config object containing either formId or form
|
|
50
|
+
* @returns The form ID or undefined if not found/extractable
|
|
51
|
+
*/
|
|
52
|
+
export declare function extractFormIdFromConfig(config: FormIdConfig): string | undefined;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for BookingForm
|
|
3
|
+
*
|
|
4
|
+
* Note: This file should not import from booking-form.ts to avoid circular dependencies.
|
|
5
|
+
* Type guards use generic types that will be compatible with BookingFormServiceConfig.
|
|
6
|
+
*/
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Type Guards
|
|
9
|
+
// ============================================================================
|
|
10
|
+
/**
|
|
11
|
+
* Type guard to check if config has formId
|
|
12
|
+
*/
|
|
13
|
+
export function hasFormId(config) {
|
|
14
|
+
return config != null && 'formId' in config;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Type guard to check if config has pre-loaded form
|
|
18
|
+
*/
|
|
19
|
+
export function hasForm(config) {
|
|
20
|
+
return config != null && 'form' in config;
|
|
21
|
+
}
|
|
22
|
+
// ============================================================================
|
|
23
|
+
// Form ID Extraction
|
|
24
|
+
// ============================================================================
|
|
25
|
+
/**
|
|
26
|
+
* Extracts the form ID from a form object.
|
|
27
|
+
* @param form The form object to extract ID from
|
|
28
|
+
* @returns The form ID or undefined if not found
|
|
29
|
+
*/
|
|
30
|
+
export function extractFormIdFromForm(form) {
|
|
31
|
+
return (form.id ||
|
|
32
|
+
form._id);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Extracts the form ID from a config object (either formId directly or from form object).
|
|
36
|
+
* @param config The config object containing either formId or form
|
|
37
|
+
* @returns The form ID or undefined if not found/extractable
|
|
38
|
+
*/
|
|
39
|
+
export function extractFormIdFromConfig(config) {
|
|
40
|
+
if (hasFormId(config)) {
|
|
41
|
+
return config.formId;
|
|
42
|
+
}
|
|
43
|
+
if (hasForm(config)) {
|
|
44
|
+
return extractFormIdFromForm(config.form);
|
|
45
|
+
}
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
package/dist/services/index.d.ts
CHANGED
|
@@ -8,6 +8,6 @@ export { TimeSlotListService, TimeSlotListServiceDefinition, TimeSlotService, Ti
|
|
|
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';
|
|
11
|
-
export { PaymentService, PaymentServiceDefinition, type PaymentServiceAPI, type PaymentServiceConfig, type PaymentDetails, type
|
|
11
|
+
export { PaymentService, PaymentServiceDefinition, type PaymentServiceAPI, type PaymentServiceConfig, type PaymentDetails, type PricingServiceSelection, 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
13
|
export { StaffMemberListService, StaffMemberListServiceDefinition, loadStaffMemberListServiceInitialData, staffMemberListServiceBinding, type StaffMemberListServiceAPI, type StaffMemberListServiceConfig, type StaffMemberListActions, type StaffMemberData, type LoadStaffMemberListServiceResult, } from './staff-member-list/staff-member-list.js';
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Handles calculating total prices, taxes, discounts, and deposit information
|
|
4
4
|
* Supports two modes: SSR (config with pre-fetched data) and lazy loading (reactive)
|
|
5
5
|
*/
|
|
6
|
-
import { type PaymentServiceConfig, type PaymentServiceInternalConfig, type
|
|
7
|
-
export { PaymentServiceDefinition, type PaymentServiceConfig, type PaymentDetails, type LineItemAdditionalInfo, type
|
|
6
|
+
import { type PaymentServiceConfig, type PaymentServiceInternalConfig, type PricingServiceSelection } from './payment.def.js';
|
|
7
|
+
export { PaymentServiceDefinition, type PaymentServiceConfig, type PaymentDetails, type LineItemAdditionalInfo, type PricingServiceSelection, } from './payment.def.js';
|
|
8
8
|
export type { PaymentServiceAPI, PaymentServiceInternalConfig, } from './payment.def.js';
|
|
9
9
|
export declare const PaymentService: import("@wix/services-definitions").ServiceFactory<string & {
|
|
10
10
|
__api: import("./payment.def.js").PaymentServiceAPI;
|
|
@@ -23,10 +23,10 @@ export type ErrorPaymentConfigResult = {
|
|
|
23
23
|
* Load payment configuration for Server-Side Rendering (SSR).
|
|
24
24
|
* Calls the pricing APIs and returns pre-calculated payment details.
|
|
25
25
|
*
|
|
26
|
-
* @param params.
|
|
26
|
+
* @param params.pricingServiceSelections - Pricing service selections for calculation
|
|
27
27
|
* @param params.numberOfParticipants - Number of participants (default: 1)
|
|
28
28
|
*/
|
|
29
29
|
export declare function loadPaymentConfig(params: {
|
|
30
|
-
|
|
30
|
+
pricingServiceSelections: PricingServiceSelection[];
|
|
31
31
|
numberOfParticipants?: number;
|
|
32
32
|
}): Promise<SuccessPaymentConfigResult | ErrorPaymentConfigResult>;
|
|
@@ -30,9 +30,9 @@ export interface PaymentDetails {
|
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
|
-
* Input for calculating payment for a
|
|
33
|
+
* Input for calculating payment for a booking service
|
|
34
34
|
*/
|
|
35
|
-
export interface
|
|
35
|
+
export interface PricingServiceSelection {
|
|
36
36
|
service: Service;
|
|
37
37
|
/** Optional line item ID. If not provided, one will be generated. */
|
|
38
38
|
lineItemId?: string;
|
|
@@ -50,8 +50,8 @@ export interface PaymentServiceConfig {
|
|
|
50
50
|
* Not exposed publicly - Core merges this with PaymentServiceConfig
|
|
51
51
|
*/
|
|
52
52
|
export interface PaymentServiceInternalConfig extends PaymentServiceConfig {
|
|
53
|
-
/**
|
|
54
|
-
|
|
53
|
+
/** Booking services for lazy loading (internal use) */
|
|
54
|
+
pricingServiceSelections?: PricingServiceSelection[];
|
|
55
55
|
/** Number of participants for lazy loading (internal use) */
|
|
56
56
|
numberOfParticipants?: number;
|
|
57
57
|
}
|
|
@@ -60,11 +60,11 @@ function buildLineItem(service, numberOfParticipants, lineItemId) {
|
|
|
60
60
|
paymentOption,
|
|
61
61
|
};
|
|
62
62
|
}
|
|
63
|
-
async function calculatePaymentDetails(
|
|
64
|
-
// Ensure all
|
|
65
|
-
const data =
|
|
66
|
-
...
|
|
67
|
-
lineItemId:
|
|
63
|
+
async function calculatePaymentDetails(pricingServiceSelections, numberOfParticipants) {
|
|
64
|
+
// Ensure all booking services have a lineItemId
|
|
65
|
+
const data = pricingServiceSelections.map((selection) => ({
|
|
66
|
+
...selection,
|
|
67
|
+
lineItemId: selection.lineItemId || generateLineItemId(),
|
|
68
68
|
}));
|
|
69
69
|
const lineItems = data.map((item) => buildLineItem(item.service, numberOfParticipants, item.lineItemId));
|
|
70
70
|
const response = await calculateTotals({
|
|
@@ -96,15 +96,15 @@ export const PaymentService = implementService.withConfig()(PaymentServiceDefini
|
|
|
96
96
|
const isLoadingSignal = signalsService.signal(false);
|
|
97
97
|
const errorSignal = signalsService.signal(null);
|
|
98
98
|
// Internal calculate function
|
|
99
|
-
const calculate = async (
|
|
100
|
-
if (!
|
|
99
|
+
const calculate = async (pricingServiceSelections, numberOfParticipants) => {
|
|
100
|
+
if (!pricingServiceSelections.length) {
|
|
101
101
|
paymentDetailsSignal.set(null);
|
|
102
102
|
return;
|
|
103
103
|
}
|
|
104
104
|
isLoadingSignal.set(true);
|
|
105
105
|
errorSignal.set(null);
|
|
106
106
|
try {
|
|
107
|
-
const paymentDetails = await calculatePaymentDetails(
|
|
107
|
+
const paymentDetails = await calculatePaymentDetails(pricingServiceSelections, numberOfParticipants);
|
|
108
108
|
paymentDetailsSignal.set(paymentDetails);
|
|
109
109
|
}
|
|
110
110
|
catch (error) {
|
|
@@ -122,22 +122,30 @@ export const PaymentService = implementService.withConfig()(PaymentServiceDefini
|
|
|
122
122
|
if (config.paymentDetails) {
|
|
123
123
|
// No-op - data is pre-fetched
|
|
124
124
|
}
|
|
125
|
-
// Mode 2: Lazy loading -
|
|
126
|
-
else if (config.
|
|
127
|
-
void calculate(config.
|
|
125
|
+
// Mode 2: Lazy loading - pricingServiceSelections provided via internal config
|
|
126
|
+
else if (config.pricingServiceSelections?.length) {
|
|
127
|
+
void calculate(config.pricingServiceSelections, config.numberOfParticipants ?? 1);
|
|
128
128
|
}
|
|
129
129
|
// Mode 3: Reactive - observe BookingService signals (client-side only)
|
|
130
130
|
else if (typeof window !== 'undefined' && bookingService) {
|
|
131
|
-
|
|
131
|
+
// Computed signal that only changes when services change (not participants)
|
|
132
|
+
const servicesKey = signalsService.computed(() => {
|
|
132
133
|
const selections = bookingService?.serviceSelections.get() || [];
|
|
134
|
+
return selections.map((s) => s.service._id).join(',');
|
|
135
|
+
});
|
|
136
|
+
signalsService.effect(() => {
|
|
137
|
+
// Subscribe to servicesKey to trigger effect only when services change
|
|
138
|
+
servicesKey.get();
|
|
139
|
+
// Read current selections without subscribing (peek)
|
|
140
|
+
const selections = bookingService?.serviceSelections.peek() || [];
|
|
133
141
|
// For single service mode, take the first selection
|
|
134
142
|
const firstSelection = selections[0];
|
|
135
143
|
const numParticipants = firstSelection?.totalParticipants || 1;
|
|
136
|
-
const
|
|
144
|
+
const pricingServiceSelections = selections.map((selection) => ({
|
|
137
145
|
service: selection.service,
|
|
138
146
|
lineItemId: selection.instanceId,
|
|
139
147
|
}));
|
|
140
|
-
void calculate(
|
|
148
|
+
void calculate(pricingServiceSelections, numParticipants);
|
|
141
149
|
});
|
|
142
150
|
}
|
|
143
151
|
return {
|
|
@@ -150,19 +158,19 @@ export const PaymentService = implementService.withConfig()(PaymentServiceDefini
|
|
|
150
158
|
* Load payment configuration for Server-Side Rendering (SSR).
|
|
151
159
|
* Calls the pricing APIs and returns pre-calculated payment details.
|
|
152
160
|
*
|
|
153
|
-
* @param params.
|
|
161
|
+
* @param params.pricingServiceSelections - Pricing service selections for calculation
|
|
154
162
|
* @param params.numberOfParticipants - Number of participants (default: 1)
|
|
155
163
|
*/
|
|
156
164
|
export async function loadPaymentConfig(params) {
|
|
157
165
|
try {
|
|
158
|
-
const {
|
|
159
|
-
if (!
|
|
166
|
+
const { pricingServiceSelections, numberOfParticipants = 1 } = params;
|
|
167
|
+
if (!pricingServiceSelections.length) {
|
|
160
168
|
return {
|
|
161
169
|
type: 'success',
|
|
162
170
|
config: { paymentDetails: undefined },
|
|
163
171
|
};
|
|
164
172
|
}
|
|
165
|
-
const paymentDetails = await calculatePaymentDetails(
|
|
173
|
+
const paymentDetails = await calculatePaymentDetails(pricingServiceSelections, numberOfParticipants);
|
|
166
174
|
return {
|
|
167
175
|
type: 'success',
|
|
168
176
|
config: { paymentDetails },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/headless-bookings",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.58",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"@wix/auto_sdk_bookings_bookings": "^1.0.103",
|
|
37
37
|
"@wix/auto_sdk_bookings_event-time-slots": "^1.0.64",
|
|
38
38
|
"@wix/auto_sdk_ecom_checkout": "^1.0.104",
|
|
39
|
-
"@wix/form-public": "
|
|
39
|
+
"@wix/form-public": "https://cdn.dev.wixpress.com/@wix/form-public/5e033ab77775b2277d596c4663a1446228270e3fc9afa7b2b85c4a94.tar.gz",
|
|
40
40
|
"@wix/headless-forms": "0.0.20",
|
|
41
41
|
"@wix/headless-media": "0.0.18",
|
|
42
42
|
"@wix/headless-utils": "0.0.8",
|
|
@@ -72,5 +72,5 @@
|
|
|
72
72
|
"groupId": "com.wixpress.headless-components"
|
|
73
73
|
}
|
|
74
74
|
},
|
|
75
|
-
"falconPackageHash": "
|
|
75
|
+
"falconPackageHash": "ccd30f51c7b5e50deedb808077fe5dfaebe97ef4f66da71d4f246455"
|
|
76
76
|
}
|