@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
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ServiceMedia - Compound component for displaying service media
|
|
3
|
+
* Provides components for displaying main media, cover media, and media galleries
|
|
4
|
+
*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import { AsChildChildren } from '@wix/headless-utils/react';
|
|
7
|
+
/**
|
|
8
|
+
* Props for ServiceMedia.Main component
|
|
9
|
+
*/
|
|
10
|
+
export interface MainProps {
|
|
11
|
+
/** Whether to render as a child component */
|
|
12
|
+
asChild?: boolean;
|
|
13
|
+
/** Custom render function when using asChild */
|
|
14
|
+
children?: AsChildChildren<{
|
|
15
|
+
media: {
|
|
16
|
+
image?: string;
|
|
17
|
+
};
|
|
18
|
+
}>;
|
|
19
|
+
/** CSS class name */
|
|
20
|
+
className?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Displays the service main media image using WixMediaImage.
|
|
24
|
+
*
|
|
25
|
+
* @component
|
|
26
|
+
* @example
|
|
27
|
+
* ```tsx
|
|
28
|
+
* // Default usage
|
|
29
|
+
* <ServiceMedia.Main className="w-full h-64 object-cover rounded-lg" />
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```tsx
|
|
34
|
+
* // asChild with primitive img element
|
|
35
|
+
* <ServiceMedia.Main asChild>
|
|
36
|
+
* <img className="w-full h-64 object-cover shadow-lg" />
|
|
37
|
+
* </ServiceMedia.Main>
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```tsx
|
|
42
|
+
* // asChild with custom component accessing media data
|
|
43
|
+
* <ServiceMedia.Main asChild>
|
|
44
|
+
* {React.forwardRef(({media, ...props}, ref) => (
|
|
45
|
+
* <div ref={ref} {...props} className="relative aspect-video">
|
|
46
|
+
* <WixMediaImage media={media} className="w-full h-full object-cover" />
|
|
47
|
+
* <div className="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/50 p-4">
|
|
48
|
+
* <Service.Name className="text-primary-foreground" />
|
|
49
|
+
* </div>
|
|
50
|
+
* </div>
|
|
51
|
+
* ))}
|
|
52
|
+
* </ServiceMedia.Main>
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare const Main: React.ForwardRefExoticComponent<MainProps & React.RefAttributes<HTMLImageElement>>;
|
|
56
|
+
/**
|
|
57
|
+
* Props for ServiceMedia.Cover component
|
|
58
|
+
*/
|
|
59
|
+
export interface CoverProps {
|
|
60
|
+
/** Whether to render as a child component */
|
|
61
|
+
asChild?: boolean;
|
|
62
|
+
/** Custom render function when using asChild */
|
|
63
|
+
children?: AsChildChildren<{
|
|
64
|
+
media: {
|
|
65
|
+
image?: string;
|
|
66
|
+
};
|
|
67
|
+
}>;
|
|
68
|
+
/** CSS class name */
|
|
69
|
+
className?: string;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Displays the service cover media image using WixMediaImage.
|
|
73
|
+
* The cover media is typically used as a hero/banner image.
|
|
74
|
+
*
|
|
75
|
+
* @component
|
|
76
|
+
* @example
|
|
77
|
+
* ```tsx
|
|
78
|
+
* // Default usage
|
|
79
|
+
* <ServiceMedia.Cover className="w-full h-96 object-cover" />
|
|
80
|
+
* ```
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```tsx
|
|
84
|
+
* // asChild as a background image container
|
|
85
|
+
* <ServiceMedia.Cover asChild>
|
|
86
|
+
* <div className="w-full h-96 bg-cover bg-center" />
|
|
87
|
+
* </ServiceMedia.Cover>
|
|
88
|
+
* ```
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```tsx
|
|
92
|
+
* // asChild with custom component accessing media data
|
|
93
|
+
* <ServiceMedia.Cover asChild>
|
|
94
|
+
* {React.forwardRef(({media, ...props}, ref) => (
|
|
95
|
+
* <header ref={ref} {...props} className="relative h-96">
|
|
96
|
+
* <WixMediaImage media={media} className="w-full h-full object-cover" />
|
|
97
|
+
* <div className="absolute inset-0 bg-black/40 flex items-center justify-center">
|
|
98
|
+
* <h1 className="text-4xl font-bold text-primary-foreground">
|
|
99
|
+
* <Service.Name />
|
|
100
|
+
* </h1>
|
|
101
|
+
* </div>
|
|
102
|
+
* </header>
|
|
103
|
+
* ))}
|
|
104
|
+
* </ServiceMedia.Cover>
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export declare const Cover: React.ForwardRefExoticComponent<CoverProps & React.RefAttributes<HTMLImageElement>>;
|
|
108
|
+
/**
|
|
109
|
+
* Props for ServiceMedia.Gallery component
|
|
110
|
+
*/
|
|
111
|
+
export interface GalleryProps {
|
|
112
|
+
/** Child components to render within the gallery (MediaGallery components) */
|
|
113
|
+
children: React.ReactNode;
|
|
114
|
+
/** Whether the gallery should loop infinitely */
|
|
115
|
+
infinite?: boolean;
|
|
116
|
+
/** Auto-play configuration for the gallery */
|
|
117
|
+
autoPlay?: {
|
|
118
|
+
/** Direction of auto-play */
|
|
119
|
+
direction?: 'forward' | 'backward';
|
|
120
|
+
/** Interval between slides in milliseconds */
|
|
121
|
+
intervalMs?: number;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Container for service media items gallery.
|
|
126
|
+
* Renders a MediaGallery.Root with the service media items.
|
|
127
|
+
* Supports autoPlay and infinite scroll options for carousel behavior.
|
|
128
|
+
*
|
|
129
|
+
* @component
|
|
130
|
+
* @example
|
|
131
|
+
* ```tsx
|
|
132
|
+
* // Basic usage with MediaGallery components
|
|
133
|
+
* <ServiceMedia.Gallery>
|
|
134
|
+
* <MediaGallery.Thumbnails>
|
|
135
|
+
* <MediaGallery.ThumbnailRepeater>
|
|
136
|
+
* <MediaGallery.ThumbnailItem />
|
|
137
|
+
* </MediaGallery.ThumbnailRepeater>
|
|
138
|
+
* </MediaGallery.Thumbnails>
|
|
139
|
+
* </ServiceMedia.Gallery>
|
|
140
|
+
*
|
|
141
|
+
* // With autoPlay carousel
|
|
142
|
+
* <ServiceMedia.Gallery
|
|
143
|
+
* autoPlay={{ direction: 'forward', intervalMs: 3000 }}
|
|
144
|
+
* infinite
|
|
145
|
+
* >
|
|
146
|
+
* <MediaGallery.Viewport />
|
|
147
|
+
* <MediaGallery.Previous />
|
|
148
|
+
* <MediaGallery.Next />
|
|
149
|
+
* </ServiceMedia.Gallery>
|
|
150
|
+
*
|
|
151
|
+
* // Full gallery with thumbnails and navigation
|
|
152
|
+
* <ServiceMedia.Gallery infinite>
|
|
153
|
+
* <div className="gallery-container">
|
|
154
|
+
* <MediaGallery.Viewport className="main-image" />
|
|
155
|
+
* <div className="controls">
|
|
156
|
+
* <MediaGallery.Previous>Prev</MediaGallery.Previous>
|
|
157
|
+
* <MediaGallery.Next>Next</MediaGallery.Next>
|
|
158
|
+
* </div>
|
|
159
|
+
* <MediaGallery.Thumbnails>
|
|
160
|
+
* <MediaGallery.ThumbnailRepeater>
|
|
161
|
+
* <MediaGallery.ThumbnailItem />
|
|
162
|
+
* </MediaGallery.ThumbnailRepeater>
|
|
163
|
+
* </MediaGallery.Thumbnails>
|
|
164
|
+
* </div>
|
|
165
|
+
* </ServiceMedia.Gallery>
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
export declare const Gallery: React.FC<GalleryProps>;
|
|
169
|
+
/**
|
|
170
|
+
* ServiceMedia compound component for displaying service media
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```tsx
|
|
174
|
+
* import { Service, ServiceMedia } from '@wix/headless-bookings/react';
|
|
175
|
+
*
|
|
176
|
+
* function ServiceCard({ service }) {
|
|
177
|
+
* return (
|
|
178
|
+
* <Service.Root serviceServiceConfig={{ service }}>
|
|
179
|
+
* <ServiceMedia.Main className="w-full h-48 object-cover" />
|
|
180
|
+
* <Service.Name />
|
|
181
|
+
* </Service.Root>
|
|
182
|
+
* );
|
|
183
|
+
* }
|
|
184
|
+
* ```
|
|
185
|
+
*/
|
|
186
|
+
export declare const ServiceMedia: {
|
|
187
|
+
Main: React.ForwardRefExoticComponent<MainProps & React.RefAttributes<HTMLImageElement>>;
|
|
188
|
+
Cover: React.ForwardRefExoticComponent<CoverProps & React.RefAttributes<HTMLImageElement>>;
|
|
189
|
+
Gallery: React.FC<GalleryProps>;
|
|
190
|
+
};
|
|
191
|
+
export default ServiceMedia;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* ServiceMedia - Compound component for displaying service media
|
|
4
|
+
* Provides components for displaying main media, cover media, and media galleries
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { AsChildSlot } from '@wix/headless-utils/react';
|
|
8
|
+
import { WixMediaImage } from '@wix/headless-media/react';
|
|
9
|
+
import { MediaGallery } from '@wix/headless-media/react';
|
|
10
|
+
import * as CoreServiceMediaMain from '../core/service/ServiceMediaMain.js';
|
|
11
|
+
import * as CoreServiceMediaCover from '../core/service/ServiceMediaCover.js';
|
|
12
|
+
import * as CoreServiceMediaGallery from '../core/service/ServiceMediaGallery.js';
|
|
13
|
+
var TestIds;
|
|
14
|
+
(function (TestIds) {
|
|
15
|
+
TestIds["serviceMediaMain"] = "service-media-main";
|
|
16
|
+
TestIds["serviceMediaCover"] = "service-media-cover";
|
|
17
|
+
})(TestIds || (TestIds = {}));
|
|
18
|
+
/**
|
|
19
|
+
* Displays the service main media image using WixMediaImage.
|
|
20
|
+
*
|
|
21
|
+
* @component
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* // Default usage
|
|
25
|
+
* <ServiceMedia.Main className="w-full h-64 object-cover rounded-lg" />
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* // asChild with primitive img element
|
|
31
|
+
* <ServiceMedia.Main asChild>
|
|
32
|
+
* <img className="w-full h-64 object-cover shadow-lg" />
|
|
33
|
+
* </ServiceMedia.Main>
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```tsx
|
|
38
|
+
* // asChild with custom component accessing media data
|
|
39
|
+
* <ServiceMedia.Main asChild>
|
|
40
|
+
* {React.forwardRef(({media, ...props}, ref) => (
|
|
41
|
+
* <div ref={ref} {...props} className="relative aspect-video">
|
|
42
|
+
* <WixMediaImage media={media} className="w-full h-full object-cover" />
|
|
43
|
+
* <div className="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/50 p-4">
|
|
44
|
+
* <Service.Name className="text-primary-foreground" />
|
|
45
|
+
* </div>
|
|
46
|
+
* </div>
|
|
47
|
+
* ))}
|
|
48
|
+
* </ServiceMedia.Main>
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export const Main = React.forwardRef((props, ref) => {
|
|
52
|
+
const { asChild, children, className } = props;
|
|
53
|
+
return (_jsx(CoreServiceMediaMain.MainMedia, { children: ({ mainMedia }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.serviceMediaMain, customElement: children, customElementProps: { media: mainMedia }, children: mainMedia?.image ? _jsx(WixMediaImage, { media: mainMedia }) : null })) }));
|
|
54
|
+
});
|
|
55
|
+
Main.displayName = 'ServiceMedia.Main';
|
|
56
|
+
/**
|
|
57
|
+
* Displays the service cover media image using WixMediaImage.
|
|
58
|
+
* The cover media is typically used as a hero/banner image.
|
|
59
|
+
*
|
|
60
|
+
* @component
|
|
61
|
+
* @example
|
|
62
|
+
* ```tsx
|
|
63
|
+
* // Default usage
|
|
64
|
+
* <ServiceMedia.Cover className="w-full h-96 object-cover" />
|
|
65
|
+
* ```
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```tsx
|
|
69
|
+
* // asChild as a background image container
|
|
70
|
+
* <ServiceMedia.Cover asChild>
|
|
71
|
+
* <div className="w-full h-96 bg-cover bg-center" />
|
|
72
|
+
* </ServiceMedia.Cover>
|
|
73
|
+
* ```
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```tsx
|
|
77
|
+
* // asChild with custom component accessing media data
|
|
78
|
+
* <ServiceMedia.Cover asChild>
|
|
79
|
+
* {React.forwardRef(({media, ...props}, ref) => (
|
|
80
|
+
* <header ref={ref} {...props} className="relative h-96">
|
|
81
|
+
* <WixMediaImage media={media} className="w-full h-full object-cover" />
|
|
82
|
+
* <div className="absolute inset-0 bg-black/40 flex items-center justify-center">
|
|
83
|
+
* <h1 className="text-4xl font-bold text-primary-foreground">
|
|
84
|
+
* <Service.Name />
|
|
85
|
+
* </h1>
|
|
86
|
+
* </div>
|
|
87
|
+
* </header>
|
|
88
|
+
* ))}
|
|
89
|
+
* </ServiceMedia.Cover>
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
export const Cover = React.forwardRef((props, ref) => {
|
|
93
|
+
const { asChild, children, className } = props;
|
|
94
|
+
return (_jsx(CoreServiceMediaCover.CoverMedia, { children: ({ coverMedia }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.serviceMediaCover, customElement: children, customElementProps: { media: coverMedia }, children: coverMedia?.image ? _jsx(WixMediaImage, { media: coverMedia }) : null })) }));
|
|
95
|
+
});
|
|
96
|
+
Cover.displayName = 'ServiceMedia.Cover';
|
|
97
|
+
/**
|
|
98
|
+
* Container for service media items gallery.
|
|
99
|
+
* Renders a MediaGallery.Root with the service media items.
|
|
100
|
+
* Supports autoPlay and infinite scroll options for carousel behavior.
|
|
101
|
+
*
|
|
102
|
+
* @component
|
|
103
|
+
* @example
|
|
104
|
+
* ```tsx
|
|
105
|
+
* // Basic usage with MediaGallery components
|
|
106
|
+
* <ServiceMedia.Gallery>
|
|
107
|
+
* <MediaGallery.Thumbnails>
|
|
108
|
+
* <MediaGallery.ThumbnailRepeater>
|
|
109
|
+
* <MediaGallery.ThumbnailItem />
|
|
110
|
+
* </MediaGallery.ThumbnailRepeater>
|
|
111
|
+
* </MediaGallery.Thumbnails>
|
|
112
|
+
* </ServiceMedia.Gallery>
|
|
113
|
+
*
|
|
114
|
+
* // With autoPlay carousel
|
|
115
|
+
* <ServiceMedia.Gallery
|
|
116
|
+
* autoPlay={{ direction: 'forward', intervalMs: 3000 }}
|
|
117
|
+
* infinite
|
|
118
|
+
* >
|
|
119
|
+
* <MediaGallery.Viewport />
|
|
120
|
+
* <MediaGallery.Previous />
|
|
121
|
+
* <MediaGallery.Next />
|
|
122
|
+
* </ServiceMedia.Gallery>
|
|
123
|
+
*
|
|
124
|
+
* // Full gallery with thumbnails and navigation
|
|
125
|
+
* <ServiceMedia.Gallery infinite>
|
|
126
|
+
* <div className="gallery-container">
|
|
127
|
+
* <MediaGallery.Viewport className="main-image" />
|
|
128
|
+
* <div className="controls">
|
|
129
|
+
* <MediaGallery.Previous>Prev</MediaGallery.Previous>
|
|
130
|
+
* <MediaGallery.Next>Next</MediaGallery.Next>
|
|
131
|
+
* </div>
|
|
132
|
+
* <MediaGallery.Thumbnails>
|
|
133
|
+
* <MediaGallery.ThumbnailRepeater>
|
|
134
|
+
* <MediaGallery.ThumbnailItem />
|
|
135
|
+
* </MediaGallery.ThumbnailRepeater>
|
|
136
|
+
* </MediaGallery.Thumbnails>
|
|
137
|
+
* </div>
|
|
138
|
+
* </ServiceMedia.Gallery>
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
export const Gallery = (props) => {
|
|
142
|
+
const { children, infinite, autoPlay } = props;
|
|
143
|
+
return (_jsx(CoreServiceMediaGallery.MediaGallery, { children: ({ mediaItems }) => {
|
|
144
|
+
const mediaGalleryServiceConfig = {
|
|
145
|
+
media: mediaItems,
|
|
146
|
+
infinite,
|
|
147
|
+
autoPlay,
|
|
148
|
+
};
|
|
149
|
+
return (_jsx(MediaGallery.Root, { mediaGalleryServiceConfig: mediaGalleryServiceConfig, children: children }));
|
|
150
|
+
} }));
|
|
151
|
+
};
|
|
152
|
+
Gallery.displayName = 'ServiceMedia.Gallery';
|
|
153
|
+
/**
|
|
154
|
+
* ServiceMedia compound component for displaying service media
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```tsx
|
|
158
|
+
* import { Service, ServiceMedia } from '@wix/headless-bookings/react';
|
|
159
|
+
*
|
|
160
|
+
* function ServiceCard({ service }) {
|
|
161
|
+
* return (
|
|
162
|
+
* <Service.Root serviceServiceConfig={{ service }}>
|
|
163
|
+
* <ServiceMedia.Main className="w-full h-48 object-cover" />
|
|
164
|
+
* <Service.Name />
|
|
165
|
+
* </Service.Root>
|
|
166
|
+
* );
|
|
167
|
+
* }
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
export const ServiceMedia = {
|
|
171
|
+
Main,
|
|
172
|
+
Cover,
|
|
173
|
+
Gallery,
|
|
174
|
+
};
|
|
175
|
+
export default ServiceMedia;
|
package/dist/services/index.d.ts
CHANGED
|
@@ -8,3 +8,4 @@ export { TimeSlotListService, TimeSlotListServiceDefinition, ViewMode, loadTimeS
|
|
|
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 SlotService, type LineItemAdditionalInfo, loadPaymentConfig, type SuccessPaymentConfigResult, type ErrorPaymentConfigResult, } from './payment/payment.js';
|
package/dist/services/index.js
CHANGED
|
@@ -8,3 +8,4 @@ export { TimeSlotListService, TimeSlotListServiceDefinition, ViewMode, loadTimeS
|
|
|
8
8
|
export { ServiceListService, ServiceListServiceDefinition, loadServiceListServiceInitialData, } from './service-list/service-list.js';
|
|
9
9
|
export { executeBookAction, canBook, buildBookingRequest, buildCheckoutRequest, } from './booking/book-action/index.js';
|
|
10
10
|
export { BookingFormService, BookingFormServiceDefinition, } from './booking-form/booking-form.js';
|
|
11
|
+
export { PaymentService, PaymentServiceDefinition, loadPaymentConfig, } from './payment/payment.js';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payment Service - Pricing calculation and payment details management
|
|
3
|
+
* Handles calculating total prices, taxes, discounts, and deposit information
|
|
4
|
+
* Supports two modes: SSR (config with pre-fetched data) and lazy loading (reactive)
|
|
5
|
+
*/
|
|
6
|
+
import { type PaymentServiceConfig, type PaymentServiceInternalConfig, type SlotService } from './payment.def.js';
|
|
7
|
+
export { PaymentServiceDefinition, type PaymentServiceConfig, type PaymentDetails, type LineItemAdditionalInfo, type SlotService, } from './payment.def.js';
|
|
8
|
+
export type { PaymentServiceAPI, PaymentServiceInternalConfig } from './payment.def.js';
|
|
9
|
+
export declare const PaymentService: import("@wix/services-definitions").ServiceFactory<string & {
|
|
10
|
+
__api: import("./payment.def.js").PaymentServiceAPI;
|
|
11
|
+
__config: {};
|
|
12
|
+
isServiceDefinition?: boolean;
|
|
13
|
+
} & import("./payment.def.js").PaymentServiceAPI, PaymentServiceInternalConfig>;
|
|
14
|
+
export type SuccessPaymentConfigResult = {
|
|
15
|
+
type: 'success';
|
|
16
|
+
config: PaymentServiceConfig;
|
|
17
|
+
};
|
|
18
|
+
export type ErrorPaymentConfigResult = {
|
|
19
|
+
type: 'error';
|
|
20
|
+
error: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Load payment configuration for Server-Side Rendering (SSR).
|
|
24
|
+
* Calls the pricing APIs and returns pre-calculated payment details.
|
|
25
|
+
*
|
|
26
|
+
* @param params.slotServices - Slot/service inputs for calculation
|
|
27
|
+
* @param params.numberOfParticipants - Number of participants (default: 1)
|
|
28
|
+
*/
|
|
29
|
+
export declare function loadPaymentConfig(params: {
|
|
30
|
+
slotServices: SlotService[];
|
|
31
|
+
numberOfParticipants?: number;
|
|
32
|
+
}): Promise<SuccessPaymentConfigResult | ErrorPaymentConfigResult>;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payment Service Definition
|
|
3
|
+
* Defines interfaces and service contract for payment calculation management
|
|
4
|
+
*/
|
|
5
|
+
import type { Signal } from '@wix/services-definitions/core-services/signals';
|
|
6
|
+
import type { CalculateTotalsResponse } from '@wix/auto_sdk_ecom_totals-calculator';
|
|
7
|
+
import type { Service } from '@wix/auto_sdk_bookings_services';
|
|
8
|
+
/**
|
|
9
|
+
* Payment option for line items
|
|
10
|
+
*/
|
|
11
|
+
export type PaymentOption = 'FULL_PAYMENT_ONLINE' | 'FULL_PAYMENT_OFFLINE';
|
|
12
|
+
/**
|
|
13
|
+
* Additional computed info for a line item (not in SDK response)
|
|
14
|
+
*/
|
|
15
|
+
export interface LineItemAdditionalInfo {
|
|
16
|
+
/** Line item ID to match with SDK's calculatedLineItems */
|
|
17
|
+
lineItemId: string;
|
|
18
|
+
/** Custom price text (for CUSTOM rate type services) */
|
|
19
|
+
priceText?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Payment calculation result with SDK response and additional computed info
|
|
23
|
+
*/
|
|
24
|
+
export interface PaymentDetails {
|
|
25
|
+
/** The raw SDK CalculateTotals response */
|
|
26
|
+
response: CalculateTotalsResponse;
|
|
27
|
+
/** Additional computed information per line item */
|
|
28
|
+
additionalInfo: {
|
|
29
|
+
lineItems: LineItemAdditionalInfo[];
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Input for calculating payment for a slot/service
|
|
34
|
+
*/
|
|
35
|
+
export interface SlotService {
|
|
36
|
+
service: Service;
|
|
37
|
+
lineItemId: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Public config for PaymentService (SSR mode only):
|
|
41
|
+
* Pass `paymentDetails` pre-fetched via loadPaymentConfig
|
|
42
|
+
*/
|
|
43
|
+
export interface PaymentServiceConfig {
|
|
44
|
+
/** Pre-calculated payment details for SSR (no API call) */
|
|
45
|
+
paymentDetails?: PaymentDetails;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Internal config used by Core component to pass lazy loading data
|
|
49
|
+
* Not exposed publicly - Core merges this with PaymentServiceConfig
|
|
50
|
+
*/
|
|
51
|
+
export interface PaymentServiceInternalConfig extends PaymentServiceConfig {
|
|
52
|
+
/** Slot services for lazy loading (internal use) */
|
|
53
|
+
slotServices?: SlotService[];
|
|
54
|
+
/** Number of participants for lazy loading (internal use) */
|
|
55
|
+
numberOfParticipants?: number;
|
|
56
|
+
}
|
|
57
|
+
export interface PaymentServiceAPI {
|
|
58
|
+
paymentDetailsSignal: Signal<PaymentDetails | null>;
|
|
59
|
+
isLoadingSignal: Signal<boolean>;
|
|
60
|
+
errorSignal: Signal<string | null>;
|
|
61
|
+
}
|
|
62
|
+
export declare const PaymentServiceDefinition: string & {
|
|
63
|
+
__api: PaymentServiceAPI;
|
|
64
|
+
__config: {};
|
|
65
|
+
isServiceDefinition?: boolean;
|
|
66
|
+
} & PaymentServiceAPI;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payment Service Definition
|
|
3
|
+
* Defines interfaces and service contract for payment calculation management
|
|
4
|
+
*/
|
|
5
|
+
import { defineService } from '@wix/services-definitions';
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// Service Definition
|
|
8
|
+
// ============================================================================
|
|
9
|
+
export const PaymentServiceDefinition = defineService('payment');
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payment Service - Pricing calculation and payment details management
|
|
3
|
+
* Handles calculating total prices, taxes, discounts, and deposit information
|
|
4
|
+
* Supports two modes: SSR (config with pre-fetched data) and lazy loading (reactive)
|
|
5
|
+
*/
|
|
6
|
+
import { implementService } from '@wix/services-definitions';
|
|
7
|
+
import { SignalsServiceDefinition } from '@wix/services-definitions/core-services/signals';
|
|
8
|
+
import { calculateTotals, } from '@wix/auto_sdk_ecom_totals-calculator';
|
|
9
|
+
import { BookingServiceDefinition } from '../booking/booking.js';
|
|
10
|
+
import { RateType } from '@wix/auto_sdk_bookings_services';
|
|
11
|
+
import { PaymentServiceDefinition, } from './payment.def.js';
|
|
12
|
+
export { PaymentServiceDefinition, } from './payment.def.js';
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Constants
|
|
15
|
+
// ============================================================================
|
|
16
|
+
const BOOKINGS_APP_DEF_ID = '13d21c63-b5ec-5912-8397-c3a5ddb27a97';
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// Helper Functions
|
|
19
|
+
// ============================================================================
|
|
20
|
+
function getAdditionalInfo(service, lineItemId) {
|
|
21
|
+
const payment = service.payment;
|
|
22
|
+
const priceText = payment?.rateType === RateType.CUSTOM && payment.custom?.description
|
|
23
|
+
? payment.custom.description
|
|
24
|
+
: undefined;
|
|
25
|
+
return { lineItemId, priceText };
|
|
26
|
+
}
|
|
27
|
+
function getPaymentOption(service) {
|
|
28
|
+
const options = service.payment?.options;
|
|
29
|
+
if (options?.inPerson) {
|
|
30
|
+
return 'FULL_PAYMENT_OFFLINE';
|
|
31
|
+
}
|
|
32
|
+
return 'FULL_PAYMENT_ONLINE';
|
|
33
|
+
}
|
|
34
|
+
function buildLineItem(service, numberOfParticipants, lineItemId) {
|
|
35
|
+
// Get fixed price from service
|
|
36
|
+
const servicePrice = service.payment?.fixed?.price?.value;
|
|
37
|
+
const price = Number(servicePrice || 0) * numberOfParticipants;
|
|
38
|
+
// Get deposit if configured
|
|
39
|
+
const deposit = service.payment?.fixed?.deposit?.value
|
|
40
|
+
? Number(service.payment.fixed.deposit.value) * numberOfParticipants
|
|
41
|
+
: undefined;
|
|
42
|
+
// Get payment option from service configuration
|
|
43
|
+
const paymentOption = getPaymentOption(service);
|
|
44
|
+
return {
|
|
45
|
+
_id: lineItemId,
|
|
46
|
+
catalogReference: {
|
|
47
|
+
catalogItemId: service._id || '',
|
|
48
|
+
appId: BOOKINGS_APP_DEF_ID,
|
|
49
|
+
},
|
|
50
|
+
price: String(price),
|
|
51
|
+
...(deposit ? { depositAmount: String(deposit) } : {}),
|
|
52
|
+
quantity: 1,
|
|
53
|
+
paymentOption,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
async function calculatePaymentDetails(slotServices, numberOfParticipants) {
|
|
57
|
+
const lineItems = slotServices.map((input) => buildLineItem(input.service, numberOfParticipants, input.lineItemId));
|
|
58
|
+
const response = await calculateTotals({
|
|
59
|
+
lineItems,
|
|
60
|
+
});
|
|
61
|
+
const additionalInfoList = slotServices.map((input) => getAdditionalInfo(input.service, input.lineItemId));
|
|
62
|
+
return {
|
|
63
|
+
response,
|
|
64
|
+
additionalInfo: {
|
|
65
|
+
lineItems: additionalInfoList,
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
// ============================================================================
|
|
70
|
+
// Service Implementation
|
|
71
|
+
// ============================================================================
|
|
72
|
+
export const PaymentService = implementService.withConfig()(PaymentServiceDefinition, ({ getService, config }) => {
|
|
73
|
+
const signalsService = getService(SignalsServiceDefinition);
|
|
74
|
+
// Try to get BookingService (optional - for reactive mode)
|
|
75
|
+
let bookingService = null;
|
|
76
|
+
try {
|
|
77
|
+
bookingService = getService(BookingServiceDefinition);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
bookingService = null;
|
|
81
|
+
}
|
|
82
|
+
// Initialize signals
|
|
83
|
+
const paymentDetailsSignal = signalsService.signal(config.paymentDetails || null);
|
|
84
|
+
const isLoadingSignal = signalsService.signal(false);
|
|
85
|
+
const errorSignal = signalsService.signal(null);
|
|
86
|
+
// Internal calculate function
|
|
87
|
+
const calculate = async (slotServices, numberOfParticipants) => {
|
|
88
|
+
if (!slotServices.length) {
|
|
89
|
+
paymentDetailsSignal.set(null);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
isLoadingSignal.set(true);
|
|
93
|
+
errorSignal.set(null);
|
|
94
|
+
try {
|
|
95
|
+
const paymentDetails = await calculatePaymentDetails(slotServices, numberOfParticipants);
|
|
96
|
+
paymentDetailsSignal.set(paymentDetails);
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
const errorMessage = error instanceof Error
|
|
100
|
+
? error.message
|
|
101
|
+
: 'Failed to calculate payment';
|
|
102
|
+
errorSignal.set(errorMessage);
|
|
103
|
+
console.error('Payment calculation error:', error);
|
|
104
|
+
}
|
|
105
|
+
finally {
|
|
106
|
+
isLoadingSignal.set(false);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
// Mode 1: SSR - paymentDetails already set in signal initialization
|
|
110
|
+
if (config.paymentDetails) {
|
|
111
|
+
// No-op - data is pre-fetched
|
|
112
|
+
}
|
|
113
|
+
// Mode 2: Lazy loading - slotServices provided via internal config
|
|
114
|
+
else if (config.slotServices?.length) {
|
|
115
|
+
void calculate(config.slotServices, config.numberOfParticipants ?? 1);
|
|
116
|
+
}
|
|
117
|
+
// Mode 3: Reactive - observe BookingService signals (client-side only)
|
|
118
|
+
else if (typeof window !== 'undefined' && bookingService) {
|
|
119
|
+
signalsService.effect(() => {
|
|
120
|
+
const selections = bookingService?.serviceSelections.get() || [];
|
|
121
|
+
// For single service mode, take the first selection
|
|
122
|
+
const firstSelection = selections[0];
|
|
123
|
+
const numParticipants = firstSelection?.totalParticipants || 1;
|
|
124
|
+
const services = selections.map((selection) => ({
|
|
125
|
+
service: selection.service,
|
|
126
|
+
lineItemId: selection.instanceId,
|
|
127
|
+
}));
|
|
128
|
+
void calculate(services, numParticipants);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
paymentDetailsSignal,
|
|
133
|
+
isLoadingSignal,
|
|
134
|
+
errorSignal,
|
|
135
|
+
};
|
|
136
|
+
});
|
|
137
|
+
/**
|
|
138
|
+
* Load payment configuration for Server-Side Rendering (SSR).
|
|
139
|
+
* Calls the pricing APIs and returns pre-calculated payment details.
|
|
140
|
+
*
|
|
141
|
+
* @param params.slotServices - Slot/service inputs for calculation
|
|
142
|
+
* @param params.numberOfParticipants - Number of participants (default: 1)
|
|
143
|
+
*/
|
|
144
|
+
export async function loadPaymentConfig(params) {
|
|
145
|
+
try {
|
|
146
|
+
const { slotServices, numberOfParticipants = 1 } = params;
|
|
147
|
+
if (!slotServices.length) {
|
|
148
|
+
return {
|
|
149
|
+
type: 'success',
|
|
150
|
+
config: { paymentDetails: undefined },
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
const paymentDetails = await calculatePaymentDetails(slotServices, numberOfParticipants);
|
|
154
|
+
return {
|
|
155
|
+
type: 'success',
|
|
156
|
+
config: { paymentDetails },
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
const errorMessage = error instanceof Error ? error.message : 'Failed to load payment config';
|
|
161
|
+
console.error('Failed to load payment config:', error);
|
|
162
|
+
return {
|
|
163
|
+
type: 'error',
|
|
164
|
+
error: errorMessage,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
}
|
package/dist/utils/money.d.ts
CHANGED
|
@@ -19,3 +19,14 @@ export declare function convertToMoneyData(sdkMoney: {
|
|
|
19
19
|
currency?: string;
|
|
20
20
|
formattedValue?: string | null;
|
|
21
21
|
} | undefined): MoneyData | null;
|
|
22
|
+
/**
|
|
23
|
+
* Converts ecom MultiCurrencyPrice format to MoneyData format
|
|
24
|
+
* MultiCurrencyPrice uses 'amount' as string, while MoneyData uses 'amount' as number
|
|
25
|
+
*
|
|
26
|
+
* @param price - The MultiCurrencyPrice object with amount as string
|
|
27
|
+
* @param currency - The currency code (from response level)
|
|
28
|
+
* @returns MoneyData object or null if conversion fails
|
|
29
|
+
*/
|
|
30
|
+
export declare function convertMultiCurrencyPriceToMoneyData(price: {
|
|
31
|
+
amount?: string;
|
|
32
|
+
} | undefined, currency: string): MoneyData | null;
|