@bailierich/booking-components 2.1.1 → 2.1.3

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/lib/storage.ts CHANGED
@@ -12,8 +12,9 @@ let supabaseClient: ReturnType<typeof createClient> | null = null;
12
12
 
13
13
  export function getSupabaseClient() {
14
14
  if (!supabaseClient) {
15
- const supabaseUrl = import.meta.env.VITE_SUPABASE_URL || process.env.NEXT_PUBLIC_SUPABASE_URL;
16
- const supabaseKey = import.meta.env.VITE_SUPABASE_ANON_KEY || process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;
15
+ const meta = import.meta as unknown as { env?: Record<string, string> };
16
+ const supabaseUrl = meta.env?.VITE_SUPABASE_URL || process.env.NEXT_PUBLIC_SUPABASE_URL;
17
+ const supabaseKey = meta.env?.VITE_SUPABASE_ANON_KEY || process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;
17
18
 
18
19
  if (!supabaseUrl || !supabaseKey) {
19
20
  throw new Error('Supabase URL and Anon Key must be provided');
@@ -58,7 +59,7 @@ export async function uploadFormImage(
58
59
  }
59
60
 
60
61
  // Validate file type
61
- if (!FORM_UPLOAD_CONFIG.limits.allowedTypes.includes(file.type)) {
62
+ if (!(FORM_UPLOAD_CONFIG.limits.allowedTypes as readonly string[]).includes(file.type)) {
62
63
  throw new Error(`File type ${file.type} not allowed. Accepted types: JPG, PNG, WebP`);
63
64
  }
64
65
 
@@ -228,7 +229,7 @@ export function validateImageFile(file: File): { valid: boolean; error?: string
228
229
  }
229
230
 
230
231
  // Check file type
231
- if (!FORM_UPLOAD_CONFIG.limits.allowedTypes.includes(file.type)) {
232
+ if (!(FORM_UPLOAD_CONFIG.limits.allowedTypes as readonly string[]).includes(file.type)) {
232
233
  return {
233
234
  valid: false,
234
235
  error: `File type not allowed. Accepted: JPG, PNG, WebP`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bailierich/booking-components",
3
- "version": "2.1.1",
3
+ "version": "2.1.3",
4
4
  "description": "Shared booking flow components for OVIAH platform",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
package/tsup.config.ts CHANGED
@@ -3,7 +3,7 @@ import { defineConfig } from 'tsup';
3
3
  export default defineConfig({
4
4
  entry: ['index.ts', 'styles/index.ts'],
5
5
  format: ['cjs', 'esm'],
6
- dts: true,
6
+ dts: false, // Disabled due to TypeScript config incompatibility with tsup DTS generation
7
7
  sourcemap: true,
8
8
  clean: true,
9
9
  external: ['react', 'react-dom'],
@@ -1,476 +0,0 @@
1
- interface Service {
2
- id: string;
3
- name: string;
4
- price: number;
5
- duration: number;
6
- description: string;
7
- category?: string;
8
- imageUrl?: string;
9
- }
10
- interface ServiceCategory {
11
- id: string;
12
- name: string;
13
- description?: string;
14
- services: Service[];
15
- }
16
- interface Addon {
17
- id: string;
18
- name: string;
19
- price: number;
20
- addonPrice?: number;
21
- duration: number;
22
- description: string;
23
- imageUrl?: string;
24
- }
25
- interface OptInModule {
26
- id: string;
27
- label: string;
28
- description?: string;
29
- required: boolean;
30
- defaultChecked?: boolean;
31
- formTitle?: string;
32
- formFields?: FormField[];
33
- renderCustomForm?: (onClose: () => void, onSubmitData: (data: any) => void, colors: {
34
- primary: string;
35
- secondary: string;
36
- bookingText?: string;
37
- }) => React.ReactNode;
38
- }
39
- interface FormField {
40
- id: string;
41
- label: string;
42
- type: 'text' | 'email' | 'tel' | 'textarea' | 'select' | 'checkbox';
43
- placeholder?: string;
44
- required?: boolean;
45
- options?: {
46
- value: string;
47
- label: string;
48
- }[];
49
- }
50
- interface BookingData {
51
- serviceId: string;
52
- date: string;
53
- time: string;
54
- addonIds: string[];
55
- contactInfo: ContactInfo;
56
- optInData?: Record<string, any>;
57
- paymentIntentId?: string;
58
- totalPrice: number;
59
- depositAmount: number;
60
- }
61
- interface ContactInfo {
62
- name: string;
63
- email: string;
64
- phone: string;
65
- notes?: string;
66
- }
67
- interface BackgroundConfig {
68
- type: 'color' | 'gradient' | 'image';
69
- value: string;
70
- }
71
- interface TransitionConfig {
72
- style: 'slide' | 'fade';
73
- speed: 'fast' | 'normal' | 'slow';
74
- }
75
- interface ProgressBarConfig {
76
- style: 'dots' | 'bar' | 'minimal';
77
- }
78
- interface StepConfig {
79
- enabled?: boolean;
80
- settings?: Record<string, any>;
81
- }
82
- interface ServiceSelectionSettings {
83
- headerContent?: {
84
- value: string;
85
- };
86
- subheaderContent?: {
87
- value: string;
88
- };
89
- serviceLayout?: 'grid' | 'list';
90
- columns?: 1 | 2 | 3 | 4;
91
- showPricing?: boolean;
92
- showDuration?: boolean;
93
- showDescription?: boolean;
94
- enableCategories?: boolean;
95
- categoryStyle?: 'dropdown' | 'tabs' | 'pills' | 'chips' | 'accordion';
96
- defaultCategoryView?: 'all' | string;
97
- policyImages?: PolicyImage[];
98
- policyText?: string;
99
- imageSpacing?: 'none' | 'small' | 'medium' | 'large';
100
- imageBorderRadius?: string;
101
- }
102
- interface PolicyImage {
103
- url: string;
104
- alt?: string;
105
- }
106
- interface DateSelectionSettings {
107
- headerContent?: {
108
- value: string;
109
- };
110
- calendarView?: 'month' | 'week';
111
- allowedDaysAhead?: number;
112
- blockedDates?: string[];
113
- }
114
- interface TimeSelectionSettings {
115
- headerContent?: {
116
- value: string;
117
- };
118
- timeFormat?: '12h' | '24h';
119
- showDuration?: boolean;
120
- columns?: 2 | 3 | 4;
121
- slotDuration?: number;
122
- }
123
- interface AddonSelectionSettings {
124
- headerContent?: {
125
- value: string;
126
- };
127
- subheaderContent?: {
128
- value: string;
129
- };
130
- showPricing?: boolean;
131
- showDuration?: boolean;
132
- }
133
- interface ContactFormSettings {
134
- headerContent?: {
135
- value: string;
136
- };
137
- requiredFields?: ('name' | 'email' | 'phone' | 'notes')[];
138
- customFields?: FormField[];
139
- }
140
- interface DataProviders {
141
- /** Fetch available services */
142
- getServices: () => Promise<Service[]>;
143
- /** Fetch available dates for a service */
144
- getAvailableDates: (serviceId: string) => Promise<string[]>;
145
- /** Fetch available time slots for a service on a specific date */
146
- getAvailableTimes: (serviceId: string, date: string) => Promise<string[]>;
147
- /** Fetch available add-ons for a service */
148
- getAddons: (serviceId: string) => Promise<Addon[]>;
149
- /** Optional: Fetch opt-in modules (custom forms) */
150
- getOptInModules?: () => Promise<OptInModule[]>;
151
- /** Optional: Fetch service categories */
152
- getServiceCategories?: () => Promise<ServiceCategory[]>;
153
- }
154
- interface PaymentConfig {
155
- squareApplicationId?: string;
156
- squareLocationId?: string;
157
- stripePublishableKey?: string;
158
- depositPercentage?: number;
159
- currency?: string;
160
- }
161
- interface BottomSheetProps {
162
- isOpen: boolean;
163
- onClose: () => void;
164
- title?: string;
165
- children: React.ReactNode;
166
- isRequired?: boolean;
167
- maxHeight?: string;
168
- }
169
- interface StepComponentProps {
170
- config: StepConfig;
171
- colors: {
172
- primary: string;
173
- secondary: string;
174
- bookingText?: string;
175
- };
176
- onNext: () => void;
177
- onBack: () => void;
178
- }
179
- interface ServiceSelectionStepProps extends StepComponentProps {
180
- services: Service[];
181
- categories?: ServiceCategory[];
182
- selectedService: string | null;
183
- onServiceSelect: (serviceId: string) => void;
184
- }
185
- interface DateSelectionStepProps extends StepComponentProps {
186
- availableDates: string[];
187
- selectedDate: string | null;
188
- onDateSelect: (date: string) => void;
189
- }
190
- interface TimeSelectionStepProps extends StepComponentProps {
191
- availableTimes: string[];
192
- selectedTime: string | null;
193
- onTimeSelect: (time: string) => void;
194
- serviceDuration?: number;
195
- }
196
- interface AddonSelectionStepProps extends StepComponentProps {
197
- addons: Addon[];
198
- selectedAddons: string[];
199
- onAddonsChange: (addonIds: string[]) => void;
200
- }
201
- interface ContactFormStepProps extends StepComponentProps {
202
- contactInfo: Partial<ContactInfo>;
203
- onContactInfoChange: (info: Partial<ContactInfo>) => void;
204
- optInModules?: OptInModule[];
205
- onOptInData?: (moduleId: string, data: any) => void;
206
- }
207
- interface ConfirmationStepProps extends StepComponentProps {
208
- bookingData: Partial<BookingData>;
209
- service?: Service;
210
- addons?: Addon[];
211
- paymentProvider: 'square' | 'stripe';
212
- paymentConfig: PaymentConfig;
213
- onConfirm: () => Promise<void>;
214
- }
215
- interface CyclePhase {
216
- phase: 'avoid' | 'caution' | 'optimal' | 'neutral' | 'unknown';
217
- color: string;
218
- bgColor: string;
219
- label: string;
220
- icon: string;
221
- description: string;
222
- daysSinceStart?: number;
223
- confidence?: number;
224
- }
225
- interface CyclePhaseMap {
226
- [dateString: string]: CyclePhase;
227
- }
228
- interface CycleClient {
229
- id: string;
230
- cycle_opt_in: boolean;
231
- cycle_last_period_start?: string;
232
- cycle_avg_days?: number;
233
- cycle_period_len?: number;
234
- [key: string]: any;
235
- }
236
- /** Function that fetches cycle phase data for a date range */
237
- type FetchCycleDataFn = (client: CycleClient, dateRange: string[]) => Promise<CyclePhaseMap>;
238
- /** Callback when a cycle warning should be shown */
239
- type CycleWarningCallback = (phase: CyclePhase, date: string) => void;
240
- interface HoldTimerConfig {
241
- enabled: boolean;
242
- duration: number;
243
- warningThreshold: number;
244
- maxExtensions: number;
245
- extensionDuration: number;
246
- showActions: boolean;
247
- showWarning: boolean;
248
- }
249
- interface HoldStatus {
250
- holdId: string;
251
- holdKey: string;
252
- date: string;
253
- time: string;
254
- serviceId: string;
255
- createdAt: number;
256
- expiresAt: number;
257
- extensions: number;
258
- maxExtensions: number;
259
- canExtend: boolean;
260
- status: 'active' | 'warning' | 'expired';
261
- }
262
- interface HoldManagerCallbacks {
263
- /** Called when hold is created successfully */
264
- onHoldCreated?: (hold: HoldStatus) => void;
265
- /** Called when hold is extended */
266
- onHoldExtended?: (hold: HoldStatus) => void;
267
- /** Called when hold is released manually */
268
- onHoldReleased?: (holdId: string) => void;
269
- /** Called when entering warning threshold */
270
- onHoldWarning?: (hold: HoldStatus) => void;
271
- /** Called when hold expires */
272
- onHoldExpired?: (hold: HoldStatus) => void;
273
- }
274
- /** Function that creates a hold on the backend */
275
- type CreateHoldFn = (data: {
276
- date: string;
277
- time: string;
278
- serviceId: string;
279
- serviceDuration: number;
280
- }) => Promise<HoldStatus>;
281
- /** Function that extends an existing hold */
282
- type ExtendHoldFn = (holdId: string) => Promise<HoldStatus>;
283
- /** Function that releases a hold */
284
- type ReleaseHoldFn = (holdId: string) => Promise<void>;
285
- type TransitionDirection = 'forward' | 'backward';
286
- interface AnimationVariants {
287
- enter: (direction: TransitionDirection) => Record<string, any>;
288
- center: Record<string, any>;
289
- exit: (direction: TransitionDirection) => Record<string, any>;
290
- }
291
-
292
- /**
293
- * Animation duration calculator based on speed and reduced motion preference
294
- */
295
- declare function getAnimationDuration(speed: 'fast' | 'normal' | 'slow', reducedMotion?: boolean): number;
296
- /**
297
- * Slide animation variants for step transitions
298
- */
299
- declare function getSlideVariants(slideDistance?: number): AnimationVariants;
300
- /**
301
- * Fade animation variants for step transitions
302
- */
303
- declare function getFadeVariants(): AnimationVariants;
304
- /**
305
- * Get transition variants based on style preference
306
- */
307
- declare function getTransitionVariants(style: 'slide' | 'fade', slideDistance?: number): AnimationVariants;
308
- /**
309
- * Common animation configurations
310
- */
311
- declare const animations: {
312
- /**
313
- * Smooth easing curve for natural motion
314
- */
315
- easing: readonly [0.4, 0, 0.2, 1];
316
- /**
317
- * Spring configuration for elastic animations
318
- */
319
- spring: {
320
- type: "spring";
321
- damping: number;
322
- stiffness: number;
323
- };
324
- /**
325
- * Stagger children animation
326
- */
327
- staggerChildren: {
328
- staggerChildren: number;
329
- delayChildren: number;
330
- };
331
- /**
332
- * Card hover animation
333
- */
334
- cardHover: {
335
- scale: number;
336
- transition: {
337
- duration: number;
338
- };
339
- };
340
- /**
341
- * Button hover animation
342
- */
343
- buttonHover: {
344
- scale: number;
345
- transition: {
346
- duration: number;
347
- };
348
- };
349
- /**
350
- * Fade in animation
351
- */
352
- fadeIn: {
353
- initial: {
354
- opacity: number;
355
- };
356
- animate: {
357
- opacity: number;
358
- };
359
- exit: {
360
- opacity: number;
361
- };
362
- };
363
- /**
364
- * Slide up animation (for bottom sheets)
365
- */
366
- slideUp: {
367
- initial: {
368
- y: string;
369
- };
370
- animate: {
371
- y: number;
372
- };
373
- exit: {
374
- y: string;
375
- };
376
- };
377
- /**
378
- * Scale in animation
379
- */
380
- scaleIn: {
381
- initial: {
382
- opacity: number;
383
- scale: number;
384
- };
385
- animate: {
386
- opacity: number;
387
- scale: number;
388
- };
389
- exit: {
390
- opacity: number;
391
- scale: number;
392
- };
393
- };
394
- /**
395
- * Slide in from left
396
- */
397
- slideInLeft: {
398
- initial: {
399
- opacity: number;
400
- x: number;
401
- };
402
- animate: {
403
- opacity: number;
404
- x: number;
405
- };
406
- };
407
- /**
408
- * Slide in from right
409
- */
410
- slideInRight: {
411
- initial: {
412
- opacity: number;
413
- x: number;
414
- };
415
- animate: {
416
- opacity: number;
417
- x: number;
418
- };
419
- };
420
- /**
421
- * Backdrop animation
422
- */
423
- backdrop: {
424
- initial: {
425
- opacity: number;
426
- };
427
- animate: {
428
- opacity: number;
429
- };
430
- exit: {
431
- opacity: number;
432
- };
433
- };
434
- };
435
- /**
436
- * Accessibility: Check for reduced motion preference
437
- */
438
- declare function shouldReduceMotion(): boolean;
439
- /**
440
- * Create stagger animation for list items
441
- */
442
- declare function createStaggerAnimation(itemCount: number, baseDelay?: number, delayIncrement?: number): {
443
- initial: {
444
- opacity: number;
445
- y: number;
446
- };
447
- animate: {
448
- opacity: number;
449
- y: number;
450
- };
451
- transition: {
452
- duration: number;
453
- delay: number;
454
- ease: readonly [0.4, 0, 0.2, 1];
455
- };
456
- }[];
457
- /**
458
- * Utility to create entrance animation with delay
459
- */
460
- declare function createEntranceAnimation(delay?: number, duration?: number): {
461
- initial: {
462
- opacity: number;
463
- y: number;
464
- };
465
- animate: {
466
- opacity: number;
467
- y: number;
468
- };
469
- transition: {
470
- duration: number;
471
- delay: number;
472
- ease: readonly [0.4, 0, 0.2, 1];
473
- };
474
- };
475
-
476
- export { type Addon as A, type BottomSheetProps as B, type CreateHoldFn as C, type DateSelectionSettings as D, type ExtendHoldFn as E, type FetchCycleDataFn as F, type TransitionDirection as G, type HoldTimerConfig as H, type AnimationVariants as I, getAnimationDuration as J, getSlideVariants as K, getFadeVariants as L, getTransitionVariants as M, animations as N, type OptInModule as O, type PaymentConfig as P, shouldReduceMotion as Q, type ReleaseHoldFn as R, type Service as S, type TimeSelectionSettings as T, createStaggerAnimation as U, createEntranceAnimation as V, type ServiceCategory as a, type ServiceSelectionSettings as b, type AddonSelectionSettings as c, type ContactInfo as d, type ContactFormSettings as e, type CyclePhase as f, type CycleClient as g, type CycleWarningCallback as h, type HoldStatus as i, type FormField as j, type BookingData as k, type BackgroundConfig as l, type TransitionConfig as m, type ProgressBarConfig as n, type StepConfig as o, type PolicyImage as p, type DataProviders as q, type StepComponentProps as r, type ServiceSelectionStepProps as s, type DateSelectionStepProps as t, type TimeSelectionStepProps as u, type AddonSelectionStepProps as v, type ContactFormStepProps as w, type ConfirmationStepProps as x, type CyclePhaseMap as y, type HoldManagerCallbacks as z };