@bailierich/booking-components 2.0.0
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/README.md +319 -0
- package/TENANT_DATA_INTEGRATION.md +402 -0
- package/TENANT_SETUP.md +316 -0
- package/components/BookingFlow/BookingFlow.tsx +790 -0
- package/components/BookingFlow/index.ts +5 -0
- package/components/BookingFlow/steps/AddonsSelection.tsx +118 -0
- package/components/BookingFlow/steps/Confirmation.tsx +185 -0
- package/components/BookingFlow/steps/ContactForm.tsx +292 -0
- package/components/BookingFlow/steps/CycleAwareDateSelection.tsx +277 -0
- package/components/BookingFlow/steps/DateSelection.tsx +473 -0
- package/components/BookingFlow/steps/ServiceSelection.tsx +315 -0
- package/components/BookingFlow/steps/TimeSelection.tsx +230 -0
- package/components/BookingFlow/steps/index.ts +10 -0
- package/components/BottomSheet/index.tsx +120 -0
- package/components/Forms/FormBlock.tsx +283 -0
- package/components/Forms/FormField.tsx +385 -0
- package/components/Forms/FormRenderer.tsx +216 -0
- package/components/Forms/FormValidation.ts +122 -0
- package/components/Forms/index.ts +4 -0
- package/components/HoldTimer/HoldTimer.tsx +266 -0
- package/components/HoldTimer/index.ts +2 -0
- package/components/SectionRenderer.tsx +558 -0
- package/components/Sections/About.tsx +145 -0
- package/components/Sections/BeforeAfter.tsx +81 -0
- package/components/Sections/BookingSection.tsx +76 -0
- package/components/Sections/Contact.tsx +103 -0
- package/components/Sections/FAQSection.tsx +239 -0
- package/components/Sections/FeatureContent.tsx +113 -0
- package/components/Sections/FeaturedLink.tsx +103 -0
- package/components/Sections/FixedInfoCard.tsx +189 -0
- package/components/Sections/Gallery.tsx +83 -0
- package/components/Sections/Header.tsx +78 -0
- package/components/Sections/Hero.tsx +178 -0
- package/components/Sections/ImageSection.tsx +147 -0
- package/components/Sections/InstagramFeed.tsx +38 -0
- package/components/Sections/LinkList.tsx +76 -0
- package/components/Sections/LocationMap.tsx +202 -0
- package/components/Sections/Logo.tsx +61 -0
- package/components/Sections/MinimalFooter.tsx +78 -0
- package/components/Sections/MinimalHeader.tsx +81 -0
- package/components/Sections/MinimalNavigation.tsx +63 -0
- package/components/Sections/Navbar.tsx +258 -0
- package/components/Sections/PricingTable.tsx +106 -0
- package/components/Sections/ScrollingTextDivider.tsx +138 -0
- package/components/Sections/ScrollingTextDivider.tsx.bak +138 -0
- package/components/Sections/ServicesPreview.tsx +129 -0
- package/components/Sections/SocialBar.tsx +177 -0
- package/components/Sections/Team.tsx +80 -0
- package/components/Sections/Testimonials.tsx +92 -0
- package/components/Sections/TextSection.tsx +116 -0
- package/components/Sections/VideoSection.tsx +178 -0
- package/components/Sections/index.ts +57 -0
- package/components/index.ts +21 -0
- package/dist/index-DAai7Glf.d.mts +474 -0
- package/dist/index-DAai7Glf.d.ts +474 -0
- package/dist/index.d.mts +1075 -0
- package/dist/index.d.ts +1075 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +22 -0
- package/dist/index.mjs.map +1 -0
- package/dist/styles/index.d.mts +1 -0
- package/dist/styles/index.d.ts +1 -0
- package/dist/styles/index.js +2 -0
- package/dist/styles/index.js.map +1 -0
- package/dist/styles/index.mjs +2 -0
- package/dist/styles/index.mjs.map +1 -0
- package/docs/API.md +849 -0
- package/docs/CALLBACKS.md +760 -0
- package/docs/COMPLETE_SESSION_SUMMARY.md +404 -0
- package/docs/DATA_SHAPES.md +684 -0
- package/docs/MIGRATION.md +662 -0
- package/docs/PAYMENT_INTEGRATION.md +766 -0
- package/docs/SESSION_SUMMARY.md +185 -0
- package/docs/STYLING.md +735 -0
- package/index.ts +4 -0
- package/lib/storage.ts +239 -0
- package/package.json +59 -0
- package/styles/animations.ts +210 -0
- package/styles/index.ts +1 -0
- package/tsconfig.json +32 -0
- package/tsup.config.ts +13 -0
- package/types/index.ts +369 -0
package/docs/API.md
ADDED
|
@@ -0,0 +1,849 @@
|
|
|
1
|
+
# @oviah/booking-components API Reference
|
|
2
|
+
|
|
3
|
+
Complete API documentation for all components in the OVIAH booking components library.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Section Components](#section-components)
|
|
8
|
+
- [Booking Flow Components](#booking-flow-components)
|
|
9
|
+
- [UI Components](#ui-components)
|
|
10
|
+
- [Common Props](#common-props)
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Section Components
|
|
15
|
+
|
|
16
|
+
### Logo
|
|
17
|
+
|
|
18
|
+
Display a logo or brand mark with customizable size and alignment.
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
import { Logo } from '@oviah/booking-components';
|
|
22
|
+
|
|
23
|
+
<Logo
|
|
24
|
+
logoUrl="https://example.com/logo.png"
|
|
25
|
+
fallbackText="AB"
|
|
26
|
+
size="medium"
|
|
27
|
+
alignment="center"
|
|
28
|
+
colors={{ primary: '#D8C4FF' }}
|
|
29
|
+
/>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Props:**
|
|
33
|
+
- `logoUrl?: string` - URL to logo image
|
|
34
|
+
- `fallbackText?: string` - Text to show if no logo (shows first 2 chars)
|
|
35
|
+
- `size?: 'small' | 'medium' | 'large'` - Logo size (80px/120px/160px)
|
|
36
|
+
- `alignment?: 'left' | 'center' | 'right'` - Horizontal alignment
|
|
37
|
+
- `colors: { primary: string }` - Theme colors
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
### Header
|
|
42
|
+
|
|
43
|
+
Simple text header with name, title, and bio.
|
|
44
|
+
|
|
45
|
+
```tsx
|
|
46
|
+
import { Header } from '@oviah/booking-components';
|
|
47
|
+
|
|
48
|
+
<Header
|
|
49
|
+
name="Jane Doe"
|
|
50
|
+
title="Master Stylist"
|
|
51
|
+
bio="Transform your look ✨"
|
|
52
|
+
showName={true}
|
|
53
|
+
showTitle={true}
|
|
54
|
+
showBio={true}
|
|
55
|
+
colors={{ text: '#000000' }}
|
|
56
|
+
typography={{ headingFont: 'Geist Sans' }}
|
|
57
|
+
/>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Props:**
|
|
61
|
+
- `name?: string` - Display name
|
|
62
|
+
- `title?: string` - Professional title
|
|
63
|
+
- `bio?: string` - Short bio text
|
|
64
|
+
- `showName?: boolean` - Show/hide name
|
|
65
|
+
- `showTitle?: boolean` - Show/hide title
|
|
66
|
+
- `showBio?: boolean` - Show/hide bio
|
|
67
|
+
- `colors: { text: string }` - Text color
|
|
68
|
+
- `typography: { headingFont?: string }` - Font settings
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
### FeaturedLink
|
|
73
|
+
|
|
74
|
+
Large call-to-action button with multiple styles.
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
import { FeaturedLink } from '@oviah/booking-components';
|
|
78
|
+
|
|
79
|
+
<FeaturedLink
|
|
80
|
+
text="💅 Book Now"
|
|
81
|
+
url="/book"
|
|
82
|
+
style="gradient"
|
|
83
|
+
size="large"
|
|
84
|
+
colors={{ primary: '#D8C4FF', secondary: '#014421' }}
|
|
85
|
+
/>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Props:**
|
|
89
|
+
- `text?: string` - Button text
|
|
90
|
+
- `url?: string` - Link URL
|
|
91
|
+
- `style?: 'gradient' | 'solid' | 'outline'` - Visual style
|
|
92
|
+
- `size?: 'small' | 'medium' | 'large'` - Button size
|
|
93
|
+
- `colors: { primary: string; secondary: string }` - Theme colors
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
### LinkList
|
|
98
|
+
|
|
99
|
+
List of clickable links in various styles.
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
import { LinkList } from '@oviah/booking-components';
|
|
103
|
+
|
|
104
|
+
<LinkList
|
|
105
|
+
links={[
|
|
106
|
+
{ id: '1', label: 'Portfolio', url: 'https://example.com' },
|
|
107
|
+
{ id: '2', label: 'Instagram', url: 'https://instagram.com' }
|
|
108
|
+
]}
|
|
109
|
+
style="pill"
|
|
110
|
+
colors={{ primary: '#D8C4FF' }}
|
|
111
|
+
/>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Props:**
|
|
115
|
+
- `links: Link[]` - Array of link objects
|
|
116
|
+
- `id: string` - Unique identifier
|
|
117
|
+
- `label: string` - Link text
|
|
118
|
+
- `url: string` - Link URL
|
|
119
|
+
- `style?: 'pill' | 'square' | 'outline'` - Button style
|
|
120
|
+
- `colors: { primary: string; linkBackground?: string; linkText?: string }`
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
### SocialBar
|
|
125
|
+
|
|
126
|
+
Social media icons with links.
|
|
127
|
+
|
|
128
|
+
```tsx
|
|
129
|
+
import { SocialBar } from '@oviah/booking-components';
|
|
130
|
+
|
|
131
|
+
<SocialBar
|
|
132
|
+
platforms={['instagram', 'facebook', 'tiktok']}
|
|
133
|
+
socialLinks={{
|
|
134
|
+
instagram: 'https://instagram.com/handle',
|
|
135
|
+
facebook: 'https://facebook.com/handle'
|
|
136
|
+
}}
|
|
137
|
+
style="filled"
|
|
138
|
+
size="large"
|
|
139
|
+
position="center"
|
|
140
|
+
colors={{ primary: '#D8C4FF' }}
|
|
141
|
+
/>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Props:**
|
|
145
|
+
- `platforms: string[]` - Array of platform names
|
|
146
|
+
- `socialLinks?: Record<string, string>` - URLs for each platform
|
|
147
|
+
- `style?: 'filled' | 'outline' | 'ghost'` - Icon style
|
|
148
|
+
- `size?: 'small' | 'medium' | 'large'` - Icon size
|
|
149
|
+
- `position?: 'center' | 'left-vertical' | 'right-vertical'` - Layout position
|
|
150
|
+
- `invertIcons?: boolean` - Invert icon colors
|
|
151
|
+
- `colors: { primary: string }`
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
### Hero
|
|
156
|
+
|
|
157
|
+
Large hero section with image and CTA.
|
|
158
|
+
|
|
159
|
+
```tsx
|
|
160
|
+
import { Hero } from '@oviah/booking-components';
|
|
161
|
+
|
|
162
|
+
<Hero
|
|
163
|
+
headline="Welcome to Our Salon"
|
|
164
|
+
subheadline="Professional beauty services"
|
|
165
|
+
heroImage="https://example.com/hero.jpg"
|
|
166
|
+
ctaButton={{ text: 'Book Now', url: '/book' }}
|
|
167
|
+
layout="split"
|
|
168
|
+
imagePosition="right"
|
|
169
|
+
contentDisplay="side"
|
|
170
|
+
colors={{ primary: '#D8C4FF', text: '#000000' }}
|
|
171
|
+
typography={{ headingFont: 'Geist Sans' }}
|
|
172
|
+
/>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
**Props:**
|
|
176
|
+
- `headline?: string` - Main heading
|
|
177
|
+
- `subheadline?: string` - Subheading text
|
|
178
|
+
- `heroImage?: string` - Background/feature image URL
|
|
179
|
+
- `ctaButton?: { text: string; url: string }` - Call-to-action button
|
|
180
|
+
- `layout?: 'split' | 'full'` - Layout type
|
|
181
|
+
- `imagePosition?: 'left' | 'right'` - Image side (split layout)
|
|
182
|
+
- `contentDisplay?: 'side' | 'overlay'` - Text positioning
|
|
183
|
+
- `colors: { primary: string; text: string }`
|
|
184
|
+
- `typography: { headingFont?: string }`
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
### About
|
|
189
|
+
|
|
190
|
+
About section with image and text.
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
import { About } from '@oviah/booking-components';
|
|
194
|
+
|
|
195
|
+
<About
|
|
196
|
+
title="About Us"
|
|
197
|
+
content="Tell your story here..."
|
|
198
|
+
image="https://example.com/about.jpg"
|
|
199
|
+
layout="split"
|
|
200
|
+
colors={{ primary: '#D8C4FF', text: '#000000' }}
|
|
201
|
+
typography={{ headingFont: 'Geist Sans' }}
|
|
202
|
+
/>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**Props:**
|
|
206
|
+
- `title?: string` - Section heading
|
|
207
|
+
- `content?: string` - About text content
|
|
208
|
+
- `image?: string` - Feature image URL
|
|
209
|
+
- `layout?: 'centered' | 'split' | 'wide'` - Layout style
|
|
210
|
+
- `colors: { primary: string; text: string }`
|
|
211
|
+
- `typography: { headingFont?: string }`
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
### ServicesPreview
|
|
216
|
+
|
|
217
|
+
Display service offerings in grid/list/carousel.
|
|
218
|
+
|
|
219
|
+
```tsx
|
|
220
|
+
import { ServicesPreview } from '@oviah/booking-components';
|
|
221
|
+
|
|
222
|
+
<ServicesPreview
|
|
223
|
+
title="Our Services"
|
|
224
|
+
services={[
|
|
225
|
+
{ id: 1, name: 'Haircut', description: '...', price: 75, duration: 60 }
|
|
226
|
+
]}
|
|
227
|
+
layout="grid"
|
|
228
|
+
columns={3}
|
|
229
|
+
showPrices={true}
|
|
230
|
+
showDuration={true}
|
|
231
|
+
colors={{ primary: '#D8C4FF', text: '#000000' }}
|
|
232
|
+
typography={{ headingFont: 'Geist Sans' }}
|
|
233
|
+
/>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
**Props:**
|
|
237
|
+
- `title?: string` - Section heading
|
|
238
|
+
- `services?: Service[]` - Array of service objects
|
|
239
|
+
- `layout?: 'grid' | 'list' | 'carousel'` - Display layout
|
|
240
|
+
- `columns?: 2 | 3 | 4` - Grid columns
|
|
241
|
+
- `showPrices?: boolean` - Show prices
|
|
242
|
+
- `showDuration?: boolean` - Show duration
|
|
243
|
+
- `colors: { primary: string; text: string }`
|
|
244
|
+
- `typography: { headingFont?: string }`
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
### Gallery
|
|
249
|
+
|
|
250
|
+
Image gallery with grid layout.
|
|
251
|
+
|
|
252
|
+
```tsx
|
|
253
|
+
import { Gallery } from '@oviah/booking-components';
|
|
254
|
+
|
|
255
|
+
<Gallery
|
|
256
|
+
title="Gallery"
|
|
257
|
+
images={[
|
|
258
|
+
{ id: '1', url: 'https://example.com/1.jpg', alt: 'Photo 1' }
|
|
259
|
+
]}
|
|
260
|
+
columns={3}
|
|
261
|
+
colors={{ primary: '#D8C4FF', text: '#000000' }}
|
|
262
|
+
typography={{ headingFont: 'Geist Sans' }}
|
|
263
|
+
/>
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
**Props:**
|
|
267
|
+
- `title?: string` - Section heading
|
|
268
|
+
- `images?: GalleryImage[]` - Array of image objects
|
|
269
|
+
- `columns?: 2 | 3 | 4` - Grid columns
|
|
270
|
+
- `colors: { primary: string; text: string }`
|
|
271
|
+
- `typography: { headingFont?: string }`
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
### Testimonials
|
|
276
|
+
|
|
277
|
+
Client testimonials with star ratings.
|
|
278
|
+
|
|
279
|
+
```tsx
|
|
280
|
+
import { Testimonials } from '@oviah/booking-components';
|
|
281
|
+
|
|
282
|
+
<Testimonials
|
|
283
|
+
title="What Clients Say"
|
|
284
|
+
testimonials={[
|
|
285
|
+
{ id: 1, text: 'Amazing!', author: 'Sarah M.', rating: 5 }
|
|
286
|
+
]}
|
|
287
|
+
layout="grid"
|
|
288
|
+
colors={{ primary: '#D8C4FF', text: '#000000' }}
|
|
289
|
+
typography={{ headingFont: 'Geist Sans' }}
|
|
290
|
+
/>
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
**Props:**
|
|
294
|
+
- `title?: string` - Section heading
|
|
295
|
+
- `testimonials?: Testimonial[]` - Array of testimonial objects
|
|
296
|
+
- `layout?: 'grid' | 'carousel'` - Display layout
|
|
297
|
+
- `colors: { primary: string; text: string }`
|
|
298
|
+
- `typography: { headingFont?: string }`
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
### Team
|
|
303
|
+
|
|
304
|
+
Team member showcase section.
|
|
305
|
+
|
|
306
|
+
**Props:** See Team.tsx for complete props interface
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
### Contact
|
|
311
|
+
|
|
312
|
+
Contact information and form section.
|
|
313
|
+
|
|
314
|
+
**Props:** See Contact.tsx for complete props interface
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
### MinimalHeader
|
|
319
|
+
|
|
320
|
+
Minimal sticky header with logo/text.
|
|
321
|
+
|
|
322
|
+
**Props:** See MinimalHeader.tsx for complete props interface
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
### MinimalNavigation
|
|
327
|
+
|
|
328
|
+
Clean navigation links (horizontal/vertical).
|
|
329
|
+
|
|
330
|
+
**Props:** See MinimalNavigation.tsx for complete props interface
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
### MinimalFooter
|
|
335
|
+
|
|
336
|
+
Footer with social links and contact info.
|
|
337
|
+
|
|
338
|
+
**Props:** See MinimalFooter.tsx for complete props interface
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
### FeatureContent
|
|
343
|
+
|
|
344
|
+
Feature content with image and text.
|
|
345
|
+
|
|
346
|
+
**Props:** See FeatureContent.tsx for complete props interface
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
### BeforeAfter
|
|
351
|
+
|
|
352
|
+
Before/after comparison section.
|
|
353
|
+
|
|
354
|
+
**Props:** See BeforeAfter.tsx for complete props interface
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
### PricingTable
|
|
359
|
+
|
|
360
|
+
Pricing plans in grid layout.
|
|
361
|
+
|
|
362
|
+
**Props:** See PricingTable.tsx for complete props interface
|
|
363
|
+
|
|
364
|
+
---
|
|
365
|
+
|
|
366
|
+
### InstagramFeed
|
|
367
|
+
|
|
368
|
+
Instagram feed grid display.
|
|
369
|
+
|
|
370
|
+
**Props:** See InstagramFeed.tsx for complete props interface
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
### FixedInfoCard
|
|
375
|
+
|
|
376
|
+
Fixed info card pinned to page corners.
|
|
377
|
+
|
|
378
|
+
```tsx
|
|
379
|
+
import { FixedInfoCard } from '@oviah/booking-components';
|
|
380
|
+
|
|
381
|
+
<FixedInfoCard
|
|
382
|
+
name="Jane Doe"
|
|
383
|
+
subheading="Master Stylist"
|
|
384
|
+
bio="Transform your look ✨"
|
|
385
|
+
links={[
|
|
386
|
+
{ id: '1', label: 'Portfolio', url: 'https://example.com' }
|
|
387
|
+
]}
|
|
388
|
+
bookingButtonText="Book Now"
|
|
389
|
+
bookingButtonUrl="/book"
|
|
390
|
+
showBookingButton={true}
|
|
391
|
+
position="bottom-left"
|
|
392
|
+
cardWidth="medium"
|
|
393
|
+
cardColor="#FFFFFF"
|
|
394
|
+
colors={{ primary: '#D8C4FF', text: '#000000', buttonText: '#FFFFFF' }}
|
|
395
|
+
typography={{ headingFont: 'Geist Sans' }}
|
|
396
|
+
/>
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
**Props:** See FixedInfoCard.tsx for complete props interface
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
### BookingSection
|
|
404
|
+
|
|
405
|
+
Wrapper section for embedding booking flows.
|
|
406
|
+
|
|
407
|
+
```tsx
|
|
408
|
+
import { BookingSection } from '@oviah/booking-components';
|
|
409
|
+
import { BookingFlowPreview } from './your-booking-flow';
|
|
410
|
+
|
|
411
|
+
<BookingSection
|
|
412
|
+
config={{
|
|
413
|
+
theme: {
|
|
414
|
+
colors: { primary: '#D8C4FF', secondary: '#014421', text: '#000000' },
|
|
415
|
+
typography: { headingFont: 'Geist Sans' }
|
|
416
|
+
},
|
|
417
|
+
bookingSettings: { /* your booking settings */ }
|
|
418
|
+
}}
|
|
419
|
+
colors={{ primary: '#D8C4FF', secondary: '#014421', text: '#000000' }}
|
|
420
|
+
BookingFlowComponent={BookingFlowPreview}
|
|
421
|
+
/>
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
**Props:**
|
|
425
|
+
- `config: BookingConfig` - Full booking configuration object
|
|
426
|
+
- `colors: { primary: string; secondary: string; text: string; bookingText?: string }` - Theme colors
|
|
427
|
+
- `BookingFlowComponent?: React.ComponentType` - Optional custom booking flow component
|
|
428
|
+
|
|
429
|
+
---
|
|
430
|
+
|
|
431
|
+
## Section Renderer
|
|
432
|
+
|
|
433
|
+
### SectionRenderer
|
|
434
|
+
|
|
435
|
+
Universal renderer that dynamically renders any section type from configuration.
|
|
436
|
+
|
|
437
|
+
```tsx
|
|
438
|
+
import { SectionRenderer } from '@oviah/booking-components';
|
|
439
|
+
|
|
440
|
+
// Render a hero section
|
|
441
|
+
<SectionRenderer
|
|
442
|
+
section={{
|
|
443
|
+
id: 'hero-1',
|
|
444
|
+
type: 'hero',
|
|
445
|
+
settings: {
|
|
446
|
+
headline: 'Welcome to Our Salon',
|
|
447
|
+
subheadline: 'Professional beauty services',
|
|
448
|
+
heroImage: '/hero.jpg',
|
|
449
|
+
layout: 'split',
|
|
450
|
+
imagePosition: 'right'
|
|
451
|
+
},
|
|
452
|
+
enabled: true,
|
|
453
|
+
position: 0
|
|
454
|
+
}}
|
|
455
|
+
theme={{
|
|
456
|
+
colors: {
|
|
457
|
+
primary: '#D8C4FF',
|
|
458
|
+
secondary: '#014421',
|
|
459
|
+
text: '#000000'
|
|
460
|
+
},
|
|
461
|
+
typography: {
|
|
462
|
+
headingFont: 'Geist Sans',
|
|
463
|
+
bodyFont: 'Inter',
|
|
464
|
+
bodySize: '16px'
|
|
465
|
+
}
|
|
466
|
+
}}
|
|
467
|
+
/>
|
|
468
|
+
|
|
469
|
+
// Render a booking section with custom flow component
|
|
470
|
+
<SectionRenderer
|
|
471
|
+
section={{
|
|
472
|
+
id: 'booking-1',
|
|
473
|
+
type: 'booking',
|
|
474
|
+
settings: {},
|
|
475
|
+
enabled: true,
|
|
476
|
+
position: 5
|
|
477
|
+
}}
|
|
478
|
+
theme={theme}
|
|
479
|
+
config={fullConfig}
|
|
480
|
+
BookingFlowComponent={YourBookingFlow}
|
|
481
|
+
/>
|
|
482
|
+
|
|
483
|
+
// Render from a dynamic sections array
|
|
484
|
+
{sections.map((section) => (
|
|
485
|
+
<SectionRenderer
|
|
486
|
+
key={section.id}
|
|
487
|
+
section={section}
|
|
488
|
+
theme={theme}
|
|
489
|
+
/>
|
|
490
|
+
))}
|
|
491
|
+
|
|
492
|
+
// Enable inline editing mode (for Studio preview)
|
|
493
|
+
<SectionRenderer
|
|
494
|
+
section={section}
|
|
495
|
+
theme={theme}
|
|
496
|
+
enableInlineEditing={true} // Adds data-editable, data-section-id, data-field-path
|
|
497
|
+
/>
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
**Props:**
|
|
501
|
+
- `section: Section` - Section configuration object
|
|
502
|
+
- `id: string` - Unique section ID
|
|
503
|
+
- `type: string` - Section type (hero, about, gallery, etc.)
|
|
504
|
+
- `settings: any` - Type-specific settings
|
|
505
|
+
- `enabled?: boolean` - Whether section is enabled
|
|
506
|
+
- `position?: number` - Sort order
|
|
507
|
+
- `theme: Theme` - Theme configuration
|
|
508
|
+
- `colors: ColorScheme` - Color palette
|
|
509
|
+
- `typography: TypographyConfig` - Font settings
|
|
510
|
+
- `enableInlineEditing?: boolean` - Enable inline editing mode (adds data-editable attributes)
|
|
511
|
+
- `BookingFlowComponent?: React.ComponentType` - Custom booking flow (for 'booking' type)
|
|
512
|
+
- `config?: any` - Full app config (for 'booking' type)
|
|
513
|
+
|
|
514
|
+
**Supported Section Types:**
|
|
515
|
+
- `logo` - Logo/brand mark
|
|
516
|
+
- `header` - Text header (name, title, bio)
|
|
517
|
+
- `featured_link` - Large CTA button
|
|
518
|
+
- `link_list` - List of links
|
|
519
|
+
- `social_bar` - Social media icons
|
|
520
|
+
- `instagram_feed` - Instagram grid
|
|
521
|
+
- `minimal_header` - Sticky header
|
|
522
|
+
- `minimal_navigation` - Navigation links
|
|
523
|
+
- `minimal_footer` - Footer section
|
|
524
|
+
- `feature_content` - Feature with image/text
|
|
525
|
+
- `hero` - Hero section
|
|
526
|
+
- `about` - About section
|
|
527
|
+
- `services_preview` - Services grid/list
|
|
528
|
+
- `gallery` - Image gallery
|
|
529
|
+
- `testimonials` - Client testimonials
|
|
530
|
+
- `team` - Team members
|
|
531
|
+
- `contact` - Contact info/form
|
|
532
|
+
- `before_after` - Before/after comparisons
|
|
533
|
+
- `pricing_table` - Pricing plans
|
|
534
|
+
- `booking` - Booking flow wrapper
|
|
535
|
+
- `fixed_info_card` - Fixed corner card
|
|
536
|
+
|
|
537
|
+
**Benefits:**
|
|
538
|
+
- ✅ Single component for all section types
|
|
539
|
+
- ✅ Type-safe section configuration
|
|
540
|
+
- ✅ Automatic prop mapping
|
|
541
|
+
- ✅ Theme inheritance
|
|
542
|
+
- ✅ Unknown type handling (renders placeholder)
|
|
543
|
+
|
|
544
|
+
---
|
|
545
|
+
|
|
546
|
+
## Booking Flow Orchestrator
|
|
547
|
+
|
|
548
|
+
### BookingFlow
|
|
549
|
+
|
|
550
|
+
Main orchestrator component that manages the entire booking flow with state and navigation.
|
|
551
|
+
|
|
552
|
+
```tsx
|
|
553
|
+
import { BookingFlow } from '@oviah/booking-components';
|
|
554
|
+
|
|
555
|
+
<BookingFlow
|
|
556
|
+
config={{
|
|
557
|
+
steps: {
|
|
558
|
+
service_selection: { enabled: true, settings: { ... } },
|
|
559
|
+
date_selection: { enabled: true, settings: { ... } },
|
|
560
|
+
time_selection: { enabled: true, settings: { ... } },
|
|
561
|
+
addon_selection: { enabled: true, settings: { ... } },
|
|
562
|
+
contact_form: { enabled: true, settings: { ... } }
|
|
563
|
+
},
|
|
564
|
+
progressBar: { style: 'dots' },
|
|
565
|
+
transitions: { style: 'slide', speed: 'normal' },
|
|
566
|
+
background: { type: 'color', value: '#FFFFFF' }
|
|
567
|
+
}}
|
|
568
|
+
colors={{
|
|
569
|
+
primary: '#D8C4FF',
|
|
570
|
+
secondary: '#014421',
|
|
571
|
+
text: '#000000'
|
|
572
|
+
}}
|
|
573
|
+
services={services}
|
|
574
|
+
categories={categories}
|
|
575
|
+
dates={availableDates}
|
|
576
|
+
times={availableTimes}
|
|
577
|
+
addons={addons}
|
|
578
|
+
onComplete={(bookingData) => {
|
|
579
|
+
console.log('Booking complete!', bookingData);
|
|
580
|
+
// Submit to backend
|
|
581
|
+
}}
|
|
582
|
+
onStepChange={(index, stepId) => {
|
|
583
|
+
console.log('Changed to step:', stepId);
|
|
584
|
+
}}
|
|
585
|
+
/>
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
**Props:**
|
|
589
|
+
- `config: BookingFlowConfig` - Flow configuration
|
|
590
|
+
- `steps` - Enable/disable and configure each step
|
|
591
|
+
- `progressBar.style?: 'dots' | 'bar' | 'minimal'` - Progress indicator style
|
|
592
|
+
- `transitions.style?: 'slide' | 'fade'` - Step transition animation
|
|
593
|
+
- `transitions.speed?: 'fast' | 'normal' | 'slow'` - Animation speed
|
|
594
|
+
- `background` - Background styling
|
|
595
|
+
- `colors: ColorScheme` - Theme colors
|
|
596
|
+
- `services?: any[]` - Available services (for service selection step)
|
|
597
|
+
- `categories?: any[]` - Service categories
|
|
598
|
+
- `dates?: string[]` - Available dates (for date selection step)
|
|
599
|
+
- `times?: string[]` - Available times (for time selection step)
|
|
600
|
+
- `addons?: any[]` - Add-on services (for addons step)
|
|
601
|
+
- `onComplete?: (bookingData) => void` - Called when booking is completed
|
|
602
|
+
- `onStepChange?: (stepIndex, stepId) => void` - Called on step navigation
|
|
603
|
+
- `validateStep?: (stepId, data) => boolean` - Custom step validation
|
|
604
|
+
|
|
605
|
+
**Features:**
|
|
606
|
+
- ✅ Automatic step state management
|
|
607
|
+
- ✅ Built-in navigation with validation
|
|
608
|
+
- ✅ Smooth animated transitions
|
|
609
|
+
- ✅ Progress indicator (dots/bar/minimal)
|
|
610
|
+
- ✅ Responsive layout
|
|
611
|
+
- ✅ Accessibility support
|
|
612
|
+
- ✅ Custom validation hooks
|
|
613
|
+
|
|
614
|
+
**Booking Data Structure:**
|
|
615
|
+
```typescript
|
|
616
|
+
{
|
|
617
|
+
service: string | null; // Selected service ID
|
|
618
|
+
date: string | null; // Selected date
|
|
619
|
+
time: string | null; // Selected time slot
|
|
620
|
+
addons: string[]; // Selected addon IDs
|
|
621
|
+
contact: { // Contact information
|
|
622
|
+
name: string;
|
|
623
|
+
email: string;
|
|
624
|
+
phone: string;
|
|
625
|
+
notes?: string;
|
|
626
|
+
};
|
|
627
|
+
optIn: any; // Opt-in module data
|
|
628
|
+
}
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
---
|
|
632
|
+
|
|
633
|
+
## Booking Flow Components
|
|
634
|
+
|
|
635
|
+
### ServiceSelection
|
|
636
|
+
|
|
637
|
+
Select a service from available options.
|
|
638
|
+
|
|
639
|
+
```tsx
|
|
640
|
+
import { ServiceSelection } from '@oviah/booking-components';
|
|
641
|
+
|
|
642
|
+
<ServiceSelection
|
|
643
|
+
services={services}
|
|
644
|
+
categories={categories}
|
|
645
|
+
selectedService={selectedId}
|
|
646
|
+
onServiceSelect={(id) => setSelectedId(id)}
|
|
647
|
+
settings={{
|
|
648
|
+
headerContent: { value: 'Choose Your Service' },
|
|
649
|
+
serviceLayout: 'grid',
|
|
650
|
+
columns: 2
|
|
651
|
+
}}
|
|
652
|
+
colors={{ primary: '#D8C4FF', secondary: '#014421' }}
|
|
653
|
+
/>
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
**Props:** See `types/index.ts` for full `ServiceSelectionStepProps`
|
|
657
|
+
|
|
658
|
+
---
|
|
659
|
+
|
|
660
|
+
### DateSelection
|
|
661
|
+
|
|
662
|
+
Pick appointment date from calendar.
|
|
663
|
+
|
|
664
|
+
```tsx
|
|
665
|
+
import { DateSelection } from '@oviah/booking-components';
|
|
666
|
+
|
|
667
|
+
<DateSelection
|
|
668
|
+
availableDates={['2025-01-15', '2025-01-16']}
|
|
669
|
+
selectedDate={selected}
|
|
670
|
+
onDateSelect={setSelected}
|
|
671
|
+
settings={{ calendarView: 'month' }}
|
|
672
|
+
colors={{ primary: '#D8C4FF', secondary: '#014421' }}
|
|
673
|
+
/>
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
---
|
|
677
|
+
|
|
678
|
+
### TimeSelection
|
|
679
|
+
|
|
680
|
+
Choose appointment time slot.
|
|
681
|
+
|
|
682
|
+
```tsx
|
|
683
|
+
import { TimeSelection } from '@oviah/booking-components';
|
|
684
|
+
|
|
685
|
+
<TimeSelection
|
|
686
|
+
availableTimes={['9:00 AM', '10:00 AM', '11:00 AM']}
|
|
687
|
+
selectedTime={selected}
|
|
688
|
+
onTimeSelect={setSelected}
|
|
689
|
+
settings={{ timeFormat: '12h', columns: 3 }}
|
|
690
|
+
serviceDuration={60}
|
|
691
|
+
colors={{ primary: '#D8C4FF', secondary: '#014421' }}
|
|
692
|
+
/>
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
---
|
|
696
|
+
|
|
697
|
+
### AddonsSelection
|
|
698
|
+
|
|
699
|
+
Select optional add-on services.
|
|
700
|
+
|
|
701
|
+
```tsx
|
|
702
|
+
import { AddonsSelection } from '@oviah/booking-components';
|
|
703
|
+
|
|
704
|
+
<AddonsSelection
|
|
705
|
+
addons={addons}
|
|
706
|
+
selectedAddons={selected}
|
|
707
|
+
onAddonsChange={setSelected}
|
|
708
|
+
settings={{ showPricing: true, showDuration: true }}
|
|
709
|
+
colors={{ primary: '#D8C4FF', secondary: '#014421' }}
|
|
710
|
+
/>
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
---
|
|
714
|
+
|
|
715
|
+
### ContactForm
|
|
716
|
+
|
|
717
|
+
Collect customer contact information.
|
|
718
|
+
|
|
719
|
+
```tsx
|
|
720
|
+
import { ContactForm } from '@oviah/booking-components';
|
|
721
|
+
|
|
722
|
+
<ContactForm
|
|
723
|
+
contactInfo={info}
|
|
724
|
+
onContactInfoChange={setInfo}
|
|
725
|
+
settings={{ headerContent: { value: 'Your Information' } }}
|
|
726
|
+
optInModules={modules}
|
|
727
|
+
onOptInData={handleOptIn}
|
|
728
|
+
colors={{ primary: '#D8C4FF', secondary: '#014421' }}
|
|
729
|
+
/>
|
|
730
|
+
```
|
|
731
|
+
|
|
732
|
+
---
|
|
733
|
+
|
|
734
|
+
### Confirmation
|
|
735
|
+
|
|
736
|
+
Review and confirm booking with payment.
|
|
737
|
+
|
|
738
|
+
```tsx
|
|
739
|
+
import { Confirmation } from '@oviah/booking-components';
|
|
740
|
+
|
|
741
|
+
<Confirmation
|
|
742
|
+
service={selectedService}
|
|
743
|
+
addons={selectedAddons}
|
|
744
|
+
selectedDate="2025-01-15"
|
|
745
|
+
selectedTime="10:00 AM"
|
|
746
|
+
paymentProvider="square"
|
|
747
|
+
paymentConfig={{ depositPercentage: 20 }}
|
|
748
|
+
onConfirm={handleConfirm}
|
|
749
|
+
colors={{ primary: '#D8C4FF', secondary: '#014421' }}
|
|
750
|
+
/>
|
|
751
|
+
```
|
|
752
|
+
|
|
753
|
+
---
|
|
754
|
+
|
|
755
|
+
## UI Components
|
|
756
|
+
|
|
757
|
+
### BottomSheet
|
|
758
|
+
|
|
759
|
+
Slide-up modal for forms and content.
|
|
760
|
+
|
|
761
|
+
```tsx
|
|
762
|
+
import { BottomSheet } from '@oviah/booking-components';
|
|
763
|
+
|
|
764
|
+
<BottomSheet
|
|
765
|
+
isOpen={isOpen}
|
|
766
|
+
onClose={() => setIsOpen(false)}
|
|
767
|
+
title="Form Title"
|
|
768
|
+
isRequired={false}
|
|
769
|
+
maxHeight="80vh"
|
|
770
|
+
>
|
|
771
|
+
<YourFormContent />
|
|
772
|
+
</BottomSheet>
|
|
773
|
+
```
|
|
774
|
+
|
|
775
|
+
**Props:**
|
|
776
|
+
- `isOpen: boolean` - Control visibility
|
|
777
|
+
- `onClose: () => void` - Close handler
|
|
778
|
+
- `title?: string` - Modal title
|
|
779
|
+
- `children: React.ReactNode` - Modal content
|
|
780
|
+
- `isRequired?: boolean` - Prevent closing (no close button/escape)
|
|
781
|
+
- `maxHeight?: string` - Maximum height (default: 80vh)
|
|
782
|
+
|
|
783
|
+
---
|
|
784
|
+
|
|
785
|
+
## Common Props
|
|
786
|
+
|
|
787
|
+
### Colors Object
|
|
788
|
+
|
|
789
|
+
```typescript
|
|
790
|
+
{
|
|
791
|
+
primary: string; // Main brand color
|
|
792
|
+
secondary: string; // Secondary brand color
|
|
793
|
+
text: string; // Text color
|
|
794
|
+
bookingText?: string; // Booking widget text
|
|
795
|
+
linkBackground?: string;// Link button background
|
|
796
|
+
linkText?: string; // Link button text
|
|
797
|
+
buttonText?: string; // Button text color
|
|
798
|
+
}
|
|
799
|
+
```
|
|
800
|
+
|
|
801
|
+
### Typography Object
|
|
802
|
+
|
|
803
|
+
```typescript
|
|
804
|
+
{
|
|
805
|
+
headingFont?: string; // Font family for headings
|
|
806
|
+
bodyFont?: string; // Font family for body text
|
|
807
|
+
bodySize?: string; // Base font size
|
|
808
|
+
}
|
|
809
|
+
```
|
|
810
|
+
|
|
811
|
+
### Settings Object
|
|
812
|
+
|
|
813
|
+
Each step/section has specific settings. See `types/index.ts` for complete definitions.
|
|
814
|
+
|
|
815
|
+
---
|
|
816
|
+
|
|
817
|
+
## Animation Utilities
|
|
818
|
+
|
|
819
|
+
Import animation helpers for consistent motion:
|
|
820
|
+
|
|
821
|
+
```tsx
|
|
822
|
+
import {
|
|
823
|
+
getSlideVariants,
|
|
824
|
+
getFadeVariants,
|
|
825
|
+
animations,
|
|
826
|
+
createEntranceAnimation,
|
|
827
|
+
shouldReduceMotion
|
|
828
|
+
} from '@oviah/booking-components/styles';
|
|
829
|
+
|
|
830
|
+
// Use with Framer Motion
|
|
831
|
+
<motion.div {...createEntranceAnimation(0.1)}>
|
|
832
|
+
Content
|
|
833
|
+
</motion.div>
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
**Available Functions:**
|
|
837
|
+
- `getAnimationDuration(speed, reducedMotion)` - Calculate animation duration
|
|
838
|
+
- `getSlideVariants(distance)` - Slide transition variants
|
|
839
|
+
- `getFadeVariants()` - Fade transition variants
|
|
840
|
+
- `getTransitionVariants(style, distance)` - Get variants by type
|
|
841
|
+
- `createEntranceAnimation(delay, duration)` - Entry animation config
|
|
842
|
+
- `createStaggerAnimation(count, baseDelay, increment)` - Stagger list items
|
|
843
|
+
- `shouldReduceMotion()` - Check reduced motion preference
|
|
844
|
+
|
|
845
|
+
---
|
|
846
|
+
|
|
847
|
+
## Full Type Definitions
|
|
848
|
+
|
|
849
|
+
See `types/index.ts` for complete TypeScript definitions of all props, interfaces, and types.
|