@flamingo-stack/openframe-frontend-core 0.0.676 → 0.0.677
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/dist/components/meeting-scheduler/booking-form.d.ts +21 -2
- package/dist/components/meeting-scheduler/booking-form.d.ts.map +1 -1
- package/dist/components/meeting-scheduler/index.cjs +92 -38
- package/dist/components/meeting-scheduler/index.cjs.map +1 -1
- package/dist/components/meeting-scheduler/index.d.ts +7 -6
- package/dist/components/meeting-scheduler/index.d.ts.map +1 -1
- package/dist/components/meeting-scheduler/index.js +66 -12
- package/dist/components/meeting-scheduler/index.js.map +1 -1
- package/dist/schemas/meeting-booking-schema.cjs +16 -0
- package/dist/schemas/meeting-booking-schema.cjs.map +1 -1
- package/dist/schemas/meeting-booking-schema.d.ts +34 -0
- package/dist/schemas/meeting-booking-schema.d.ts.map +1 -1
- package/dist/schemas/meeting-booking-schema.js +15 -1
- package/dist/schemas/meeting-booking-schema.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/meeting-scheduler-details-first.test.tsx +42 -1
- package/src/components/meeting-scheduler/booking-form.tsx +91 -17
- package/src/components/meeting-scheduler/index.tsx +7 -5
- package/src/schemas/meeting-booking-schema.ts +34 -0
|
@@ -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":"AAIA,OAAO,KAAK,EAAa,SAAS,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;
|
|
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',
|
|
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',
|
|
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',
|
|
452
|
-
var optionLabel = (field, value) => _nullishCoalesce(_optionalChain([field, 'access',
|
|
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,
|
|
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',
|
|
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',
|
|
666
|
-
const [consented, setConsented] = _react.useState.call(void 0, _optionalChain([initialValues, 'optionalAccess',
|
|
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',
|
|
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',
|
|
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',
|
|
716
|
-
return _optionalChain([err, 'optionalAccess',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
1546
|
-
const shownHosts = _nullishCoalesce(_nullishCoalesce(hosts, () => ( _optionalChain([availability, 'optionalAccess',
|
|
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',
|
|
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',
|
|
1655
|
-
consent: Boolean(_optionalChain([detailsFormProps, 'optionalAccess',
|
|
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',
|
|
1770
|
+
initialValues: detailsFirst ? _optionalChain([stash, 'optionalAccess', _52 => _52.payload]) : void 0,
|
|
1717
1771
|
isSubmitting,
|
|
1718
1772
|
onSubmit: detailsFirst ? stashDetails : handleSubmit,
|
|
1719
1773
|
honeypotInputProps,
|