@bailierich/booking-components 2.0.0 → 2.1.1

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.
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
 
3
- import { useState } from 'react';
3
+ import { useState, useEffect, useRef } from 'react';
4
4
  import { motion } from 'framer-motion';
5
5
  import type { ContactInfo, ContactFormSettings, OptInModule } from '../../../types';
6
6
  import { createEntranceAnimation } from '../../../styles';
@@ -30,9 +30,33 @@ export function ContactForm({
30
30
  }: ContactFormProps) {
31
31
  const [isModalOpen, setIsModalOpen] = useState(false);
32
32
  const [currentOptInModule, setCurrentOptInModule] = useState<OptInModule | null>(null);
33
- const [optInChecked, setOptInChecked] = useState<Record<string, boolean>>({});
33
+ const [optInChecked, setOptInChecked] = useState<Record<string, boolean>>(() => {
34
+ // Initialize from defaultChecked on each module
35
+ const defaults: Record<string, boolean> = {};
36
+ optInModules.forEach(m => {
37
+ if (m.defaultChecked) defaults[m.id] = true;
38
+ });
39
+ return defaults;
40
+ });
34
41
  const [errors, setErrors] = useState<Record<string, string>>({});
35
42
  const [touched, setTouched] = useState<Record<string, boolean>>({});
43
+ const defaultsFiredRef = useRef(false);
44
+
45
+ // Fire onOptInData for defaultChecked modules on mount
46
+ useEffect(() => {
47
+ if (defaultsFiredRef.current) return;
48
+ defaultsFiredRef.current = true;
49
+ optInModules.forEach(m => {
50
+ if (m.defaultChecked && m.renderCustomForm && onOptInData) {
51
+ // Auto-submit consent data for pre-checked modules
52
+ m.renderCustomForm(
53
+ () => {},
54
+ (data: any) => onOptInData(m.id, data),
55
+ colors
56
+ );
57
+ }
58
+ });
59
+ }, []);
36
60
 
37
61
  const headerText = settings.headerContent?.value || 'Your Information';
38
62
 
@@ -114,8 +138,28 @@ export function ContactForm({
114
138
  const handleOptInChange = (module: OptInModule, checked: boolean) => {
115
139
  setOptInChecked(prev => ({ ...prev, [module.id]: checked }));
116
140
  if (checked) {
141
+ // For modules with renderCustomForm that auto-submit (like SMS consent),
142
+ // fire the submit immediately without showing BottomSheet
143
+ if (module.renderCustomForm) {
144
+ let submitted = false;
145
+ const result = module.renderCustomForm(
146
+ () => {},
147
+ (data: any) => {
148
+ if (onOptInData) onOptInData(module.id, data);
149
+ submitted = true;
150
+ },
151
+ colors
152
+ );
153
+ // If renderCustomForm returned null and submitted, skip the BottomSheet
154
+ if (result === null && submitted) return;
155
+ }
117
156
  setCurrentOptInModule(module);
118
157
  setIsModalOpen(true);
158
+ } else {
159
+ // Unchecked — revoke by sending null data
160
+ if (onOptInData) {
161
+ onOptInData(module.id, null);
162
+ }
119
163
  }
120
164
  };
121
165
 
@@ -203,9 +247,11 @@ export function ContactForm({
203
247
  {module.label}
204
248
  {module.required && <span className="text-red-500 ml-1">*</span>}
205
249
  </span>
206
- <p className="text-xs text-gray-500 mt-0.5">
207
- Check this to provide additional information
208
- </p>
250
+ {module.description && (
251
+ <p className="text-xs text-gray-500 mt-0.5">
252
+ {module.description}
253
+ </p>
254
+ )}
209
255
  </div>
210
256
  </label>
211
257
  ))}
@@ -154,14 +154,22 @@ export default function FormRenderer({ form, businessId, onSuccess }: FormRender
154
154
  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
155
155
  </svg>
156
156
  </div>
157
- <h3 className="text-xl font-semibold mb-2" style={{ color: form.settings.styling?.labelColor || '#000000' }}>Success!</h3>
158
- <p style={{ color: form.settings.styling?.textColor || '#000000' }}>{form.settings.successMessage}</p>
159
- <button
160
- onClick={() => setIsSuccess(false)}
161
- className="mt-6 px-4 py-2 bg-gray-900 text-white rounded-lg hover:bg-gray-800 transition-colors"
162
- >
163
- Submit Another Response
164
- </button>
157
+ <h3 className="text-xl font-semibold mb-2" style={{ color: '#1a1a1a' }}>Success!</h3>
158
+ <p style={{ color: '#374151' }}>{form.settings.successMessage}</p>
159
+ <div className="mt-6 flex gap-3 justify-center">
160
+ <button
161
+ onClick={() => window.location.href = '/'}
162
+ className="px-4 py-2 bg-gray-900 text-white rounded-lg hover:bg-gray-800 transition-colors"
163
+ >
164
+ Back to Home
165
+ </button>
166
+ <button
167
+ onClick={() => setIsSuccess(false)}
168
+ className="px-4 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors"
169
+ >
170
+ Submit Another Response
171
+ </button>
172
+ </div>
165
173
  </div>
166
174
  </div>
167
175
  );
@@ -25,7 +25,9 @@ interface Addon {
25
25
  interface OptInModule {
26
26
  id: string;
27
27
  label: string;
28
+ description?: string;
28
29
  required: boolean;
30
+ defaultChecked?: boolean;
29
31
  formTitle?: string;
30
32
  formFields?: FormField[];
31
33
  renderCustomForm?: (onClose: () => void, onSubmitData: (data: any) => void, colors: {
@@ -25,7 +25,9 @@ interface Addon {
25
25
  interface OptInModule {
26
26
  id: string;
27
27
  label: string;
28
+ description?: string;
28
29
  required: boolean;
30
+ defaultChecked?: boolean;
29
31
  formTitle?: string;
30
32
  formFields?: FormField[];
31
33
  renderCustomForm?: (onClose: () => void, onSubmitData: (data: any) => void, colors: {
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { H as HoldTimerConfig, C as CreateHoldFn, E as ExtendHoldFn, R as ReleaseHoldFn, O as OptInModule, S as Service, a as ServiceCategory, b as ServiceSelectionSettings, D as DateSelectionSettings, T as TimeSelectionSettings, A as Addon, c as AddonSelectionSettings, d as ContactInfo, e as ContactFormSettings, P as PaymentConfig, f as CyclePhase, F as FetchCycleDataFn, g as CycleClient, h as CycleWarningCallback, B as BottomSheetProps, i as HoldStatus } from './index-DAai7Glf.mjs';
3
- export { v as AddonSelectionStepProps, I as AnimationVariants, l as BackgroundConfig, k as BookingData, x as ConfirmationStepProps, w as ContactFormStepProps, y as CyclePhaseMap, q as DataProviders, t as DateSelectionStepProps, j as FormField, z as HoldManagerCallbacks, p as PolicyImage, n as ProgressBarConfig, s as ServiceSelectionStepProps, r as StepComponentProps, o as StepConfig, u as TimeSelectionStepProps, m as TransitionConfig, G as TransitionDirection, N as animations, V as createEntranceAnimation, U as createStaggerAnimation, J as getAnimationDuration, L as getFadeVariants, K as getSlideVariants, M as getTransitionVariants, Q as shouldReduceMotion } from './index-DAai7Glf.mjs';
2
+ import { H as HoldTimerConfig, C as CreateHoldFn, E as ExtendHoldFn, R as ReleaseHoldFn, O as OptInModule, S as Service, a as ServiceCategory, b as ServiceSelectionSettings, D as DateSelectionSettings, T as TimeSelectionSettings, A as Addon, c as AddonSelectionSettings, d as ContactInfo, e as ContactFormSettings, P as PaymentConfig, f as CyclePhase, F as FetchCycleDataFn, g as CycleClient, h as CycleWarningCallback, B as BottomSheetProps, i as HoldStatus } from './index-CqGdjmIM.mjs';
3
+ export { v as AddonSelectionStepProps, I as AnimationVariants, l as BackgroundConfig, k as BookingData, x as ConfirmationStepProps, w as ContactFormStepProps, y as CyclePhaseMap, q as DataProviders, t as DateSelectionStepProps, j as FormField, z as HoldManagerCallbacks, p as PolicyImage, n as ProgressBarConfig, s as ServiceSelectionStepProps, r as StepComponentProps, o as StepConfig, u as TimeSelectionStepProps, m as TransitionConfig, G as TransitionDirection, N as animations, V as createEntranceAnimation, U as createStaggerAnimation, J as getAnimationDuration, L as getFadeVariants, K as getSlideVariants, M as getTransitionVariants, Q as shouldReduceMotion } from './index-CqGdjmIM.mjs';
4
4
  import React$1 from 'react';
5
5
 
6
6
  interface LogoProps {
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { H as HoldTimerConfig, C as CreateHoldFn, E as ExtendHoldFn, R as ReleaseHoldFn, O as OptInModule, S as Service, a as ServiceCategory, b as ServiceSelectionSettings, D as DateSelectionSettings, T as TimeSelectionSettings, A as Addon, c as AddonSelectionSettings, d as ContactInfo, e as ContactFormSettings, P as PaymentConfig, f as CyclePhase, F as FetchCycleDataFn, g as CycleClient, h as CycleWarningCallback, B as BottomSheetProps, i as HoldStatus } from './index-DAai7Glf.js';
3
- export { v as AddonSelectionStepProps, I as AnimationVariants, l as BackgroundConfig, k as BookingData, x as ConfirmationStepProps, w as ContactFormStepProps, y as CyclePhaseMap, q as DataProviders, t as DateSelectionStepProps, j as FormField, z as HoldManagerCallbacks, p as PolicyImage, n as ProgressBarConfig, s as ServiceSelectionStepProps, r as StepComponentProps, o as StepConfig, u as TimeSelectionStepProps, m as TransitionConfig, G as TransitionDirection, N as animations, V as createEntranceAnimation, U as createStaggerAnimation, J as getAnimationDuration, L as getFadeVariants, K as getSlideVariants, M as getTransitionVariants, Q as shouldReduceMotion } from './index-DAai7Glf.js';
2
+ import { H as HoldTimerConfig, C as CreateHoldFn, E as ExtendHoldFn, R as ReleaseHoldFn, O as OptInModule, S as Service, a as ServiceCategory, b as ServiceSelectionSettings, D as DateSelectionSettings, T as TimeSelectionSettings, A as Addon, c as AddonSelectionSettings, d as ContactInfo, e as ContactFormSettings, P as PaymentConfig, f as CyclePhase, F as FetchCycleDataFn, g as CycleClient, h as CycleWarningCallback, B as BottomSheetProps, i as HoldStatus } from './index-CqGdjmIM.js';
3
+ export { v as AddonSelectionStepProps, I as AnimationVariants, l as BackgroundConfig, k as BookingData, x as ConfirmationStepProps, w as ContactFormStepProps, y as CyclePhaseMap, q as DataProviders, t as DateSelectionStepProps, j as FormField, z as HoldManagerCallbacks, p as PolicyImage, n as ProgressBarConfig, s as ServiceSelectionStepProps, r as StepComponentProps, o as StepConfig, u as TimeSelectionStepProps, m as TransitionConfig, G as TransitionDirection, N as animations, V as createEntranceAnimation, U as createStaggerAnimation, J as getAnimationDuration, L as getFadeVariants, K as getSlideVariants, M as getTransitionVariants, Q as shouldReduceMotion } from './index-CqGdjmIM.js';
4
4
  import React$1 from 'react';
5
5
 
6
6
  interface LogoProps {