@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.
Files changed (83) hide show
  1. package/README.md +319 -0
  2. package/TENANT_DATA_INTEGRATION.md +402 -0
  3. package/TENANT_SETUP.md +316 -0
  4. package/components/BookingFlow/BookingFlow.tsx +790 -0
  5. package/components/BookingFlow/index.ts +5 -0
  6. package/components/BookingFlow/steps/AddonsSelection.tsx +118 -0
  7. package/components/BookingFlow/steps/Confirmation.tsx +185 -0
  8. package/components/BookingFlow/steps/ContactForm.tsx +292 -0
  9. package/components/BookingFlow/steps/CycleAwareDateSelection.tsx +277 -0
  10. package/components/BookingFlow/steps/DateSelection.tsx +473 -0
  11. package/components/BookingFlow/steps/ServiceSelection.tsx +315 -0
  12. package/components/BookingFlow/steps/TimeSelection.tsx +230 -0
  13. package/components/BookingFlow/steps/index.ts +10 -0
  14. package/components/BottomSheet/index.tsx +120 -0
  15. package/components/Forms/FormBlock.tsx +283 -0
  16. package/components/Forms/FormField.tsx +385 -0
  17. package/components/Forms/FormRenderer.tsx +216 -0
  18. package/components/Forms/FormValidation.ts +122 -0
  19. package/components/Forms/index.ts +4 -0
  20. package/components/HoldTimer/HoldTimer.tsx +266 -0
  21. package/components/HoldTimer/index.ts +2 -0
  22. package/components/SectionRenderer.tsx +558 -0
  23. package/components/Sections/About.tsx +145 -0
  24. package/components/Sections/BeforeAfter.tsx +81 -0
  25. package/components/Sections/BookingSection.tsx +76 -0
  26. package/components/Sections/Contact.tsx +103 -0
  27. package/components/Sections/FAQSection.tsx +239 -0
  28. package/components/Sections/FeatureContent.tsx +113 -0
  29. package/components/Sections/FeaturedLink.tsx +103 -0
  30. package/components/Sections/FixedInfoCard.tsx +189 -0
  31. package/components/Sections/Gallery.tsx +83 -0
  32. package/components/Sections/Header.tsx +78 -0
  33. package/components/Sections/Hero.tsx +178 -0
  34. package/components/Sections/ImageSection.tsx +147 -0
  35. package/components/Sections/InstagramFeed.tsx +38 -0
  36. package/components/Sections/LinkList.tsx +76 -0
  37. package/components/Sections/LocationMap.tsx +202 -0
  38. package/components/Sections/Logo.tsx +61 -0
  39. package/components/Sections/MinimalFooter.tsx +78 -0
  40. package/components/Sections/MinimalHeader.tsx +81 -0
  41. package/components/Sections/MinimalNavigation.tsx +63 -0
  42. package/components/Sections/Navbar.tsx +258 -0
  43. package/components/Sections/PricingTable.tsx +106 -0
  44. package/components/Sections/ScrollingTextDivider.tsx +138 -0
  45. package/components/Sections/ScrollingTextDivider.tsx.bak +138 -0
  46. package/components/Sections/ServicesPreview.tsx +129 -0
  47. package/components/Sections/SocialBar.tsx +177 -0
  48. package/components/Sections/Team.tsx +80 -0
  49. package/components/Sections/Testimonials.tsx +92 -0
  50. package/components/Sections/TextSection.tsx +116 -0
  51. package/components/Sections/VideoSection.tsx +178 -0
  52. package/components/Sections/index.ts +57 -0
  53. package/components/index.ts +21 -0
  54. package/dist/index-DAai7Glf.d.mts +474 -0
  55. package/dist/index-DAai7Glf.d.ts +474 -0
  56. package/dist/index.d.mts +1075 -0
  57. package/dist/index.d.ts +1075 -0
  58. package/dist/index.js +22 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/index.mjs +22 -0
  61. package/dist/index.mjs.map +1 -0
  62. package/dist/styles/index.d.mts +1 -0
  63. package/dist/styles/index.d.ts +1 -0
  64. package/dist/styles/index.js +2 -0
  65. package/dist/styles/index.js.map +1 -0
  66. package/dist/styles/index.mjs +2 -0
  67. package/dist/styles/index.mjs.map +1 -0
  68. package/docs/API.md +849 -0
  69. package/docs/CALLBACKS.md +760 -0
  70. package/docs/COMPLETE_SESSION_SUMMARY.md +404 -0
  71. package/docs/DATA_SHAPES.md +684 -0
  72. package/docs/MIGRATION.md +662 -0
  73. package/docs/PAYMENT_INTEGRATION.md +766 -0
  74. package/docs/SESSION_SUMMARY.md +185 -0
  75. package/docs/STYLING.md +735 -0
  76. package/index.ts +4 -0
  77. package/lib/storage.ts +239 -0
  78. package/package.json +59 -0
  79. package/styles/animations.ts +210 -0
  80. package/styles/index.ts +1 -0
  81. package/tsconfig.json +32 -0
  82. package/tsup.config.ts +13 -0
  83. package/types/index.ts +369 -0
@@ -0,0 +1,662 @@
1
+ # Migration Guide
2
+
3
+ Guide for migrating from inline components to the `@oviah/booking-components` package.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Why Migrate?](#why-migrate)
8
+ - [Before You Start](#before-you-start)
9
+ - [Migration Steps](#migration-steps)
10
+ - [Breaking Changes](#breaking-changes)
11
+ - [Troubleshooting](#troubleshooting)
12
+
13
+ ---
14
+
15
+ ## Why Migrate?
16
+
17
+ ### Benefits
18
+
19
+ ✅ **Reusability** - Use components across dashboard and tenant apps
20
+ ✅ **Maintainability** - Single source of truth for updates
21
+ ✅ **Type Safety** - Full TypeScript support
22
+ ✅ **Performance** - Optimized bundle size
23
+ ✅ **Testing** - Easier to test isolated components
24
+ ✅ **Documentation** - Comprehensive API docs
25
+
26
+ ### What's Different?
27
+
28
+ | Old (Inline) | New (Package) |
29
+ |--------------|---------------|
30
+ | Components in page files | Separate package |
31
+ | Props passed directly | Structured config objects |
32
+ | Scattered settings | Centralized configuration |
33
+ | Duplicate code | Shared components |
34
+ | Hard to maintain | Easy updates |
35
+
36
+ ---
37
+
38
+ ## Before You Start
39
+
40
+ ### 1. Check Your Current Implementation
41
+
42
+ Identify which components you're using:
43
+
44
+ ```tsx
45
+ // Old: src/app/[businessId]/page.tsx
46
+ function SectionRenderer({ section, theme }) {
47
+ switch (section.type) {
48
+ case 'logo':
49
+ // Inline logo rendering
50
+ return <div>...</div>;
51
+ case 'hero':
52
+ // Inline hero rendering
53
+ return <div>...</div>;
54
+ // ... more cases
55
+ }
56
+ }
57
+ ```
58
+
59
+ ### 2. Review Your Configuration
60
+
61
+ Document your current config structure:
62
+
63
+ ```typescript
64
+ const currentConfig = {
65
+ sections: [...], // What sections do you have?
66
+ theme: {...}, // What colors/fonts?
67
+ bookingFlow: {...} // What booking steps?
68
+ };
69
+ ```
70
+
71
+ ### 3. Backup Your Code
72
+
73
+ ```bash
74
+ git checkout -b backup-before-migration
75
+ git add .
76
+ git commit -m "Backup before component migration"
77
+ ```
78
+
79
+ ---
80
+
81
+ ## Migration Steps
82
+
83
+ ### Step 1: Install the Package
84
+
85
+ ```bash
86
+ # From the root of your monorepo
87
+ npm install
88
+ # The package is already in your workspace
89
+ ```
90
+
91
+ ### Step 2: Update Imports
92
+
93
+ #### Before (Inline Components)
94
+
95
+ ```tsx
96
+ // src/app/[businessId]/page.tsx
97
+ 'use client';
98
+
99
+ import { useState } from 'react';
100
+ import BookingFlowPreview from '@/components/preview/BookingFlowPreview';
101
+
102
+ function SectionRenderer({ section, theme }) {
103
+ // 1000+ lines of inline rendering logic
104
+ }
105
+
106
+ export default function TenantPage() {
107
+ // Component logic
108
+ }
109
+ ```
110
+
111
+ #### After (Package Components)
112
+
113
+ ```tsx
114
+ // src/app/[businessId]/page.tsx
115
+ 'use client';
116
+
117
+ import { SectionRenderer, BookingFlow } from '@oviah/booking-components';
118
+
119
+ export default function TenantPage() {
120
+ // Much cleaner!
121
+ }
122
+ ```
123
+
124
+ ---
125
+
126
+ ### Step 3: Migrate Section Rendering
127
+
128
+ #### Before
129
+
130
+ ```tsx
131
+ function SectionRenderer({ section, theme }) {
132
+ const { type, settings } = section;
133
+ const colors = theme?.colors || {};
134
+
135
+ switch (type) {
136
+ case 'logo':
137
+ return (
138
+ <div className="container mx-auto px-4">
139
+ {settings.logoUrl ? (
140
+ <img src={settings.logoUrl} alt="Logo" />
141
+ ) : (
142
+ <div>{settings.fallbackText}</div>
143
+ )}
144
+ </div>
145
+ );
146
+
147
+ case 'hero':
148
+ return (
149
+ <div className="hero">
150
+ <h1>{settings.headline}</h1>
151
+ <p>{settings.subheadline}</p>
152
+ {/* ... more JSX */}
153
+ </div>
154
+ );
155
+
156
+ // ... 20 more cases
157
+ }
158
+ }
159
+ ```
160
+
161
+ #### After
162
+
163
+ ```tsx
164
+ import { SectionRenderer } from '@oviah/booking-components';
165
+
166
+ // Just pass section and theme - that's it!
167
+ <SectionRenderer
168
+ section={section}
169
+ theme={theme}
170
+ />
171
+ ```
172
+
173
+ **That's a reduction from 1000+ lines to 5 lines!** 🎉
174
+
175
+ ---
176
+
177
+ ### Step 4: Migrate Booking Flow
178
+
179
+ #### Before
180
+
181
+ ```tsx
182
+ // src/components/preview/BookingFlowPreview.tsx (1200+ lines)
183
+ export default function BookingFlowPreview({ config, colors }) {
184
+ const [currentStep, setCurrentStep] = useState(0);
185
+ const [selectedService, setSelectedService] = useState(null);
186
+ const [selectedDate, setSelectedDate] = useState(null);
187
+ // ... 50+ state variables
188
+
189
+ const renderServiceSelection = () => {
190
+ // 200+ lines of JSX
191
+ };
192
+
193
+ const renderDateSelection = () => {
194
+ // 150+ lines of JSX
195
+ };
196
+
197
+ // ... more render functions
198
+
199
+ return (
200
+ <div>
201
+ {/* Complex flow logic */}
202
+ </div>
203
+ );
204
+ }
205
+ ```
206
+
207
+ #### After
208
+
209
+ ```tsx
210
+ import { BookingFlow } from '@oviah/booking-components';
211
+
212
+ <BookingFlow
213
+ config={config.booking_flow}
214
+ colors={colors}
215
+ services={services}
216
+ dates={availableDates}
217
+ times={availableTimes}
218
+ addons={addons}
219
+ onComplete={(bookingData) => {
220
+ // Handle booking completion
221
+ }}
222
+ />
223
+ ```
224
+
225
+ **From 1200 lines to 15 lines!** 🚀
226
+
227
+ ---
228
+
229
+ ### Step 5: Update Configuration Structure
230
+
231
+ Your config structure should remain mostly the same, but here are the key mappings:
232
+
233
+ #### Section Configuration
234
+
235
+ ```typescript
236
+ // Your existing config works as-is!
237
+ const section = {
238
+ id: 'hero-1',
239
+ type: 'hero',
240
+ enabled: true,
241
+ position: 0,
242
+ settings: {
243
+ headline: 'Welcome',
244
+ subheadline: 'Book your appointment',
245
+ heroImage: '/hero.jpg',
246
+ layout: 'split'
247
+ }
248
+ };
249
+
250
+ // Just pass it to SectionRenderer
251
+ <SectionRenderer section={section} theme={theme} />
252
+ ```
253
+
254
+ #### Booking Flow Configuration
255
+
256
+ ```typescript
257
+ // Your existing booking_flow config works!
258
+ const config = {
259
+ booking_flow: {
260
+ steps: {
261
+ service_selection: {
262
+ enabled: true,
263
+ settings: {
264
+ headerContent: { value: 'Choose Service' },
265
+ serviceLayout: 'grid',
266
+ columns: 2
267
+ }
268
+ },
269
+ date_selection: {
270
+ enabled: true,
271
+ settings: {
272
+ headerContent: { value: 'Select Date' },
273
+ calendarView: 'month'
274
+ }
275
+ }
276
+ // ... more steps
277
+ },
278
+ progressBar: { style: 'dots' },
279
+ transitions: { style: 'slide', speed: 'normal' }
280
+ }
281
+ };
282
+
283
+ <BookingFlow config={config.booking_flow} colors={colors} />
284
+ ```
285
+
286
+ ---
287
+
288
+ ### Step 6: Handle Data Fetching
289
+
290
+ #### Before (Inline)
291
+
292
+ ```tsx
293
+ // Data fetching mixed with rendering
294
+ export default function TenantPage({ params }) {
295
+ const [config, setConfig] = useState(null);
296
+ const [services, setServices] = useState([]);
297
+
298
+ useEffect(() => {
299
+ // Fetch config and services
300
+ }, []);
301
+
302
+ return (
303
+ <div>
304
+ {/* Render sections */}
305
+ </div>
306
+ );
307
+ }
308
+ ```
309
+
310
+ #### After (Separated Concerns)
311
+
312
+ ```tsx
313
+ // src/app/[businessId]/page.tsx
314
+ export default function TenantPage({ params }) {
315
+ const { config, services, dates, times, addons } = useBookingData(params.businessId);
316
+
317
+ return (
318
+ <div>
319
+ {sections.map(section => (
320
+ <SectionRenderer
321
+ key={section.id}
322
+ section={section}
323
+ theme={config.theme}
324
+ />
325
+ ))}
326
+
327
+ {showBookingFlow && (
328
+ <BookingFlow
329
+ config={config.booking_flow}
330
+ colors={config.theme.colors}
331
+ services={services}
332
+ dates={dates}
333
+ times={times}
334
+ addons={addons}
335
+ onComplete={handleBookingComplete}
336
+ />
337
+ )}
338
+ </div>
339
+ );
340
+ }
341
+ ```
342
+
343
+ ---
344
+
345
+ ## Breaking Changes
346
+
347
+ ### 1. Import Paths
348
+
349
+ ```tsx
350
+ // ❌ Old
351
+ import BookingFlowPreview from '@/components/preview/BookingFlowPreview';
352
+
353
+ // ✅ New
354
+ import { BookingFlow } from '@oviah/booking-components';
355
+ ```
356
+
357
+ ### 2. Component Names
358
+
359
+ | Old | New |
360
+ |-----|-----|
361
+ | `BookingFlowPreview` | `BookingFlow` |
362
+ | `SectionRenderer` (inline) | `SectionRenderer` (from package) |
363
+
364
+ ### 3. Props Structure
365
+
366
+ Some components now expect structured config objects:
367
+
368
+ ```tsx
369
+ // ❌ Old (individual props)
370
+ <ServiceSelection
371
+ services={services}
372
+ categories={categories}
373
+ layout="grid"
374
+ columns={2}
375
+ showPricing={true}
376
+ />
377
+
378
+ // ✅ New (settings object)
379
+ <ServiceSelection
380
+ services={services}
381
+ categories={categories}
382
+ settings={{
383
+ serviceLayout: 'grid',
384
+ columns: 2,
385
+ showPricing: true
386
+ }}
387
+ colors={colors}
388
+ />
389
+ ```
390
+
391
+ ### 4. Callback Patterns
392
+
393
+ ```tsx
394
+ // ❌ Old
395
+ <BookingFlowPreview
396
+ config={config}
397
+ colors={colors}
398
+ onComplete={() => {
399
+ // Limited data
400
+ }}
401
+ />
402
+
403
+ // ✅ New (full booking data)
404
+ <BookingFlow
405
+ config={config}
406
+ colors={colors}
407
+ onComplete={(bookingData) => {
408
+ // Full structured data
409
+ console.log(bookingData.service);
410
+ console.log(bookingData.date);
411
+ console.log(bookingData.contact);
412
+ }}
413
+ onStepChange={(index, stepId) => {
414
+ // Track step changes
415
+ }}
416
+ />
417
+ ```
418
+
419
+ ---
420
+
421
+ ## Step-by-Step Migration Checklist
422
+
423
+ ### Phase 1: Preparation
424
+ - [ ] Backup your code
425
+ - [ ] Document current configuration
426
+ - [ ] Review all components you're using
427
+ - [ ] Test current implementation
428
+
429
+ ### Phase 2: Install & Setup
430
+ - [ ] Install package (already in workspace)
431
+ - [ ] Update TypeScript paths if needed
432
+ - [ ] Import components in your files
433
+
434
+ ### Phase 3: Migrate Sections
435
+ - [ ] Replace inline `SectionRenderer` with package version
436
+ - [ ] Test each section type renders correctly
437
+ - [ ] Verify styling matches
438
+
439
+ ### Phase 4: Migrate Booking Flow
440
+ - [ ] Replace `BookingFlowPreview` with `BookingFlow`
441
+ - [ ] Pass data providers (services, dates, times)
442
+ - [ ] Update callbacks
443
+ - [ ] Test complete booking flow
444
+
445
+ ### Phase 5: Cleanup
446
+ - [ ] Remove old component files
447
+ - [ ] Remove unused imports
448
+ - [ ] Update tests
449
+ - [ ] Update documentation
450
+
451
+ ### Phase 6: Testing
452
+ - [ ] Test all section types
453
+ - [ ] Test booking flow end-to-end
454
+ - [ ] Test on mobile devices
455
+ - [ ] Test payment integration
456
+ - [ ] Performance testing
457
+
458
+ ### Phase 7: Deploy
459
+ - [ ] Deploy to staging
460
+ - [ ] QA testing
461
+ - [ ] Deploy to production
462
+ - [ ] Monitor for errors
463
+
464
+ ---
465
+
466
+ ## Troubleshooting
467
+
468
+ ### Issue: Components Not Rendering
469
+
470
+ **Problem:** Components show blank or throw errors
471
+
472
+ **Solution:**
473
+ ```tsx
474
+ // Check that you're passing all required props
475
+ <SectionRenderer
476
+ section={section} // ✅ Required
477
+ theme={theme} // ✅ Required
478
+ />
479
+
480
+ // Check section has required fields
481
+ const section = {
482
+ id: 'hero-1', // ✅ Required
483
+ type: 'hero', // ✅ Required
484
+ settings: {...} // ✅ Required
485
+ };
486
+ ```
487
+
488
+ ### Issue: TypeScript Errors
489
+
490
+ **Problem:** Type errors on component props
491
+
492
+ **Solution:**
493
+ ```tsx
494
+ // Import types
495
+ import type { SectionRendererProps } from '@oviah/booking-components';
496
+
497
+ // Use correct types
498
+ const section: Section = {
499
+ id: 'hero-1',
500
+ type: 'hero',
501
+ enabled: true,
502
+ position: 0,
503
+ settings: {
504
+ headline: 'Welcome'
505
+ }
506
+ };
507
+ ```
508
+
509
+ ### Issue: Styling Looks Different
510
+
511
+ **Problem:** Components don't match previous styling
512
+
513
+ **Solution:**
514
+ ```tsx
515
+ // Ensure colors are passed correctly
516
+ const colors = {
517
+ primary: '#D8C4FF',
518
+ secondary: '#014421',
519
+ text: '#000000',
520
+ // Add all color properties
521
+ };
522
+
523
+ // Check custom CSS isn't overriding
524
+ // The package components use inline styles for theming
525
+ ```
526
+
527
+ ### Issue: Booking Flow State Not Persisting
528
+
529
+ **Problem:** User loses progress on navigation
530
+
531
+ **Solution:**
532
+ ```tsx
533
+ // Save state to localStorage
534
+ useEffect(() => {
535
+ const progress = {
536
+ service: selectedService,
537
+ date: selectedDate,
538
+ // ... other selections
539
+ };
540
+ localStorage.setItem('bookingProgress', JSON.stringify(progress));
541
+ }, [selectedService, selectedDate]);
542
+
543
+ // Restore on mount
544
+ useEffect(() => {
545
+ const saved = localStorage.getItem('bookingProgress');
546
+ if (saved) {
547
+ const progress = JSON.parse(saved);
548
+ // Restore state
549
+ }
550
+ }, []);
551
+ ```
552
+
553
+ ### Issue: Payment Integration Broken
554
+
555
+ **Problem:** Payment processing fails after migration
556
+
557
+ **Solution:**
558
+ ```tsx
559
+ // The Confirmation component is presentational only
560
+ // You need to handle payment logic yourself
561
+
562
+ <Confirmation
563
+ // ... props
564
+ onConfirm={async () => {
565
+ // YOUR payment processing logic here
566
+ await processPayment();
567
+ await createBooking();
568
+ }}
569
+ />
570
+ ```
571
+
572
+ ---
573
+
574
+ ## Example: Complete Migration
575
+
576
+ ### Before (app/[businessId]/page.tsx)
577
+
578
+ ```tsx
579
+ // 2000+ lines of code
580
+ 'use client';
581
+
582
+ import { use, useEffect, useState } from 'react';
583
+ // ... many imports
584
+
585
+ export default function TenantPage({ params }) {
586
+ // 50+ state variables
587
+ // 500+ lines of logic
588
+
589
+ function SectionRenderer() {
590
+ // 1000+ lines of switch statement
591
+ }
592
+
593
+ return (
594
+ <div>
595
+ {/* Complex rendering logic */}
596
+ </div>
597
+ );
598
+ }
599
+ ```
600
+
601
+ ### After (app/[businessId]/page.tsx)
602
+
603
+ ```tsx
604
+ // ~100 lines of code
605
+ 'use client';
606
+
607
+ import { use, useEffect, useState } from 'react';
608
+ import { SectionRenderer, BookingFlow } from '@oviah/booking-components';
609
+ import { useBookingData } from '@/hooks/useBookingData';
610
+
611
+ export default function TenantPage({ params }) {
612
+ const { businessId } = use(params);
613
+ const { config, services, dates, times, addons } = useBookingData(businessId);
614
+
615
+ if (!config) return <Loading />;
616
+
617
+ const { theme, sections, booking_flow } = config;
618
+
619
+ return (
620
+ <div style={{ backgroundColor: config.background?.value }}>
621
+ {sections.map(section => (
622
+ <SectionRenderer
623
+ key={section.id}
624
+ section={section}
625
+ theme={theme}
626
+ />
627
+ ))}
628
+
629
+ {booking_flow && (
630
+ <BookingFlow
631
+ config={booking_flow}
632
+ colors={theme.colors}
633
+ services={services}
634
+ dates={dates}
635
+ times={times}
636
+ addons={addons}
637
+ onComplete={handleBookingComplete}
638
+ />
639
+ )}
640
+ </div>
641
+ );
642
+ }
643
+ ```
644
+
645
+ **Result:** 95% reduction in code! 🎉
646
+
647
+ ---
648
+
649
+ ## Need Help?
650
+
651
+ - Check [API.md](./API.md) for component reference
652
+ - See [DATA_SHAPES.md](./DATA_SHAPES.md) for data structures
653
+ - Review [CALLBACKS.md](./CALLBACKS.md) for event handling
654
+ - Read [STYLING.md](./STYLING.md) for customization
655
+
656
+ If you encounter issues:
657
+ 1. Check the troubleshooting section above
658
+ 2. Review the example code in this guide
659
+ 3. Verify your configuration matches the data shapes
660
+ 4. Test components individually before full integration
661
+
662
+ Happy migrating! 🚀