@wix/headless-bookings 0.0.29 → 0.0.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/dist/react/core/payment/Payment.d.ts +193 -0
- package/cjs/dist/react/core/payment/Payment.js +202 -0
- package/cjs/dist/react/core/service/ServiceMediaCover.d.ts +43 -0
- package/cjs/dist/react/core/service/ServiceMediaCover.js +34 -0
- package/cjs/dist/react/core/service/ServiceMediaGallery.d.ts +50 -0
- package/cjs/dist/react/core/service/ServiceMediaGallery.js +37 -0
- package/cjs/dist/react/core/service/ServiceMediaMain.d.ts +42 -0
- package/cjs/dist/react/core/service/ServiceMediaMain.js +33 -0
- package/cjs/dist/react/index.d.ts +3 -0
- package/cjs/dist/react/index.js +3 -0
- package/cjs/dist/react/payment/Payment.d.ts +342 -0
- package/cjs/dist/react/payment/Payment.js +294 -0
- package/cjs/dist/react/payment/PaymentLineItem.d.ts +144 -0
- package/cjs/dist/react/payment/PaymentLineItem.js +141 -0
- package/cjs/dist/react/service/Service.d.ts +7 -154
- package/cjs/dist/react/service/Service.js +8 -148
- package/cjs/dist/react/service/ServiceMedia.d.ts +191 -0
- package/cjs/dist/react/service/ServiceMedia.js +175 -0
- package/cjs/dist/services/index.d.ts +1 -0
- package/cjs/dist/services/index.js +1 -0
- package/cjs/dist/services/payment/payment.d.ts +32 -0
- package/cjs/dist/services/payment/payment.def.d.ts +66 -0
- package/cjs/dist/services/payment/payment.def.js +9 -0
- package/cjs/dist/services/payment/payment.js +167 -0
- package/cjs/dist/utils/money.d.ts +11 -0
- package/cjs/dist/utils/money.js +16 -0
- package/dist/react/core/payment/Payment.d.ts +193 -0
- package/dist/react/core/payment/Payment.js +202 -0
- package/dist/react/core/service/ServiceMediaCover.d.ts +43 -0
- package/dist/react/core/service/ServiceMediaCover.js +34 -0
- package/dist/react/core/service/ServiceMediaGallery.d.ts +50 -0
- package/dist/react/core/service/ServiceMediaGallery.js +37 -0
- package/dist/react/core/service/ServiceMediaMain.d.ts +42 -0
- package/dist/react/core/service/ServiceMediaMain.js +33 -0
- package/dist/react/index.d.ts +3 -0
- package/dist/react/index.js +3 -0
- package/dist/react/payment/Payment.d.ts +342 -0
- package/dist/react/payment/Payment.js +294 -0
- package/dist/react/payment/PaymentLineItem.d.ts +144 -0
- package/dist/react/payment/PaymentLineItem.js +141 -0
- package/dist/react/service/Service.d.ts +7 -154
- package/dist/react/service/Service.js +8 -148
- package/dist/react/service/ServiceMedia.d.ts +191 -0
- package/dist/react/service/ServiceMedia.js +175 -0
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +1 -0
- package/dist/services/payment/payment.d.ts +32 -0
- package/dist/services/payment/payment.def.d.ts +66 -0
- package/dist/services/payment/payment.def.js +9 -0
- package/dist/services/payment/payment.js +167 -0
- package/dist/utils/money.d.ts +11 -0
- package/dist/utils/money.js +16 -0
- package/package.json +2 -2
package/cjs/dist/utils/money.js
CHANGED
|
@@ -32,3 +32,19 @@ export function convertToMoneyData(sdkMoney) {
|
|
|
32
32
|
}
|
|
33
33
|
return null;
|
|
34
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Converts ecom MultiCurrencyPrice format to MoneyData format
|
|
37
|
+
* MultiCurrencyPrice uses 'amount' as string, while MoneyData uses 'amount' as number
|
|
38
|
+
*
|
|
39
|
+
* @param price - The MultiCurrencyPrice object with amount as string
|
|
40
|
+
* @param currency - The currency code (from response level)
|
|
41
|
+
* @returns MoneyData object or null if conversion fails
|
|
42
|
+
*/
|
|
43
|
+
export function convertMultiCurrencyPriceToMoneyData(price, currency) {
|
|
44
|
+
if (!price?.amount)
|
|
45
|
+
return null;
|
|
46
|
+
const parsed = parseFloat(price.amount);
|
|
47
|
+
if (isNaN(parsed) || parsed < 0)
|
|
48
|
+
return null;
|
|
49
|
+
return { amount: parsed, currency };
|
|
50
|
+
}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core Payment Components
|
|
3
|
+
* Provides low-level access to PaymentService via render props
|
|
4
|
+
* Note: Currently supports single service only
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { type PaymentServiceConfig, type PaymentDetails, type SlotService } from '../../../services/payment/payment.js';
|
|
8
|
+
import type { MoneyData } from '@wix/headless-components/react';
|
|
9
|
+
/**
|
|
10
|
+
* Props for Payment.Root component
|
|
11
|
+
*/
|
|
12
|
+
export interface RootProps {
|
|
13
|
+
children: React.ReactNode | ((props: {
|
|
14
|
+
isLoading: boolean;
|
|
15
|
+
hasError: boolean;
|
|
16
|
+
}) => React.ReactNode);
|
|
17
|
+
/** Service config - SSR only (paymentDetails) */
|
|
18
|
+
paymentServiceConfig?: PaymentServiceConfig;
|
|
19
|
+
/** Slot services for lazy loading (triggers API call) */
|
|
20
|
+
slotServices?: SlotService[];
|
|
21
|
+
/** Number of participants for lazy loading */
|
|
22
|
+
numberOfParticipants?: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Root component that provides payment context.
|
|
26
|
+
* Supports 3 modes:
|
|
27
|
+
* 1. SSR: paymentServiceConfig.paymentDetails - pre-fetched data
|
|
28
|
+
* 2. Lazy loading: slotServices + numberOfParticipants props - calls API on init
|
|
29
|
+
* 3. Reactive: no config/props - reads from BookingService signals
|
|
30
|
+
*
|
|
31
|
+
* @component
|
|
32
|
+
* @example
|
|
33
|
+
* ```tsx
|
|
34
|
+
* // SSR mode
|
|
35
|
+
* <Payment.Root paymentServiceConfig={{ paymentDetails }}>
|
|
36
|
+
* <Payment.Summary />
|
|
37
|
+
* </Payment.Root>
|
|
38
|
+
*
|
|
39
|
+
* // Lazy loading mode
|
|
40
|
+
* <Payment.Root slotServices={[...]} numberOfParticipants={2}>
|
|
41
|
+
* {({ isLoading }) => isLoading ? <div>Loading...</div> : <Payment.Summary />}
|
|
42
|
+
* </Payment.Root>
|
|
43
|
+
*
|
|
44
|
+
* // Reactive mode
|
|
45
|
+
* <Payment.Root>
|
|
46
|
+
* <Payment.Summary />
|
|
47
|
+
* </Payment.Root>
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function Root(props: RootProps): React.ReactNode;
|
|
51
|
+
/**
|
|
52
|
+
* Props for Payment render prop component
|
|
53
|
+
*/
|
|
54
|
+
export interface PaymentProps {
|
|
55
|
+
children: (data: {
|
|
56
|
+
paymentDetails: PaymentDetails | null;
|
|
57
|
+
isLoading: boolean;
|
|
58
|
+
error: string | null;
|
|
59
|
+
}) => React.ReactNode;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Core component that provides access to full payment details via render props.
|
|
63
|
+
*
|
|
64
|
+
* @component
|
|
65
|
+
* @example
|
|
66
|
+
* ```tsx
|
|
67
|
+
* <Payment.Payment>
|
|
68
|
+
* {({ paymentDetails, isLoading, error }) => (
|
|
69
|
+
* isLoading ? <div>Loading...</div> : <div>{JSON.stringify(paymentDetails)}</div>
|
|
70
|
+
* )}
|
|
71
|
+
* </Payment.Payment>
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export declare function Payment(props: PaymentProps): React.ReactNode;
|
|
75
|
+
/**
|
|
76
|
+
* Props for Summary render prop component
|
|
77
|
+
*/
|
|
78
|
+
export interface SummaryProps {
|
|
79
|
+
children: (data: {
|
|
80
|
+
subtotal: MoneyData | null;
|
|
81
|
+
total: MoneyData | null;
|
|
82
|
+
currency: string;
|
|
83
|
+
tax: MoneyData | null;
|
|
84
|
+
hasTax: boolean;
|
|
85
|
+
discount: MoneyData | null;
|
|
86
|
+
hasDiscount: boolean;
|
|
87
|
+
payNow: MoneyData | null;
|
|
88
|
+
payLater: MoneyData | null;
|
|
89
|
+
isDeposit: boolean;
|
|
90
|
+
}) => React.ReactNode;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Core component that provides access to payment summary totals via render props.
|
|
94
|
+
* Returns all pricing totals with MoneyData format for the Money component.
|
|
95
|
+
* Use data-attributes for conditional visibility via CSS.
|
|
96
|
+
*
|
|
97
|
+
* @component
|
|
98
|
+
* @example
|
|
99
|
+
* ```tsx
|
|
100
|
+
* <Payment.Summary>
|
|
101
|
+
* {({ subtotal, tax, total, hasTax, hasDiscount, discount, isDeposit, payNow }) => (
|
|
102
|
+
* <div>
|
|
103
|
+
* <div>Subtotal: <Money money={subtotal} /></div>
|
|
104
|
+
* <div data-has-tax={hasTax}>Tax: <Money money={tax} /></div>
|
|
105
|
+
* <div data-has-discount={hasDiscount}>Discount: <Money money={discount} /></div>
|
|
106
|
+
* <div>Total: <Money money={total} /></div>
|
|
107
|
+
* <div data-has-deposit={isDeposit}>Pay Now: <Money money={payNow} /></div>
|
|
108
|
+
* </div>
|
|
109
|
+
* )}
|
|
110
|
+
* </Payment.Summary>
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
export declare function Summary(props: SummaryProps): React.ReactNode;
|
|
114
|
+
import type { CalculatedLineItem as ApiCalculatedLineItem } from '@wix/auto_sdk_ecom_totals-calculator';
|
|
115
|
+
import type { LineItemAdditionalInfo } from '../../../services/payment/payment.js';
|
|
116
|
+
/**
|
|
117
|
+
* Combined line item with SDK data and additional computed info
|
|
118
|
+
*/
|
|
119
|
+
export interface CombinedLineItem {
|
|
120
|
+
/** SDK line item data */
|
|
121
|
+
sdkLineItem: ApiCalculatedLineItem;
|
|
122
|
+
/** Additional computed info */
|
|
123
|
+
additionalInfo: LineItemAdditionalInfo | undefined;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Props for LineItems render prop component
|
|
127
|
+
*/
|
|
128
|
+
export interface LineItemsProps {
|
|
129
|
+
children: (data: {
|
|
130
|
+
lineItems: CombinedLineItem[];
|
|
131
|
+
hasLineItems: boolean;
|
|
132
|
+
currency: string;
|
|
133
|
+
}) => React.ReactNode;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Core component that provides access to calculated line items via render props.
|
|
137
|
+
* Combines SDK line items with additional computed info.
|
|
138
|
+
* Note: Currently supports single service only (always 1 line item).
|
|
139
|
+
*
|
|
140
|
+
* @component
|
|
141
|
+
* @example
|
|
142
|
+
* ```tsx
|
|
143
|
+
* <Payment.LineItems>
|
|
144
|
+
* {({ lineItems, hasLineItems, currency }) => (
|
|
145
|
+
* <ul data-has-items={hasLineItems}>
|
|
146
|
+
* {lineItems.map((item) => (
|
|
147
|
+
* <Payment.LineItem key={item.sdkLineItem.lineItemId} lineItem={item} currency={currency}>
|
|
148
|
+
* {({ totalPriceAfterTaxAndDiscount }) => (
|
|
149
|
+
* <li><Money money={totalPriceAfterTaxAndDiscount} /></li>
|
|
150
|
+
* )}
|
|
151
|
+
* </Payment.LineItem>
|
|
152
|
+
* ))}
|
|
153
|
+
* </ul>
|
|
154
|
+
* )}
|
|
155
|
+
* </Payment.LineItems>
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
export declare function LineItems(props: LineItemsProps): React.ReactNode;
|
|
159
|
+
/**
|
|
160
|
+
* Props for LineItem render prop component
|
|
161
|
+
*/
|
|
162
|
+
export interface LineItemProps {
|
|
163
|
+
lineItem: CombinedLineItem;
|
|
164
|
+
currency: string;
|
|
165
|
+
children: (data: {
|
|
166
|
+
totalPrice: MoneyData | null;
|
|
167
|
+
subtotal: MoneyData | null;
|
|
168
|
+
tax: MoneyData | null;
|
|
169
|
+
discount: MoneyData | null;
|
|
170
|
+
deposit: MoneyData | null;
|
|
171
|
+
priceText: string | null;
|
|
172
|
+
}) => React.ReactNode;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Core component that provides access to a single line item via render props.
|
|
176
|
+
* Use data-attributes for conditional visibility via CSS.
|
|
177
|
+
*
|
|
178
|
+
* @component
|
|
179
|
+
* @example
|
|
180
|
+
* ```tsx
|
|
181
|
+
* <Payment.LineItem lineItem={item} currency="USD">
|
|
182
|
+
* {({ totalPrice, subtotal, tax, discount, deposit, priceText }) => (
|
|
183
|
+
* <div>
|
|
184
|
+
* <span><Money money={totalPrice} /></span>
|
|
185
|
+
* <span data-has-discount={!!discount?.amount}><Money money={discount} /></span>
|
|
186
|
+
* <span data-has-deposit={!!deposit?.amount}><Money money={deposit} /></span>
|
|
187
|
+
* <span data-has-price-text={!!priceText}>{priceText}</span>
|
|
188
|
+
* </div>
|
|
189
|
+
* )}
|
|
190
|
+
* </Payment.LineItem>
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
|
+
export declare function LineItem(props: LineItemProps): React.ReactNode;
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { WixServices, useService } from '@wix/services-manager-react';
|
|
3
|
+
import { createServicesMap } from '@wix/services-manager';
|
|
4
|
+
import { PaymentServiceDefinition, PaymentService, } from '../../../services/payment/payment.js';
|
|
5
|
+
import { convertMultiCurrencyPriceToMoneyData } from '../../../utils/money.js';
|
|
6
|
+
/**
|
|
7
|
+
* Internal content component that reads from service
|
|
8
|
+
*/
|
|
9
|
+
function RootContent({ children, }) {
|
|
10
|
+
const paymentService = useService(PaymentServiceDefinition);
|
|
11
|
+
const isLoading = paymentService.isLoadingSignal.get();
|
|
12
|
+
const error = paymentService.errorSignal.get();
|
|
13
|
+
const hasError = !!error;
|
|
14
|
+
if (typeof children === 'function') {
|
|
15
|
+
return children({ isLoading, hasError });
|
|
16
|
+
}
|
|
17
|
+
return children;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Root component that provides payment context.
|
|
21
|
+
* Supports 3 modes:
|
|
22
|
+
* 1. SSR: paymentServiceConfig.paymentDetails - pre-fetched data
|
|
23
|
+
* 2. Lazy loading: slotServices + numberOfParticipants props - calls API on init
|
|
24
|
+
* 3. Reactive: no config/props - reads from BookingService signals
|
|
25
|
+
*
|
|
26
|
+
* @component
|
|
27
|
+
* @example
|
|
28
|
+
* ```tsx
|
|
29
|
+
* // SSR mode
|
|
30
|
+
* <Payment.Root paymentServiceConfig={{ paymentDetails }}>
|
|
31
|
+
* <Payment.Summary />
|
|
32
|
+
* </Payment.Root>
|
|
33
|
+
*
|
|
34
|
+
* // Lazy loading mode
|
|
35
|
+
* <Payment.Root slotServices={[...]} numberOfParticipants={2}>
|
|
36
|
+
* {({ isLoading }) => isLoading ? <div>Loading...</div> : <Payment.Summary />}
|
|
37
|
+
* </Payment.Root>
|
|
38
|
+
*
|
|
39
|
+
* // Reactive mode
|
|
40
|
+
* <Payment.Root>
|
|
41
|
+
* <Payment.Summary />
|
|
42
|
+
* </Payment.Root>
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export function Root(props) {
|
|
46
|
+
const { children, paymentServiceConfig = {}, slotServices, numberOfParticipants } = props;
|
|
47
|
+
// Merge public config with lazy loading props into internal config
|
|
48
|
+
const internalConfig = {
|
|
49
|
+
...paymentServiceConfig,
|
|
50
|
+
slotServices,
|
|
51
|
+
numberOfParticipants,
|
|
52
|
+
};
|
|
53
|
+
return (_jsx(WixServices, { servicesMap: createServicesMap().addService(PaymentServiceDefinition, PaymentService, internalConfig), children: _jsx(RootContent, { children: children }) }));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Core component that provides access to full payment details via render props.
|
|
57
|
+
*
|
|
58
|
+
* @component
|
|
59
|
+
* @example
|
|
60
|
+
* ```tsx
|
|
61
|
+
* <Payment.Payment>
|
|
62
|
+
* {({ paymentDetails, isLoading, error }) => (
|
|
63
|
+
* isLoading ? <div>Loading...</div> : <div>{JSON.stringify(paymentDetails)}</div>
|
|
64
|
+
* )}
|
|
65
|
+
* </Payment.Payment>
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export function Payment(props) {
|
|
69
|
+
const paymentService = useService(PaymentServiceDefinition);
|
|
70
|
+
const paymentDetails = paymentService.paymentDetailsSignal.get();
|
|
71
|
+
const isLoading = paymentService.isLoadingSignal.get();
|
|
72
|
+
const error = paymentService.errorSignal.get();
|
|
73
|
+
return props.children({ paymentDetails, isLoading, error });
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Core component that provides access to payment summary totals via render props.
|
|
77
|
+
* Returns all pricing totals with MoneyData format for the Money component.
|
|
78
|
+
* Use data-attributes for conditional visibility via CSS.
|
|
79
|
+
*
|
|
80
|
+
* @component
|
|
81
|
+
* @example
|
|
82
|
+
* ```tsx
|
|
83
|
+
* <Payment.Summary>
|
|
84
|
+
* {({ subtotal, tax, total, hasTax, hasDiscount, discount, isDeposit, payNow }) => (
|
|
85
|
+
* <div>
|
|
86
|
+
* <div>Subtotal: <Money money={subtotal} /></div>
|
|
87
|
+
* <div data-has-tax={hasTax}>Tax: <Money money={tax} /></div>
|
|
88
|
+
* <div data-has-discount={hasDiscount}>Discount: <Money money={discount} /></div>
|
|
89
|
+
* <div>Total: <Money money={total} /></div>
|
|
90
|
+
* <div data-has-deposit={isDeposit}>Pay Now: <Money money={payNow} /></div>
|
|
91
|
+
* </div>
|
|
92
|
+
* )}
|
|
93
|
+
* </Payment.Summary>
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export function Summary(props) {
|
|
97
|
+
const paymentService = useService(PaymentServiceDefinition);
|
|
98
|
+
const paymentDetails = paymentService.paymentDetailsSignal.get();
|
|
99
|
+
const currency = paymentDetails?.response?.currency || 'USD';
|
|
100
|
+
const priceSummary = paymentDetails?.response?.priceSummary;
|
|
101
|
+
// Always present
|
|
102
|
+
const subtotal = convertMultiCurrencyPriceToMoneyData(priceSummary?.subtotal, currency);
|
|
103
|
+
const total = convertMultiCurrencyPriceToMoneyData(priceSummary?.total, currency);
|
|
104
|
+
// May or may not exist
|
|
105
|
+
const tax = convertMultiCurrencyPriceToMoneyData(priceSummary?.tax, currency);
|
|
106
|
+
const hasTax = tax !== null && tax.amount > 0;
|
|
107
|
+
const discount = convertMultiCurrencyPriceToMoneyData(priceSummary?.discount, currency);
|
|
108
|
+
const hasDiscount = discount !== null && discount.amount > 0;
|
|
109
|
+
// Deposit scenarios only
|
|
110
|
+
const payNow = convertMultiCurrencyPriceToMoneyData(paymentDetails?.response?.payNow?.total, currency);
|
|
111
|
+
const payLater = convertMultiCurrencyPriceToMoneyData(paymentDetails?.response?.payLater?.total, currency);
|
|
112
|
+
const isDeposit = payNow !== null && total !== null && payNow.amount < total.amount;
|
|
113
|
+
return props.children({
|
|
114
|
+
subtotal,
|
|
115
|
+
total,
|
|
116
|
+
currency,
|
|
117
|
+
tax,
|
|
118
|
+
hasTax,
|
|
119
|
+
discount,
|
|
120
|
+
hasDiscount,
|
|
121
|
+
payNow,
|
|
122
|
+
payLater,
|
|
123
|
+
isDeposit,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Core component that provides access to calculated line items via render props.
|
|
128
|
+
* Combines SDK line items with additional computed info.
|
|
129
|
+
* Note: Currently supports single service only (always 1 line item).
|
|
130
|
+
*
|
|
131
|
+
* @component
|
|
132
|
+
* @example
|
|
133
|
+
* ```tsx
|
|
134
|
+
* <Payment.LineItems>
|
|
135
|
+
* {({ lineItems, hasLineItems, currency }) => (
|
|
136
|
+
* <ul data-has-items={hasLineItems}>
|
|
137
|
+
* {lineItems.map((item) => (
|
|
138
|
+
* <Payment.LineItem key={item.sdkLineItem.lineItemId} lineItem={item} currency={currency}>
|
|
139
|
+
* {({ totalPriceAfterTaxAndDiscount }) => (
|
|
140
|
+
* <li><Money money={totalPriceAfterTaxAndDiscount} /></li>
|
|
141
|
+
* )}
|
|
142
|
+
* </Payment.LineItem>
|
|
143
|
+
* ))}
|
|
144
|
+
* </ul>
|
|
145
|
+
* )}
|
|
146
|
+
* </Payment.LineItems>
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
export function LineItems(props) {
|
|
150
|
+
const paymentService = useService(PaymentServiceDefinition);
|
|
151
|
+
const paymentDetails = paymentService.paymentDetailsSignal.get();
|
|
152
|
+
const sdkLineItems = paymentDetails?.response?.calculatedLineItems || [];
|
|
153
|
+
const additionalInfoList = paymentDetails?.additionalInfo?.lineItems || [];
|
|
154
|
+
const currency = paymentDetails?.response?.currency || 'USD';
|
|
155
|
+
// Combine SDK line items with additional info
|
|
156
|
+
const lineItems = sdkLineItems.map((sdkLineItem) => ({
|
|
157
|
+
sdkLineItem,
|
|
158
|
+
additionalInfo: additionalInfoList.find((info) => info.lineItemId === sdkLineItem.lineItemId),
|
|
159
|
+
}));
|
|
160
|
+
const hasLineItems = lineItems.length > 0;
|
|
161
|
+
return props.children({ lineItems, hasLineItems, currency });
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Core component that provides access to a single line item via render props.
|
|
165
|
+
* Use data-attributes for conditional visibility via CSS.
|
|
166
|
+
*
|
|
167
|
+
* @component
|
|
168
|
+
* @example
|
|
169
|
+
* ```tsx
|
|
170
|
+
* <Payment.LineItem lineItem={item} currency="USD">
|
|
171
|
+
* {({ totalPrice, subtotal, tax, discount, deposit, priceText }) => (
|
|
172
|
+
* <div>
|
|
173
|
+
* <span><Money money={totalPrice} /></span>
|
|
174
|
+
* <span data-has-discount={!!discount?.amount}><Money money={discount} /></span>
|
|
175
|
+
* <span data-has-deposit={!!deposit?.amount}><Money money={deposit} /></span>
|
|
176
|
+
* <span data-has-price-text={!!priceText}>{priceText}</span>
|
|
177
|
+
* </div>
|
|
178
|
+
* )}
|
|
179
|
+
* </Payment.LineItem>
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
export function LineItem(props) {
|
|
183
|
+
const { lineItem, currency, children } = props;
|
|
184
|
+
const { sdkLineItem, additionalInfo } = lineItem;
|
|
185
|
+
const pricesBreakdown = sdkLineItem?.pricesBreakdown;
|
|
186
|
+
// Prices (from SDK)
|
|
187
|
+
const totalPrice = convertMultiCurrencyPriceToMoneyData(pricesBreakdown?.totalPriceAfterTax, currency);
|
|
188
|
+
const subtotal = convertMultiCurrencyPriceToMoneyData(pricesBreakdown?.fullPrice, currency);
|
|
189
|
+
const tax = convertMultiCurrencyPriceToMoneyData(pricesBreakdown?.taxDetails?.totalTax, currency);
|
|
190
|
+
const discount = convertMultiCurrencyPriceToMoneyData(pricesBreakdown?.totalDiscount, currency);
|
|
191
|
+
const deposit = convertMultiCurrencyPriceToMoneyData(pricesBreakdown?.depositAmount, currency);
|
|
192
|
+
// Custom price text (for CUSTOM rate type)
|
|
193
|
+
const priceText = additionalInfo?.priceText || null;
|
|
194
|
+
return children({
|
|
195
|
+
totalPrice,
|
|
196
|
+
subtotal,
|
|
197
|
+
tax,
|
|
198
|
+
discount,
|
|
199
|
+
deposit,
|
|
200
|
+
priceText,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core ServiceMediaCover Component
|
|
3
|
+
* Provides low-level access to service cover media via render props
|
|
4
|
+
*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
/**
|
|
7
|
+
* Render props for CoverMedia component
|
|
8
|
+
*/
|
|
9
|
+
export interface CoverMediaRenderProps {
|
|
10
|
+
/** Cover media object containing the image string */
|
|
11
|
+
coverMedia: {
|
|
12
|
+
image?: string;
|
|
13
|
+
};
|
|
14
|
+
/** Whether the service has a cover media image */
|
|
15
|
+
hasCoverMedia: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Props for CoverMedia component
|
|
19
|
+
*/
|
|
20
|
+
export interface CoverMediaProps {
|
|
21
|
+
/** Render prop function that receives cover media data */
|
|
22
|
+
children: (props: CoverMediaRenderProps) => React.ReactNode;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Core component that provides access to service cover media via render props.
|
|
26
|
+
* The cover media is typically used as a hero/banner image.
|
|
27
|
+
* Must be used within a Service.Root context.
|
|
28
|
+
*
|
|
29
|
+
* @component
|
|
30
|
+
* @example
|
|
31
|
+
* ```tsx
|
|
32
|
+
* <ServiceMediaCover.CoverMedia>
|
|
33
|
+
* {({ coverMedia, hasCoverMedia }) => (
|
|
34
|
+
* hasCoverMedia ? (
|
|
35
|
+
* <img src={coverMedia.image} alt="Service Cover" />
|
|
36
|
+
* ) : (
|
|
37
|
+
* <div>No cover image available</div>
|
|
38
|
+
* )
|
|
39
|
+
* )}
|
|
40
|
+
* </ServiceMediaCover.CoverMedia>
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export declare function CoverMedia(props: CoverMediaProps): React.ReactNode;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core ServiceMediaCover Component
|
|
3
|
+
* Provides low-level access to service cover media via render props
|
|
4
|
+
*/
|
|
5
|
+
import { useService } from '@wix/services-manager-react';
|
|
6
|
+
import { ServiceServiceDefinition } from '../../../services/service/service.js';
|
|
7
|
+
/**
|
|
8
|
+
* Core component that provides access to service cover media via render props.
|
|
9
|
+
* The cover media is typically used as a hero/banner image.
|
|
10
|
+
* Must be used within a Service.Root context.
|
|
11
|
+
*
|
|
12
|
+
* @component
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* <ServiceMediaCover.CoverMedia>
|
|
16
|
+
* {({ coverMedia, hasCoverMedia }) => (
|
|
17
|
+
* hasCoverMedia ? (
|
|
18
|
+
* <img src={coverMedia.image} alt="Service Cover" />
|
|
19
|
+
* ) : (
|
|
20
|
+
* <div>No cover image available</div>
|
|
21
|
+
* )
|
|
22
|
+
* )}
|
|
23
|
+
* </ServiceMediaCover.CoverMedia>
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export function CoverMedia(props) {
|
|
27
|
+
const serviceService = useService(ServiceServiceDefinition);
|
|
28
|
+
const service = serviceService.serviceSignal.get();
|
|
29
|
+
const coverMedia = {
|
|
30
|
+
image: service.media?.coverMedia?.image,
|
|
31
|
+
};
|
|
32
|
+
const hasCoverMedia = !!coverMedia.image;
|
|
33
|
+
return props.children({ coverMedia, hasCoverMedia });
|
|
34
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core ServiceMediaGallery Component
|
|
3
|
+
* Provides low-level access to service media gallery items via render props
|
|
4
|
+
*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
/**
|
|
7
|
+
* Media item type for gallery items
|
|
8
|
+
*/
|
|
9
|
+
export interface MediaItem {
|
|
10
|
+
image?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Render props for MediaGallery component
|
|
14
|
+
*/
|
|
15
|
+
export interface MediaGalleryRenderProps {
|
|
16
|
+
/** Array of media items in the gallery */
|
|
17
|
+
mediaItems: MediaItem[];
|
|
18
|
+
/** Whether the service has any media items */
|
|
19
|
+
hasMediaItems: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Props for MediaGallery component
|
|
23
|
+
*/
|
|
24
|
+
export interface MediaGalleryProps {
|
|
25
|
+
/** Render prop function that receives media gallery data */
|
|
26
|
+
children: (props: MediaGalleryRenderProps) => React.ReactNode;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Core component that provides access to service media gallery items via render props.
|
|
30
|
+
* Must be used within a Service.Root context.
|
|
31
|
+
*
|
|
32
|
+
* @component
|
|
33
|
+
* @example
|
|
34
|
+
* ```tsx
|
|
35
|
+
* <ServiceMediaGallery.MediaGallery>
|
|
36
|
+
* {({ mediaItems, hasMediaItems }) => (
|
|
37
|
+
* hasMediaItems ? (
|
|
38
|
+
* <div>
|
|
39
|
+
* {mediaItems.map((item, index) => (
|
|
40
|
+
* <img key={index} src={item.image} alt={`Gallery item ${index}`} />
|
|
41
|
+
* ))}
|
|
42
|
+
* </div>
|
|
43
|
+
* ) : (
|
|
44
|
+
* <div>No gallery items available</div>
|
|
45
|
+
* )
|
|
46
|
+
* )}
|
|
47
|
+
* </ServiceMediaGallery.MediaGallery>
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function MediaGallery(props: MediaGalleryProps): React.ReactNode;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core ServiceMediaGallery Component
|
|
3
|
+
* Provides low-level access to service media gallery items via render props
|
|
4
|
+
*/
|
|
5
|
+
import { useService } from '@wix/services-manager-react';
|
|
6
|
+
import { ServiceServiceDefinition } from '../../../services/service/service.js';
|
|
7
|
+
/**
|
|
8
|
+
* Core component that provides access to service media gallery items via render props.
|
|
9
|
+
* Must be used within a Service.Root context.
|
|
10
|
+
*
|
|
11
|
+
* @component
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* <ServiceMediaGallery.MediaGallery>
|
|
15
|
+
* {({ mediaItems, hasMediaItems }) => (
|
|
16
|
+
* hasMediaItems ? (
|
|
17
|
+
* <div>
|
|
18
|
+
* {mediaItems.map((item, index) => (
|
|
19
|
+
* <img key={index} src={item.image} alt={`Gallery item ${index}`} />
|
|
20
|
+
* ))}
|
|
21
|
+
* </div>
|
|
22
|
+
* ) : (
|
|
23
|
+
* <div>No gallery items available</div>
|
|
24
|
+
* )
|
|
25
|
+
* )}
|
|
26
|
+
* </ServiceMediaGallery.MediaGallery>
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export function MediaGallery(props) {
|
|
30
|
+
const serviceService = useService(ServiceServiceDefinition);
|
|
31
|
+
const service = serviceService.serviceSignal.get();
|
|
32
|
+
const mediaItems = service.media?.items?.map((item) => ({
|
|
33
|
+
image: item.image,
|
|
34
|
+
})) || [];
|
|
35
|
+
const hasMediaItems = mediaItems.length > 0;
|
|
36
|
+
return props.children({ mediaItems, hasMediaItems });
|
|
37
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core ServiceMediaMain Component
|
|
3
|
+
* Provides low-level access to service main media via render props
|
|
4
|
+
*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
/**
|
|
7
|
+
* Render props for MainMedia component
|
|
8
|
+
*/
|
|
9
|
+
export interface MainMediaRenderProps {
|
|
10
|
+
/** Main media object containing the image string */
|
|
11
|
+
mainMedia: {
|
|
12
|
+
image?: string;
|
|
13
|
+
};
|
|
14
|
+
/** Whether the service has a main media image */
|
|
15
|
+
hasMainMedia: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Props for MainMedia component
|
|
19
|
+
*/
|
|
20
|
+
export interface MainMediaProps {
|
|
21
|
+
/** Render prop function that receives main media data */
|
|
22
|
+
children: (props: MainMediaRenderProps) => React.ReactNode;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Core component that provides access to service main media via render props.
|
|
26
|
+
* Must be used within a Service.Root context.
|
|
27
|
+
*
|
|
28
|
+
* @component
|
|
29
|
+
* @example
|
|
30
|
+
* ```tsx
|
|
31
|
+
* <ServiceMediaMain.MainMedia>
|
|
32
|
+
* {({ mainMedia, hasMainMedia }) => (
|
|
33
|
+
* hasMainMedia ? (
|
|
34
|
+
* <img src={mainMedia.image} alt="Service" />
|
|
35
|
+
* ) : (
|
|
36
|
+
* <div>No image available</div>
|
|
37
|
+
* )
|
|
38
|
+
* )}
|
|
39
|
+
* </ServiceMediaMain.MainMedia>
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare function MainMedia(props: MainMediaProps): React.ReactNode;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core ServiceMediaMain Component
|
|
3
|
+
* Provides low-level access to service main media via render props
|
|
4
|
+
*/
|
|
5
|
+
import { useService } from '@wix/services-manager-react';
|
|
6
|
+
import { ServiceServiceDefinition } from '../../../services/service/service.js';
|
|
7
|
+
/**
|
|
8
|
+
* Core component that provides access to service main media via render props.
|
|
9
|
+
* Must be used within a Service.Root context.
|
|
10
|
+
*
|
|
11
|
+
* @component
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* <ServiceMediaMain.MainMedia>
|
|
15
|
+
* {({ mainMedia, hasMainMedia }) => (
|
|
16
|
+
* hasMainMedia ? (
|
|
17
|
+
* <img src={mainMedia.image} alt="Service" />
|
|
18
|
+
* ) : (
|
|
19
|
+
* <div>No image available</div>
|
|
20
|
+
* )
|
|
21
|
+
* )}
|
|
22
|
+
* </ServiceMediaMain.MainMedia>
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export function MainMedia(props) {
|
|
26
|
+
const serviceService = useService(ServiceServiceDefinition);
|
|
27
|
+
const service = serviceService.serviceSignal.get();
|
|
28
|
+
const mainMedia = {
|
|
29
|
+
image: service.media?.mainMedia?.image,
|
|
30
|
+
};
|
|
31
|
+
const hasMainMedia = !!mainMedia.image;
|
|
32
|
+
return props.children({ mainMedia, hasMainMedia });
|
|
33
|
+
}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export * as Booking from './booking/Booking.js';
|
|
2
2
|
export * as BookingForm from './booking-form/BookingForm.js';
|
|
3
3
|
export * as Service from './service/Service.js';
|
|
4
|
+
export * as ServiceMedia from './service/ServiceMedia.js';
|
|
4
5
|
export * as TimeSlotList from './time-slot-list/TimeSlotList.js';
|
|
5
6
|
export * as ServiceList from './service-list/ServiceList.js';
|
|
6
7
|
export * as Location from './location/Location.js';
|
|
8
|
+
export * as Payment from './payment/Payment.js';
|
|
9
|
+
export * as PaymentLineItem from './payment/PaymentLineItem.js';
|
package/dist/react/index.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export * as Booking from './booking/Booking.js';
|
|
2
2
|
export * as BookingForm from './booking-form/BookingForm.js';
|
|
3
3
|
export * as Service from './service/Service.js';
|
|
4
|
+
export * as ServiceMedia from './service/ServiceMedia.js';
|
|
4
5
|
export * as TimeSlotList from './time-slot-list/TimeSlotList.js';
|
|
5
6
|
export * as ServiceList from './service-list/ServiceList.js';
|
|
6
7
|
export * as Location from './location/Location.js';
|
|
8
|
+
export * as Payment from './payment/Payment.js';
|
|
9
|
+
export * as PaymentLineItem from './payment/PaymentLineItem.js';
|