@flamingo-stack/openframe-frontend-core 0.0.675 → 0.0.676-2437.7324.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,5 +1,5 @@
1
1
  import type { ReactNode, Ref } from 'react';
2
- import { type BuiltInBookingFieldName, type MeetingAvailability } from '../../schemas/meeting-booking-schema';
2
+ import { type BuiltInBookingFieldName, type DeniedEmailDomains, type MeetingAvailability } from '../../schemas/meeting-booking-schema';
3
3
  import type { FormRescueDefinition } from '../../utils/form-rescue';
4
4
  /**
5
5
  * One field in a host-supplied row. `name` is a built-in (`email`, `firstName`,
@@ -14,6 +14,20 @@ export interface BookingFieldSlot {
14
14
  /** Columns out of `GRID_COLUMNS` at `md` and up — the keys of `SPAN_CLASS`. */
15
15
  export type BookingFieldSpan = keyof typeof SPAN_CLASS;
16
16
  export type BookingFieldRow = BookingFieldSlot[];
17
+ /**
18
+ * Display copy a HOST overrides for ONE field, keyed by its name — a built-in
19
+ * (`email`) or a HubSpot-declared question. It replaces what is DRAWN and
20
+ * nothing else: the name the answer rides under, the validation and the
21
+ * schema's own messages are untouched, so a campaign page can ask for a
22
+ * "Business Email" without owning a second email rule.
23
+ *
24
+ * An overridden `label` also feeds the type's derived placeholder
25
+ * (`Enter <label>`), so overriding the label alone keeps the pair consistent.
26
+ */
27
+ export interface BookingFieldCopy {
28
+ label?: string;
29
+ placeholder?: string;
30
+ }
17
31
  /**
18
32
  * A HOST-supplied consent row — the block the waitlist form draws for its SMS
19
33
  * consent, here for "I agree to the Privacy Policy and to be contacted". It is
@@ -76,6 +90,11 @@ export interface BookingFormProps {
76
90
  * appended full width. Both are deliberate — see `slotNode`/`unplacedFields`.
77
91
  */
78
92
  fieldRows?: BookingFieldRow[];
93
+ /** Per-field display overrides, keyed by field name — see `BookingFieldCopy`. */
94
+ fieldCopy?: Record<string, BookingFieldCopy>;
95
+ /** Email domains this form refuses, with the message it shows — see `DeniedEmailDomains`.
96
+ * MEMOIZE it: a new object every render rebuilds the resolver's schema. */
97
+ deniedEmailDomains?: DeniedEmailDomains;
79
98
  /** Host-supplied consent row, rendered after the fields — see `BookingFormConsent`. */
80
99
  consent?: BookingFormConsent;
81
100
  isSubmitting: boolean;
@@ -106,7 +125,7 @@ export interface BookingFormProps {
106
125
  * submit; the parent calls `resetSignals()` after a SLOT_TAKEN refetch so a
107
126
  * legitimate retry isn't flagged too-fast.
108
127
  */
109
- export declare function BookingForm({ availability, meetingId, startTimeMs, durationMs, timezone, deferSlot, initialValues, submitLabel, footerNote, fieldRows, consent, isSubmitting, onSubmit, honeypotInputProps, getSignals, rescue, }: BookingFormProps): import("react").JSX.Element;
128
+ export declare function BookingForm({ availability, meetingId, startTimeMs, durationMs, timezone, deferSlot, initialValues, submitLabel, footerNote, fieldRows, fieldCopy, deniedEmailDomains, consent, isSubmitting, onSubmit, honeypotInputProps, getSignals, rescue, }: BookingFormProps): import("react").JSX.Element;
110
129
  /**
111
130
  * Cold-start placeholder for `flow="details-first"`, where the FORM is the
112
131
  * first thing in the action panel.
@@ -1 +1 @@
1
- {"version":3,"file":"booking-form.d.ts","sourceRoot":"","sources":["../../../src/components/meeting-scheduler/booking-form.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"booking-form.d.ts","sourceRoot":"","sources":["../../../src/components/meeting-scheduler/booking-form.tsx"],"names":[],"mappings":"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"}
@@ -331,6 +331,20 @@ function makeDeferredBookingSchema(formFields, legalConsent) {
331
331
  timezone: TIMEZONE.nullish()
332
332
  });
333
333
  }
334
+ function emailDomainDenied(email, rule) {
335
+ if (typeof email !== "string") return false;
336
+ const domain = _optionalChain([email, 'access', _5 => _5.split, 'call', _6 => _6("@"), 'access', _7 => _7[1], 'optionalAccess', _8 => _8.trim, 'call', _9 => _9(), 'access', _10 => _10.toLowerCase, 'call', _11 => _11()]);
337
+ if (domain === void 0 || domain === "") return false;
338
+ return rule.domains.includes(domain);
339
+ }
340
+ function withDeniedEmailDomains(schema, rule) {
341
+ if (!rule) return schema;
342
+ return schema.superRefine((values, ctx) => {
343
+ if (emailDomainDenied(values.email, rule)) {
344
+ ctx.addIssue({ code: "custom", path: ["email"], message: rule.message });
345
+ }
346
+ });
347
+ }
334
348
 
335
349
  // src/hooks/use-meeting-booking.ts
336
350
  var AVAILABILITY_STALE_MS = 0;
@@ -341,7 +355,7 @@ var BOOKING_IN_FLIGHT_MESSAGE = "Already submitting";
341
355
  function useMeetingBooking(options) {
342
356
  const { meetingId, apiBaseUrl = "", initialAvailability } = options;
343
357
  const queryClient = _reactquery.useQueryClient.call(void 0, );
344
- const seededOffset = _optionalChain([initialAvailability, 'optionalAccess', _5 => _5.meetingId]) === meetingId ? initialAvailability.monthOffset : void 0;
358
+ const seededOffset = _optionalChain([initialAvailability, 'optionalAccess', _12 => _12.meetingId]) === meetingId ? initialAvailability.monthOffset : void 0;
345
359
  const [monthOffset, setMonthOffsetState] = _react.useState.call(void 0, _nullishCoalesce(seededOffset, () => ( 0)));
346
360
  const setMonthOffset = _react.useCallback.call(void 0, (offset) => {
347
361
  setMonthOffsetState(Math.max(0, Math.min(_chunkVZMST7BDcjs.MAX_MONTH_OFFSET, offset)));
@@ -352,7 +366,7 @@ function useMeetingBooking(options) {
352
366
  prevMeetingIdRef.current = meetingId;
353
367
  setMonthOffsetState(0);
354
368
  }, [meetingId]);
355
- const seed = _optionalChain([initialAvailability, 'optionalAccess', _6 => _6.meetingId]) === meetingId && initialAvailability.monthOffset === monthOffset ? initialAvailability : void 0;
369
+ const seed = _optionalChain([initialAvailability, 'optionalAccess', _13 => _13.meetingId]) === meetingId && initialAvailability.monthOffset === monthOffset ? initialAvailability : void 0;
356
370
  const availabilityQuery = _reactquery.useQuery.call(void 0, {
357
371
  queryKey: meetingAvailabilityKey(apiBaseUrl, meetingId, monthOffset),
358
372
  queryFn: async ({ signal }) => {
@@ -448,8 +462,8 @@ var evenSpan = (count, index) => {
448
462
  return Math.min(GRID_COLUMNS, Math.max(1, index < extra ? base + 1 : base));
449
463
  };
450
464
  var slotColumnClass = (row, slot, index) => _chunkX7CEWD6Vcjs.cn.call(void 0, row.length === 2 ? "col-span-1" : "col-span-2", SPAN_CLASS[_nullishCoalesce(slot.span, () => ( evenSpan(row.length, index)))]);
451
- var placeholderFor = (field) => _nullishCoalesce(field.placeholder, () => ( _optionalChain([fieldTypeSpec, 'call', _7 => _7(field.type), 'access', _8 => _8.placeholder, 'optionalCall', _9 => _9(field)])));
452
- var optionLabel = (field, value) => _nullishCoalesce(_optionalChain([field, 'access', _10 => _10.optionLabels, 'optionalAccess', _11 => _11[value]]), () => ( value));
465
+ var placeholderFor = (field) => _nullishCoalesce(field.placeholder, () => ( _optionalChain([fieldTypeSpec, 'call', _14 => _14(field.type), 'access', _15 => _15.placeholder, 'optionalCall', _16 => _16(field)])));
466
+ var optionLabel = (field, value) => _nullishCoalesce(_optionalChain([field, 'access', _17 => _17.optionLabels, 'optionalAccess', _18 => _18[value]]), () => ( value));
453
467
  var trimmed = (v) => String(_nullishCoalesce(v, () => ( ""))).trim();
454
468
  var canonicalNumber = (v) => {
455
469
  const s = String(_nullishCoalesce(v, () => ( ""))).trim();
@@ -467,6 +481,7 @@ var FIELD_CONTROLS = {
467
481
  type: _nullishCoalesce(field.inputType, () => ( "text")),
468
482
  required: field.required,
469
483
  "aria-invalid": Boolean(error),
484
+ invalid: Boolean(error),
470
485
  autoComplete: field.autoComplete,
471
486
  placeholder: placeholderFor(field),
472
487
  ...register(registerName)
@@ -478,6 +493,7 @@ var FIELD_CONTROLS = {
478
493
  id,
479
494
  required: field.required,
480
495
  "aria-invalid": Boolean(error),
496
+ invalid: Boolean(error),
481
497
  placeholder: placeholderFor(field),
482
498
  ...register(registerName)
483
499
  }
@@ -491,6 +507,7 @@ var FIELD_CONTROLS = {
491
507
  step: "any",
492
508
  required: field.required,
493
509
  "aria-invalid": Boolean(error),
510
+ invalid: Boolean(error),
494
511
  ...register(registerName, { setValueAs: canonicalNumber })
495
512
  }
496
513
  ),
@@ -503,6 +520,7 @@ var FIELD_CONTROLS = {
503
520
  autoComplete: "tel",
504
521
  required: field.required,
505
522
  "aria-invalid": Boolean(error),
523
+ invalid: Boolean(error),
506
524
  placeholder: placeholderFor(field),
507
525
  ...register(registerName, { setValueAs: trimmed })
508
526
  }
@@ -516,6 +534,7 @@ var FIELD_CONTROLS = {
516
534
  type: "date",
517
535
  required: field.required,
518
536
  "aria-invalid": Boolean(error),
537
+ invalid: Boolean(error),
519
538
  ...register(registerName)
520
539
  }
521
540
  )
@@ -526,7 +545,16 @@ var FIELD_CONTROLS = {
526
545
  control,
527
546
  name: registerName,
528
547
  render: ({ field: rhf }) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkVZMST7BDcjs.Select, { value: _nullishCoalesce(rhf.value, () => ( "")), onValueChange: rhf.onChange, children: [
529
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkVZMST7BDcjs.SelectTrigger, { id, "aria-required": field.required || void 0, "aria-invalid": Boolean(error), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkVZMST7BDcjs.SelectValue, { placeholder: "Select\u2026" }) }),
548
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
549
+ _chunkVZMST7BDcjs.SelectTrigger,
550
+ {
551
+ id,
552
+ "aria-required": field.required || void 0,
553
+ "aria-invalid": Boolean(error),
554
+ invalid: Boolean(error),
555
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkVZMST7BDcjs.SelectValue, { placeholder: "Select\u2026" })
556
+ }
557
+ ),
530
558
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkVZMST7BDcjs.SelectContent, { children: (_nullishCoalesce(field.options, () => ( []))).map((opt) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkVZMST7BDcjs.SelectItem, { value: opt, children: optionLabel(field, opt) }, opt)) })
531
559
  ] })
532
560
  }
@@ -616,6 +644,8 @@ function BookingForm({
616
644
  submitLabel,
617
645
  footerNote,
618
646
  fieldRows,
647
+ fieldCopy,
648
+ deniedEmailDomains,
619
649
  consent,
620
650
  isSubmitting,
621
651
  onSubmit,
@@ -626,11 +656,11 @@ function BookingForm({
626
656
  const { formFields, legalConsent } = availability;
627
657
  const supportedFields = _react.useMemo.call(void 0, () => normalizeFormFields(formFields), [formFields]);
628
658
  const schema = _react.useMemo.call(void 0,
629
- () => makeDeferredBookingSchema(supportedFields, legalConsent),
630
- [supportedFields, legalConsent]
659
+ () => withDeniedEmailDomains(makeDeferredBookingSchema(supportedFields, legalConsent), deniedEmailDomains),
660
+ [supportedFields, legalConsent, deniedEmailDomains]
631
661
  );
632
662
  const consentDefaults = _react.useMemo.call(void 0,
633
- () => (_nullishCoalesce(_optionalChain([legalConsent, 'optionalAccess', _12 => _12.communicationConsentCheckboxes]), () => ( []))).map((c) => ({
663
+ () => (_nullishCoalesce(_optionalChain([legalConsent, 'optionalAccess', _19 => _19.communicationConsentCheckboxes]), () => ( []))).map((c) => ({
634
664
  communicationTypeId: c.communicationTypeId,
635
665
  consented: false
636
666
  })),
@@ -662,8 +692,8 @@ function BookingForm({
662
692
  ..._nullishCoalesce(initialValues, () => ( {}))
663
693
  }
664
694
  });
665
- const priorConsents = _optionalChain([initialValues, 'optionalAccess', _13 => _13.legalConsentResponses]);
666
- const [consented, setConsented] = _react.useState.call(void 0, _optionalChain([initialValues, 'optionalAccess', _14 => _14[HOST_CONSENT_KEY]]) === true);
695
+ const priorConsents = _optionalChain([initialValues, 'optionalAccess', _20 => _20.legalConsentResponses]);
696
+ const [consented, setConsented] = _react.useState.call(void 0, _optionalChain([initialValues, 'optionalAccess', _21 => _21[HOST_CONSENT_KEY]]) === true);
667
697
  const [consentError, setConsentError] = _react.useState.call(void 0, null);
668
698
  const consentMissing = Boolean(consent) && !consented;
669
699
  _react.useEffect.call(void 0, () => {
@@ -672,7 +702,7 @@ function BookingForm({
672
702
  "legalConsentResponses",
673
703
  consentDefaults.map((next) => ({
674
704
  ...next,
675
- consented: _nullishCoalesce(_optionalChain([current, 'access', _15 => _15.find, 'call', _16 => _16((r) => r.communicationTypeId === next.communicationTypeId), 'optionalAccess', _17 => _17.consented]), () => ( false))
705
+ consented: _nullishCoalesce(_optionalChain([current, 'access', _22 => _22.find, 'call', _23 => _23((r) => r.communicationTypeId === next.communicationTypeId), 'optionalAccess', _24 => _24.consented]), () => ( false))
676
706
  })),
677
707
  { shouldDirty: false }
678
708
  );
@@ -690,6 +720,16 @@ function BookingForm({
690
720
  fieldPath: (name) => BUILT_IN_BOOKING_FIELDS.some((field) => field.name === name) ? name : `formFields.${name}`
691
721
  }
692
722
  );
723
+ const { toast } = _chunkRCLYHHB3cjs.useToast.call(void 0, );
724
+ const onInvalid = () => {
725
+ if (deniedEmailDomains && emailDomainDenied(getValues("email"), deniedEmailDomains)) {
726
+ toast({
727
+ variant: "error",
728
+ title: "Check your email address",
729
+ description: deniedEmailDomains.message
730
+ });
731
+ }
732
+ };
693
733
  const submitValid = handleSubmit(async (data) => {
694
734
  if (consentMissing) return;
695
735
  if (deferSlot) {
@@ -706,27 +746,41 @@ function BookingForm({
706
746
  ...getSignals(),
707
747
  ...formRescue.submitFields()
708
748
  });
709
- });
749
+ }, onInvalid);
710
750
  const submit = (event) => {
711
- if (consentMissing) setConsentError(_nullishCoalesce(_optionalChain([consent, 'optionalAccess', _18 => _18.errorMessage]), () => ( "Please agree to continue.")));
751
+ if (consentMissing) setConsentError(_nullishCoalesce(_optionalChain([consent, 'optionalAccess', _25 => _25.errorMessage]), () => ( "Please agree to continue.")));
712
752
  return submitValid(event);
713
753
  };
714
754
  const fieldError = (name) => {
715
- const err = _optionalChain([errors, 'access', _19 => _19.formFields, 'optionalAccess', _20 => _20[name]]);
716
- return _optionalChain([err, 'optionalAccess', _21 => _21.message]);
755
+ const err = _optionalChain([errors, 'access', _26 => _26.formFields, 'optionalAccess', _27 => _27[name]]);
756
+ return _optionalChain([err, 'optionalAccess', _28 => _28.message]);
757
+ };
758
+ const renderField = (field, where) => {
759
+ const copy = _optionalChain([fieldCopy, 'optionalAccess', _29 => _29[field.name]]);
760
+ const shown = copy ? { ...field, label: _nullishCoalesce(copy.label, () => ( field.label)), placeholder: _nullishCoalesce(copy.placeholder, () => ( field.placeholder)) } : field;
761
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
762
+ _chunkQVSVRG7Icjs.FieldWrapper,
763
+ {
764
+ label: shown.label,
765
+ htmlFor: where.id,
766
+ required: shown.required,
767
+ error: where.error,
768
+ children: FIELD_CONTROLS[shown.type]({
769
+ field: shown,
770
+ id: where.id,
771
+ registerName: where.registerName,
772
+ error: where.error,
773
+ register,
774
+ control
775
+ })
776
+ },
777
+ shown.name
778
+ );
717
779
  };
718
- const renderField = (field, where) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkQVSVRG7Icjs.FieldWrapper, { label: field.label, htmlFor: where.id, required: field.required, error: where.error, children: FIELD_CONTROLS[field.type]({
719
- field,
720
- id: where.id,
721
- registerName: where.registerName,
722
- error: where.error,
723
- register,
724
- control
725
- }) }, field.name);
726
780
  const builtInFields = Object.fromEntries(
727
781
  BUILT_IN_BOOKING_FIELDS.map((field) => [
728
782
  field.name,
729
- renderField(field, { id: builtInId(field.name), registerName: field.name, error: _optionalChain([errors, 'access', _22 => _22[field.name], 'optionalAccess', _23 => _23.message]) })
783
+ renderField(field, { id: builtInId(field.name), registerName: field.name, error: _optionalChain([errors, 'access', _30 => _30[field.name], 'optionalAccess', _31 => _31.message]) })
730
784
  ])
731
785
  );
732
786
  const renderDeclaredField = (field) => renderField(field, {
@@ -787,7 +841,7 @@ function BookingForm({
787
841
  // box doesn't shove the submit button down the card. With no error the
788
842
  // wrapper is `display:contents` and the panel below is the flex item,
789
843
  // exactly as it was.
790
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkQVSVRG7Icjs.FieldWrapper, { error: _optionalChain([errors, 'access', _24 => _24.legalConsentResponses, 'optionalAccess', _25 => _25.message]), children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-[var(--spacing-system-xs)]", children: [
844
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkQVSVRG7Icjs.FieldWrapper, { error: _optionalChain([errors, 'access', _32 => _32.legalConsentResponses, 'optionalAccess', _33 => _33.message]), children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-[var(--spacing-system-xs)]", children: [
791
845
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-ods-text-secondary text-h6", children: legalConsent.processingConsentText }),
792
846
  legalConsent.communicationConsentText && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-ods-text-secondary text-h6", children: legalConsent.communicationConsentText }),
793
847
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -806,7 +860,7 @@ function BookingForm({
806
860
  _chunkVZMST7BDcjs.CheckboxBlock,
807
861
  {
808
862
  id: `ms-consent-${box.communicationTypeId}`,
809
- checked: _nullishCoalesce(_optionalChain([current, 'optionalAccess', _26 => _26.consented]), () => ( false)),
863
+ checked: _nullishCoalesce(_optionalChain([current, 'optionalAccess', _34 => _34.consented]), () => ( false)),
810
864
  onCheckedChange: (v) => rhf.onChange(
811
865
  responses.map(
812
866
  (r) => r.communicationTypeId === box.communicationTypeId ? { ...r, consented: v } : r
@@ -901,7 +955,7 @@ function zoneLabel(tz) {
901
955
  timeZone: tz,
902
956
  timeZoneName: "shortOffset"
903
957
  }).formatToParts(/* @__PURE__ */ new Date());
904
- const offset = _nullishCoalesce(_optionalChain([parts, 'access', _27 => _27.find, 'call', _28 => _28((p) => p.type === "timeZoneName"), 'optionalAccess', _29 => _29.value]), () => ( ""));
958
+ const offset = _nullishCoalesce(_optionalChain([parts, 'access', _35 => _35.find, 'call', _36 => _36((p) => p.type === "timeZoneName"), 'optionalAccess', _37 => _37.value]), () => ( ""));
905
959
  return offset ? `${tz.replace(/_/g, " ")} (${offset})` : tz.replace(/_/g, " ");
906
960
  } catch (e4) {
907
961
  return tz.replace(/_/g, " ");
@@ -1028,7 +1082,7 @@ function SchedulerContextPanel({
1028
1082
  value: timezone,
1029
1083
  disabled,
1030
1084
  onChange: (tz) => {
1031
- if (tz) _optionalChain([onTimezoneChange, 'optionalCall', _30 => _30(tz)]);
1085
+ if (tz) _optionalChain([onTimezoneChange, 'optionalCall', _38 => _38(tz)]);
1032
1086
  },
1033
1087
  options: zoneOptions,
1034
1088
  placeholder: "Search timezone\u2026",
@@ -1112,7 +1166,7 @@ function DayCalendar({ monthOffset, onMonthOffsetChange, selectedDay, onSelectDa
1112
1166
  const startMonth = new Date(now.getFullYear(), now.getMonth(), 1);
1113
1167
  const endMonth = new Date(now.getFullYear(), now.getMonth() + _chunkVZMST7BDcjs.MAX_MONTH_OFFSET + 1, 0);
1114
1168
  const visibleMonth = new Date(now.getFullYear(), now.getMonth() + monthOffset, 1);
1115
- const dayHasNoSlots = _react.useCallback.call(void 0, (day) => !_optionalChain([slotsByDay, 'optionalAccess', _31 => _31.has, 'call', _32 => _32(calendarDayKey(day))]), [slotsByDay]);
1169
+ const dayHasNoSlots = _react.useCallback.call(void 0, (day) => !_optionalChain([slotsByDay, 'optionalAccess', _39 => _39.has, 'call', _40 => _40(calendarDayKey(day))]), [slotsByDay]);
1116
1170
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex min-h-0 flex-1 flex-col", "aria-busy": slotsByDay === null, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1117
1171
  _chunkVZMST7BDcjs.DatePickerCalendar,
1118
1172
  {
@@ -1130,7 +1184,7 @@ function DayCalendar({ monthOffset, onMonthOffsetChange, selectedDay, onSelectDa
1130
1184
  const day = value;
1131
1185
  if (!day) return;
1132
1186
  const key = calendarDayKey(day);
1133
- if (_optionalChain([slotsByDay, 'optionalAccess', _33 => _33.has, 'call', _34 => _34(key)])) onSelectDay(key);
1187
+ if (_optionalChain([slotsByDay, 'optionalAccess', _41 => _41.has, 'call', _42 => _42(key)])) onSelectDay(key);
1134
1188
  },
1135
1189
  disabledDays: slotsByDay === null ? DISABLE_EVERY_DAY : dayHasNoSlots
1136
1190
  }
@@ -1354,7 +1408,7 @@ function MeetingSchedulerDirectory({
1354
1408
  };
1355
1409
  }, [initialData, includeAll, apiBaseUrl]);
1356
1410
  const rows = _react.useMemo.call(void 0, () => {
1357
- const purposes = _nullishCoalesce(_optionalChain([data, 'optionalAccess', _35 => _35.purposes]), () => ( []));
1411
+ const purposes = _nullishCoalesce(_optionalChain([data, 'optionalAccess', _43 => _43.purposes]), () => ( []));
1358
1412
  return purposes.flatMap((p) => p.links.map((link) => ({ link, audienceLabel: p.label })));
1359
1413
  }, [data]);
1360
1414
  const totalPages = _chunkVTYP25OWcjs.pageCount.call(void 0, rows.length, pageSize);
@@ -1511,7 +1565,7 @@ function HubSpotMeetingScheduler({
1511
1565
  onStageChangeRef.current = onStageChange;
1512
1566
  });
1513
1567
  _react.useEffect.call(void 0, () => {
1514
- _optionalChain([onStageChangeRef, 'access', _36 => _36.current, 'optionalCall', _37 => _37(stage)]);
1568
+ _optionalChain([onStageChangeRef, 'access', _44 => _44.current, 'optionalCall', _45 => _45(stage)]);
1515
1569
  }, [stage]);
1516
1570
  const [stash, setStash] = _react.useState.call(void 0, null);
1517
1571
  const inFlightRef = _react.useRef.call(void 0, false);
@@ -1542,8 +1596,8 @@ function HubSpotMeetingScheduler({
1542
1596
  _react.useEffect.call(void 0, () => {
1543
1597
  autoAdvanceCount.current = 0;
1544
1598
  }, [meetingId]);
1545
- const durations = _react.useMemo.call(void 0, () => _nullishCoalesce(_optionalChain([availability, 'optionalAccess', _38 => _38.durationsMs]), () => ( [])), [_optionalChain([availability, 'optionalAccess', _39 => _39.durationsMs])]);
1546
- const shownHosts = _nullishCoalesce(_nullishCoalesce(hosts, () => ( _optionalChain([availability, 'optionalAccess', _40 => _40.hosts]))), () => ( []));
1599
+ const durations = _react.useMemo.call(void 0, () => _nullishCoalesce(_optionalChain([availability, 'optionalAccess', _46 => _46.durationsMs]), () => ( [])), [_optionalChain([availability, 'optionalAccess', _47 => _47.durationsMs])]);
1600
+ const shownHosts = _nullishCoalesce(_nullishCoalesce(hosts, () => ( _optionalChain([availability, 'optionalAccess', _48 => _48.hosts]))), () => ( []));
1547
1601
  const durationMs = _nullishCoalesce(_nullishCoalesce(pickedDurationMs, () => ( durations[0])), () => ( null));
1548
1602
  const slots = _react.useMemo.call(void 0, () => {
1549
1603
  if (!availability || durationMs == null) return [];
@@ -1603,7 +1657,7 @@ function HubSpotMeetingScheduler({
1603
1657
  _chunkRCLYHHB3cjs.completeFormRescue.call(void 0, rescue, payload[_chunkRCLYHHB3cjs.FORM_RESCUE_ATTEMPT_FIELD]);
1604
1658
  setConfirmation(result.confirmation);
1605
1659
  setStep("confirmed");
1606
- _optionalChain([onBooked, 'optionalCall', _41 => _41(result.confirmation)]);
1660
+ _optionalChain([onBooked, 'optionalCall', _49 => _49(result.confirmation)]);
1607
1661
  return;
1608
1662
  }
1609
1663
  const code = _nullishCoalesce(result.code, () => ( "TEMPORARILY_UNAVAILABLE"));
@@ -1651,8 +1705,8 @@ function HubSpotMeetingScheduler({
1651
1705
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: stepPanelClass, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1652
1706
  BookingFormSkeleton,
1653
1707
  {
1654
- fieldRows: _optionalChain([detailsFormProps, 'optionalAccess', _42 => _42.fieldRows]),
1655
- consent: Boolean(_optionalChain([detailsFormProps, 'optionalAccess', _43 => _43.consent])),
1708
+ fieldRows: _optionalChain([detailsFormProps, 'optionalAccess', _50 => _50.fieldRows]),
1709
+ consent: Boolean(_optionalChain([detailsFormProps, 'optionalAccess', _51 => _51.consent])),
1656
1710
  footerNote: preset.footerNote
1657
1711
  }
1658
1712
  ) })
@@ -1713,7 +1767,7 @@ function HubSpotMeetingScheduler({
1713
1767
  deferSlot: detailsFirst,
1714
1768
  submitLabel: preset.submitLabel,
1715
1769
  footerNote: preset.footerNote,
1716
- initialValues: detailsFirst ? _optionalChain([stash, 'optionalAccess', _44 => _44.payload]) : void 0,
1770
+ initialValues: detailsFirst ? _optionalChain([stash, 'optionalAccess', _52 => _52.payload]) : void 0,
1717
1771
  isSubmitting,
1718
1772
  onSubmit: detailsFirst ? stashDetails : handleSubmit,
1719
1773
  honeypotInputProps,