@flamingo-stack/openframe-frontend-core 0.0.664 → 0.0.665-2372.7066.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.
- package/dist/components/meeting-scheduler/booking-form.d.ts.map +1 -1
- package/dist/components/meeting-scheduler/index.cjs +177 -35
- package/dist/components/meeting-scheduler/index.cjs.map +1 -1
- package/dist/components/meeting-scheduler/index.d.ts.map +1 -1
- package/dist/components/meeting-scheduler/index.js +151 -9
- package/dist/components/meeting-scheduler/index.js.map +1 -1
- package/dist/schemas/meeting-booking-schema.cjs +107 -6
- package/dist/schemas/meeting-booking-schema.cjs.map +1 -1
- package/dist/schemas/meeting-booking-schema.d.ts +105 -19
- package/dist/schemas/meeting-booking-schema.d.ts.map +1 -1
- package/dist/schemas/meeting-booking-schema.js +99 -7
- package/dist/schemas/meeting-booking-schema.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/meeting-booking-schema.test.ts +2 -2
- package/src/__tests__/meeting-form-field-types.test.tsx +240 -0
- package/src/__tests__/meeting-scheduler-details-first.test.tsx +33 -0
- package/src/components/meeting-scheduler/booking-form.tsx +67 -4
- package/src/components/meeting-scheduler/index.tsx +9 -6
- package/src/schemas/meeting-booking-schema.ts +231 -25
- package/src/utils/__tests__/hubspot-meetings-convention.test.ts +15 -6
|
@@ -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;AAGvD,OAAO,EAEL,KAAK,uBAAuB,
|
|
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;AAGvD,OAAO,EAEL,KAAK,uBAAuB,EAQ5B,KAAK,mBAAmB,EAKzB,MAAM,sCAAsC,CAAC;AAsB9C;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,yFAAyF;IACzF,IAAI,EAAE,uBAAuB,GAAG,CAAC,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;IAChE,gFAAgF;IAChF,IAAI,CAAC,EAAE,gBAAgB,CAAC;CACzB;AAED,+EAA+E;AAC/E,MAAM,MAAM,gBAAgB,GAAG,MAAM,OAAO,UAAU,CAAC;AAEvD,MAAM,MAAM,eAAe,GAAG,gBAAgB,EAAE,CAAC;AAEjD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAiBD;6CAC6C;AAC7C,QAAA,MAAM,UAAU;;;;;CAKN,CAAC;AAOX,0GAA0G;AAC1G,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AAYtD;iFACiF;AACjF,eAAO,MAAM,QAAQ,GAAI,OAAO,MAAM,EAAE,OAAO,MAAM,KAAG,gBAIvD,CAAC;AA+MF,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,mBAAmB,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;qEACiE;IACjE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,eAAe,EAAE,CAAC;IAC9B,uFAAuF;IACvF,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,mFAAmF;IACnF,kBAAkB,EAAE;QAAE,GAAG,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACjE,UAAU,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;CACnD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,EAC1B,YAAY,EACZ,SAAS,EACT,WAAW,EACX,UAAU,EACV,QAAQ,EACR,SAAiB,EACjB,aAAa,EACb,WAAW,EACX,UAAU,EACV,SAAS,EACT,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,kBAAkB,EAClB,UAAU,GACX,EAAE,gBAAgB,+BAuTlB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,SAAS,EACT,OAAO,EACP,UAAU,GACX,EAAE;IACD,SAAS,CAAC,EAAE,eAAe,EAAE,CAAC;IAC9B;;qDAEiD;IACjD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,+BA2BA"}
|
|
@@ -101,6 +101,18 @@ var optionValidator = (field, base) => base.refine((v) => !v || (_nullishCoalesc
|
|
|
101
101
|
message: `Please choose a valid option for ${field.label}`
|
|
102
102
|
});
|
|
103
103
|
var DECIMAL_LITERAL_RE = /^-?\d+(\.\d+)?$/;
|
|
104
|
+
var MULTI_VALUE_SEPARATOR = ";";
|
|
105
|
+
var splitMultiValue = (value) => typeof value === "string" && value ? value.split(MULTI_VALUE_SEPARATOR) : [];
|
|
106
|
+
var PHONE_RE = /^\+?[\d\s().\-/]+(?:\s*(?:x|ext\.?)\s*\d+)?$/i;
|
|
107
|
+
var PHONE_MIN_DIGITS = 5;
|
|
108
|
+
var PHONE_MAX_DIGITS = 20;
|
|
109
|
+
var phoneDigits = (v) => v.replace(/\D/g, "").length;
|
|
110
|
+
var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
111
|
+
var isRealIsoDate = (v) => {
|
|
112
|
+
if (!ISO_DATE_RE.test(v)) return false;
|
|
113
|
+
const d = /* @__PURE__ */ new Date(`${v}T00:00:00Z`);
|
|
114
|
+
return !Number.isNaN(d.getTime()) && d.toISOString().slice(0, 10) === v;
|
|
115
|
+
};
|
|
104
116
|
var FORM_FIELD_TYPES = {
|
|
105
117
|
text: {
|
|
106
118
|
kind: "string",
|
|
@@ -121,16 +133,88 @@ var FORM_FIELD_TYPES = {
|
|
|
121
133
|
// accepts (`1e3`, `007`) to this before it is validated or sent.
|
|
122
134
|
validator: (field, base) => base.max(32, { message: `${field.label} is too long` }).regex(DECIMAL_LITERAL_RE, { message: `${field.label} must be a number` })
|
|
123
135
|
},
|
|
136
|
+
phone: {
|
|
137
|
+
kind: "string",
|
|
138
|
+
hasOptions: false,
|
|
139
|
+
validator: (field, base) => base.max(40, { message: `${field.label} is too long` }).refine(
|
|
140
|
+
(v) => !v || PHONE_RE.test(v) && phoneDigits(v) >= PHONE_MIN_DIGITS && phoneDigits(v) <= PHONE_MAX_DIGITS,
|
|
141
|
+
{ message: `Please enter a valid phone number for ${field.label}` }
|
|
142
|
+
),
|
|
143
|
+
placeholder: (field) => `Enter ${field.label}`
|
|
144
|
+
},
|
|
145
|
+
date: {
|
|
146
|
+
kind: "string",
|
|
147
|
+
hasOptions: false,
|
|
148
|
+
validator: (field, base) => base.refine((v) => !v || isRealIsoDate(v), { message: `${field.label} must be a date` })
|
|
149
|
+
},
|
|
124
150
|
select: { kind: "string", hasOptions: true, validator: optionValidator },
|
|
125
151
|
radio: { kind: "string", hasOptions: true, validator: optionValidator },
|
|
152
|
+
multiselect: {
|
|
153
|
+
kind: "string",
|
|
154
|
+
hasOptions: true,
|
|
155
|
+
validator: (field, base) => base.refine((v) => splitMultiValue(v).every((part) => (_nullishCoalesce(field.options, () => ( []))).includes(part)), {
|
|
156
|
+
message: `Please choose valid options for ${field.label}`
|
|
157
|
+
})
|
|
158
|
+
},
|
|
126
159
|
checkbox: { kind: "boolean", hasOptions: false, validator: () => _zod.z.boolean() }
|
|
127
160
|
};
|
|
128
161
|
var SUPPORTED_FORM_FIELD_TYPES = Object.keys(FORM_FIELD_TYPES);
|
|
162
|
+
var FIELD_TYPE_CONTROLS = {
|
|
163
|
+
text: "text",
|
|
164
|
+
textarea: "textarea",
|
|
165
|
+
number: "number",
|
|
166
|
+
select: "select",
|
|
167
|
+
radio: "radio",
|
|
168
|
+
booleancheckbox: "checkbox",
|
|
169
|
+
phonenumber: "phone",
|
|
170
|
+
date: "date",
|
|
171
|
+
html: "display",
|
|
172
|
+
file: "unanswerable"
|
|
173
|
+
};
|
|
174
|
+
var DATA_TYPE_CONTROLS = {
|
|
175
|
+
string: "text",
|
|
176
|
+
number: "number",
|
|
177
|
+
enumeration: "select",
|
|
178
|
+
bool: "checkbox",
|
|
179
|
+
date: "date",
|
|
180
|
+
datetime: "date",
|
|
181
|
+
phone_number: "phone"
|
|
182
|
+
};
|
|
183
|
+
var hasDeclaredOptions = (field) => (_nullishCoalesce(_optionalChain([field, 'access', _2 => _2.options, 'optionalAccess', _3 => _3.length]), () => ( 0))) > 0;
|
|
184
|
+
function resolveFormFieldControl(field) {
|
|
185
|
+
const fieldType = (_nullishCoalesce(field.type, () => ( ""))).toLowerCase();
|
|
186
|
+
const withOptions = hasDeclaredOptions(field);
|
|
187
|
+
const usable = (r) => {
|
|
188
|
+
if (!r || r === "display" || r === "unanswerable") return r;
|
|
189
|
+
return FORM_FIELD_TYPES[r].hasOptions && !withOptions ? "text" : r;
|
|
190
|
+
};
|
|
191
|
+
if (fieldType === "checkbox") return withOptions ? "multiselect" : "checkbox";
|
|
192
|
+
if (fieldType.startsWith("calculation")) return "display";
|
|
193
|
+
const asControl = Object.prototype.hasOwnProperty.call(FORM_FIELD_TYPES, fieldType) ? fieldType : void 0;
|
|
194
|
+
return _nullishCoalesce(_nullishCoalesce(usable(_nullishCoalesce(FIELD_TYPE_CONTROLS[fieldType], () => ( asControl))), () => ( usable(DATA_TYPE_CONTROLS[(_nullishCoalesce(field.dataType, () => ( ""))).toLowerCase()]))), () => ( (withOptions ? "select" : "text")));
|
|
195
|
+
}
|
|
129
196
|
var FORM_FIELD_TYPES_WITH_OPTIONS = SUPPORTED_FORM_FIELD_TYPES.filter(
|
|
130
197
|
(type) => FORM_FIELD_TYPES[type].hasOptions
|
|
131
198
|
);
|
|
132
|
-
function
|
|
133
|
-
|
|
199
|
+
function normalizeFormField(field) {
|
|
200
|
+
const control = resolveFormFieldControl(field);
|
|
201
|
+
if (control === "display" || control === "unanswerable") return null;
|
|
202
|
+
const normalized = {
|
|
203
|
+
...field,
|
|
204
|
+
type: control,
|
|
205
|
+
hubspotType: _nullishCoalesce(field.hubspotType, () => ( field.type))
|
|
206
|
+
};
|
|
207
|
+
if (!FORM_FIELD_TYPES[control].hasOptions) {
|
|
208
|
+
delete normalized.options;
|
|
209
|
+
delete normalized.optionLabels;
|
|
210
|
+
}
|
|
211
|
+
return normalized;
|
|
212
|
+
}
|
|
213
|
+
function normalizeFormFields(fields) {
|
|
214
|
+
return fields.flatMap((f) => _nullishCoalesce(normalizeFormField(f), () => ( [])));
|
|
215
|
+
}
|
|
216
|
+
function blocksNativeBooking(field) {
|
|
217
|
+
return field.required && resolveFormFieldControl(field) === "unanswerable";
|
|
134
218
|
}
|
|
135
219
|
var BUILT_IN_BOOKING_FIELDS = [
|
|
136
220
|
{
|
|
@@ -188,8 +272,8 @@ function isValidBcp47Locale(locale) {
|
|
|
188
272
|
}
|
|
189
273
|
function buildBookingSchema(formFields, legalConsent, slot) {
|
|
190
274
|
const answers = {};
|
|
191
|
-
|
|
192
|
-
|
|
275
|
+
const drawn = normalizeFormFields(formFields);
|
|
276
|
+
for (const field of drawn) {
|
|
193
277
|
const spec = FORM_FIELD_TYPES[field.type];
|
|
194
278
|
let validator;
|
|
195
279
|
if (spec.kind === "boolean") {
|
|
@@ -201,8 +285,8 @@ function buildBookingSchema(formFields, legalConsent, slot) {
|
|
|
201
285
|
}
|
|
202
286
|
answers[field.name] = validator;
|
|
203
287
|
}
|
|
204
|
-
const requiredConsentIds = (_nullishCoalesce(_optionalChain([legalConsent, 'optionalAccess',
|
|
205
|
-
const hasRequiredAnswers =
|
|
288
|
+
const requiredConsentIds = (_nullishCoalesce(_optionalChain([legalConsent, 'optionalAccess', _4 => _4.communicationConsentCheckboxes]), () => ( []))).filter((c) => c.required).map((c) => c.communicationTypeId);
|
|
289
|
+
const hasRequiredAnswers = drawn.some((f) => f.required);
|
|
206
290
|
const answersObject = _zod.z.object(answers);
|
|
207
291
|
return _zod.z.object({
|
|
208
292
|
meetingId: _zod.z.string().min(1),
|
|
@@ -254,7 +338,7 @@ var BOOKING_IN_FLIGHT_MESSAGE = "Already submitting";
|
|
|
254
338
|
function useMeetingBooking(options) {
|
|
255
339
|
const { meetingId, apiBaseUrl = "", initialAvailability } = options;
|
|
256
340
|
const queryClient = _reactquery.useQueryClient.call(void 0, );
|
|
257
|
-
const seededOffset = _optionalChain([initialAvailability, 'optionalAccess',
|
|
341
|
+
const seededOffset = _optionalChain([initialAvailability, 'optionalAccess', _5 => _5.meetingId]) === meetingId ? initialAvailability.monthOffset : void 0;
|
|
258
342
|
const [monthOffset, setMonthOffsetState] = _react.useState.call(void 0, _nullishCoalesce(seededOffset, () => ( 0)));
|
|
259
343
|
const setMonthOffset = _react.useCallback.call(void 0, (offset) => {
|
|
260
344
|
setMonthOffsetState(Math.max(0, Math.min(_chunk6FD7ZEBYcjs.MAX_MONTH_OFFSET, offset)));
|
|
@@ -265,7 +349,7 @@ function useMeetingBooking(options) {
|
|
|
265
349
|
prevMeetingIdRef.current = meetingId;
|
|
266
350
|
setMonthOffsetState(0);
|
|
267
351
|
}, [meetingId]);
|
|
268
|
-
const seed = _optionalChain([initialAvailability, 'optionalAccess',
|
|
352
|
+
const seed = _optionalChain([initialAvailability, 'optionalAccess', _6 => _6.meetingId]) === meetingId && initialAvailability.monthOffset === monthOffset ? initialAvailability : void 0;
|
|
269
353
|
const availabilityQuery = _reactquery.useQuery.call(void 0, {
|
|
270
354
|
queryKey: meetingAvailabilityKey(apiBaseUrl, meetingId, monthOffset),
|
|
271
355
|
queryFn: async ({ signal }) => {
|
|
@@ -361,7 +445,9 @@ var evenSpan = (count, index) => {
|
|
|
361
445
|
return Math.min(GRID_COLUMNS, Math.max(1, index < extra ? base + 1 : base));
|
|
362
446
|
};
|
|
363
447
|
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)))]);
|
|
364
|
-
var placeholderFor = (field) => _nullishCoalesce(field.placeholder, () => ( _optionalChain([fieldTypeSpec, 'call',
|
|
448
|
+
var placeholderFor = (field) => _nullishCoalesce(field.placeholder, () => ( _optionalChain([fieldTypeSpec, 'call', _7 => _7(field.type), 'access', _8 => _8.placeholder, 'optionalCall', _9 => _9(field)])));
|
|
449
|
+
var optionLabel = (field, value) => _nullishCoalesce(_optionalChain([field, 'access', _10 => _10.optionLabels, 'optionalAccess', _11 => _11[value]]), () => ( value));
|
|
450
|
+
var trimmed = (v) => String(_nullishCoalesce(v, () => ( ""))).trim();
|
|
365
451
|
var canonicalNumber = (v) => {
|
|
366
452
|
const s = String(_nullishCoalesce(v, () => ( ""))).trim();
|
|
367
453
|
if (s === "" || DECIMAL_LITERAL_RE.test(s)) return s;
|
|
@@ -405,6 +491,32 @@ var FIELD_CONTROLS = {
|
|
|
405
491
|
...register(registerName, { setValueAs: canonicalNumber })
|
|
406
492
|
}
|
|
407
493
|
),
|
|
494
|
+
phone: ({ field, id, registerName, error, register }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
495
|
+
_chunkQVSVRG7Icjs.Input,
|
|
496
|
+
{
|
|
497
|
+
id,
|
|
498
|
+
type: "tel",
|
|
499
|
+
inputMode: "tel",
|
|
500
|
+
autoComplete: "tel",
|
|
501
|
+
required: field.required,
|
|
502
|
+
"aria-invalid": Boolean(error),
|
|
503
|
+
placeholder: placeholderFor(field),
|
|
504
|
+
...register(registerName, { setValueAs: trimmed })
|
|
505
|
+
}
|
|
506
|
+
),
|
|
507
|
+
date: ({ field, id, registerName, error, register }) => (
|
|
508
|
+
// The native picker emits exactly the wire shape (`YYYY-MM-DD`).
|
|
509
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
510
|
+
_chunkQVSVRG7Icjs.Input,
|
|
511
|
+
{
|
|
512
|
+
id,
|
|
513
|
+
type: "date",
|
|
514
|
+
required: field.required,
|
|
515
|
+
"aria-invalid": Boolean(error),
|
|
516
|
+
...register(registerName)
|
|
517
|
+
}
|
|
518
|
+
)
|
|
519
|
+
),
|
|
408
520
|
select: ({ field, id, registerName, error, control }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
409
521
|
_reacthookform.Controller,
|
|
410
522
|
{
|
|
@@ -412,7 +524,7 @@ var FIELD_CONTROLS = {
|
|
|
412
524
|
name: registerName,
|
|
413
525
|
render: ({ field: rhf }) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk6FD7ZEBYcjs.Select, { value: _nullishCoalesce(rhf.value, () => ( "")), onValueChange: rhf.onChange, children: [
|
|
414
526
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6FD7ZEBYcjs.SelectTrigger, { id, "aria-required": field.required || void 0, "aria-invalid": Boolean(error), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6FD7ZEBYcjs.SelectValue, { placeholder: "Select\u2026" }) }),
|
|
415
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6FD7ZEBYcjs.SelectContent, { children: (_nullishCoalesce(field.options, () => ( []))).map((opt) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6FD7ZEBYcjs.SelectItem, { value: opt, children: opt }, opt)) })
|
|
527
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6FD7ZEBYcjs.SelectContent, { children: (_nullishCoalesce(field.options, () => ( []))).map((opt) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6FD7ZEBYcjs.SelectItem, { value: opt, children: optionLabel(field, opt) }, opt)) })
|
|
416
528
|
] })
|
|
417
529
|
}
|
|
418
530
|
),
|
|
@@ -430,12 +542,42 @@ var FIELD_CONTROLS = {
|
|
|
430
542
|
"aria-invalid": Boolean(error),
|
|
431
543
|
children: (_nullishCoalesce(field.options, () => ( []))).map((opt) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-[var(--spacing-system-xs)]", children: [
|
|
432
544
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6FD7ZEBYcjs.RadioGroupItem, { id: `${id}-${opt}`, value: opt }),
|
|
433
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGSD62VAYcjs.Label, { htmlFor: `${id}-${opt}`, children: opt })
|
|
545
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGSD62VAYcjs.Label, { htmlFor: `${id}-${opt}`, children: optionLabel(field, opt) })
|
|
434
546
|
] }, opt))
|
|
435
547
|
}
|
|
436
548
|
)
|
|
437
549
|
}
|
|
438
550
|
),
|
|
551
|
+
multiselect: ({ field, id, registerName, error, control }) => (
|
|
552
|
+
// HubSpot's "multiple checkboxes": the answer is its `;`-joined value list,
|
|
553
|
+
// held in that wire shape so the validator and the POST see one string.
|
|
554
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
555
|
+
_reacthookform.Controller,
|
|
556
|
+
{
|
|
557
|
+
control,
|
|
558
|
+
name: registerName,
|
|
559
|
+
render: ({ field: rhf }) => {
|
|
560
|
+
const selected = splitMultiValue(rhf.value);
|
|
561
|
+
const toggle = (opt, on) => {
|
|
562
|
+
const next = (_nullishCoalesce(field.options, () => ( []))).filter((o) => o === opt ? on : selected.includes(o));
|
|
563
|
+
rhf.onChange(next.join(MULTI_VALUE_SEPARATOR));
|
|
564
|
+
};
|
|
565
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { id, role: "group", className: "flex flex-col gap-[var(--spacing-system-xs)]", children: (_nullishCoalesce(field.options, () => ( []))).map((opt) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-[var(--spacing-system-xs)]", children: [
|
|
566
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
567
|
+
_chunkQVSVRG7Icjs.Checkbox,
|
|
568
|
+
{
|
|
569
|
+
id: `${id}-${opt}`,
|
|
570
|
+
checked: selected.includes(opt),
|
|
571
|
+
onCheckedChange: (v) => toggle(opt, v === true),
|
|
572
|
+
"aria-invalid": Boolean(error)
|
|
573
|
+
}
|
|
574
|
+
),
|
|
575
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGSD62VAYcjs.Label, { htmlFor: `${id}-${opt}`, children: optionLabel(field, opt) })
|
|
576
|
+
] }, opt)) });
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
)
|
|
580
|
+
),
|
|
439
581
|
checkbox: ({ field, id, registerName, error, control }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
440
582
|
_reacthookform.Controller,
|
|
441
583
|
{
|
|
@@ -478,13 +620,13 @@ function BookingForm({
|
|
|
478
620
|
getSignals
|
|
479
621
|
}) {
|
|
480
622
|
const { formFields, legalConsent } = availability;
|
|
481
|
-
const supportedFields = _react.useMemo.call(void 0, () => formFields
|
|
623
|
+
const supportedFields = _react.useMemo.call(void 0, () => normalizeFormFields(formFields), [formFields]);
|
|
482
624
|
const schema = _react.useMemo.call(void 0,
|
|
483
625
|
() => makeDeferredBookingSchema(supportedFields, legalConsent),
|
|
484
626
|
[supportedFields, legalConsent]
|
|
485
627
|
);
|
|
486
628
|
const consentDefaults = _react.useMemo.call(void 0,
|
|
487
|
-
() => (_nullishCoalesce(_optionalChain([legalConsent, 'optionalAccess',
|
|
629
|
+
() => (_nullishCoalesce(_optionalChain([legalConsent, 'optionalAccess', _12 => _12.communicationConsentCheckboxes]), () => ( []))).map((c) => ({
|
|
488
630
|
communicationTypeId: c.communicationTypeId,
|
|
489
631
|
consented: false
|
|
490
632
|
})),
|
|
@@ -515,8 +657,8 @@ function BookingForm({
|
|
|
515
657
|
..._nullishCoalesce(initialValues, () => ( {}))
|
|
516
658
|
}
|
|
517
659
|
});
|
|
518
|
-
const priorConsents = _optionalChain([initialValues, 'optionalAccess',
|
|
519
|
-
const [consented, setConsented] = _react.useState.call(void 0, _optionalChain([initialValues, 'optionalAccess',
|
|
660
|
+
const priorConsents = _optionalChain([initialValues, 'optionalAccess', _13 => _13.legalConsentResponses]);
|
|
661
|
+
const [consented, setConsented] = _react.useState.call(void 0, _optionalChain([initialValues, 'optionalAccess', _14 => _14[HOST_CONSENT_KEY]]) === true);
|
|
520
662
|
const [consentError, setConsentError] = _react.useState.call(void 0, null);
|
|
521
663
|
const consentMissing = Boolean(consent) && !consented;
|
|
522
664
|
_react.useEffect.call(void 0, () => {
|
|
@@ -525,7 +667,7 @@ function BookingForm({
|
|
|
525
667
|
"legalConsentResponses",
|
|
526
668
|
consentDefaults.map((next) => ({
|
|
527
669
|
...next,
|
|
528
|
-
consented: _nullishCoalesce(_optionalChain([current, 'access',
|
|
670
|
+
consented: _nullishCoalesce(_optionalChain([current, 'access', _15 => _15.find, 'call', _16 => _16((r) => r.communicationTypeId === next.communicationTypeId), 'optionalAccess', _17 => _17.consented]), () => ( false))
|
|
529
671
|
})),
|
|
530
672
|
{ shouldDirty: false }
|
|
531
673
|
);
|
|
@@ -547,12 +689,12 @@ function BookingForm({
|
|
|
547
689
|
});
|
|
548
690
|
});
|
|
549
691
|
const submit = (event) => {
|
|
550
|
-
if (consentMissing) setConsentError(_nullishCoalesce(_optionalChain([consent, 'optionalAccess',
|
|
692
|
+
if (consentMissing) setConsentError(_nullishCoalesce(_optionalChain([consent, 'optionalAccess', _18 => _18.errorMessage]), () => ( "Please agree to continue.")));
|
|
551
693
|
return submitValid(event);
|
|
552
694
|
};
|
|
553
695
|
const fieldError = (name) => {
|
|
554
|
-
const err = _optionalChain([errors, 'access',
|
|
555
|
-
return _optionalChain([err, 'optionalAccess',
|
|
696
|
+
const err = _optionalChain([errors, 'access', _19 => _19.formFields, 'optionalAccess', _20 => _20[name]]);
|
|
697
|
+
return _optionalChain([err, 'optionalAccess', _21 => _21.message]);
|
|
556
698
|
};
|
|
557
699
|
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]({
|
|
558
700
|
field,
|
|
@@ -565,7 +707,7 @@ function BookingForm({
|
|
|
565
707
|
const builtInFields = Object.fromEntries(
|
|
566
708
|
BUILT_IN_BOOKING_FIELDS.map((field) => [
|
|
567
709
|
field.name,
|
|
568
|
-
renderField(field, { id: builtInId(field.name), registerName: field.name, error: _optionalChain([errors, 'access',
|
|
710
|
+
renderField(field, { id: builtInId(field.name), registerName: field.name, error: _optionalChain([errors, 'access', _22 => _22[field.name], 'optionalAccess', _23 => _23.message]) })
|
|
569
711
|
])
|
|
570
712
|
);
|
|
571
713
|
const renderDeclaredField = (field) => renderField(field, {
|
|
@@ -626,7 +768,7 @@ function BookingForm({
|
|
|
626
768
|
// box doesn't shove the submit button down the card. With no error the
|
|
627
769
|
// wrapper is `display:contents` and the panel below is the flex item,
|
|
628
770
|
// exactly as it was.
|
|
629
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkQVSVRG7Icjs.FieldWrapper, { error: _optionalChain([errors, 'access',
|
|
771
|
+
/* @__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: [
|
|
630
772
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-ods-text-secondary text-h6", children: legalConsent.processingConsentText }),
|
|
631
773
|
legalConsent.communicationConsentText && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-ods-text-secondary text-h6", children: legalConsent.communicationConsentText }),
|
|
632
774
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
@@ -645,7 +787,7 @@ function BookingForm({
|
|
|
645
787
|
_chunk6FD7ZEBYcjs.CheckboxBlock,
|
|
646
788
|
{
|
|
647
789
|
id: `ms-consent-${box.communicationTypeId}`,
|
|
648
|
-
checked: _nullishCoalesce(_optionalChain([current, 'optionalAccess',
|
|
790
|
+
checked: _nullishCoalesce(_optionalChain([current, 'optionalAccess', _26 => _26.consented]), () => ( false)),
|
|
649
791
|
onCheckedChange: (v) => rhf.onChange(
|
|
650
792
|
responses.map(
|
|
651
793
|
(r) => r.communicationTypeId === box.communicationTypeId ? { ...r, consented: v } : r
|
|
@@ -740,7 +882,7 @@ function zoneLabel(tz) {
|
|
|
740
882
|
timeZone: tz,
|
|
741
883
|
timeZoneName: "shortOffset"
|
|
742
884
|
}).formatToParts(/* @__PURE__ */ new Date());
|
|
743
|
-
const offset = _nullishCoalesce(_optionalChain([parts, 'access',
|
|
885
|
+
const offset = _nullishCoalesce(_optionalChain([parts, 'access', _27 => _27.find, 'call', _28 => _28((p) => p.type === "timeZoneName"), 'optionalAccess', _29 => _29.value]), () => ( ""));
|
|
744
886
|
return offset ? `${tz.replace(/_/g, " ")} (${offset})` : tz.replace(/_/g, " ");
|
|
745
887
|
} catch (e4) {
|
|
746
888
|
return tz.replace(/_/g, " ");
|
|
@@ -867,7 +1009,7 @@ function SchedulerContextPanel({
|
|
|
867
1009
|
value: timezone,
|
|
868
1010
|
disabled,
|
|
869
1011
|
onChange: (tz) => {
|
|
870
|
-
if (tz) _optionalChain([onTimezoneChange, 'optionalCall',
|
|
1012
|
+
if (tz) _optionalChain([onTimezoneChange, 'optionalCall', _30 => _30(tz)]);
|
|
871
1013
|
},
|
|
872
1014
|
options: zoneOptions,
|
|
873
1015
|
placeholder: "Search timezone\u2026",
|
|
@@ -951,7 +1093,7 @@ function DayCalendar({ monthOffset, onMonthOffsetChange, selectedDay, onSelectDa
|
|
|
951
1093
|
const startMonth = new Date(now.getFullYear(), now.getMonth(), 1);
|
|
952
1094
|
const endMonth = new Date(now.getFullYear(), now.getMonth() + _chunk6FD7ZEBYcjs.MAX_MONTH_OFFSET + 1, 0);
|
|
953
1095
|
const visibleMonth = new Date(now.getFullYear(), now.getMonth() + monthOffset, 1);
|
|
954
|
-
const dayHasNoSlots = _react.useCallback.call(void 0, (day) => !_optionalChain([slotsByDay, 'optionalAccess',
|
|
1096
|
+
const dayHasNoSlots = _react.useCallback.call(void 0, (day) => !_optionalChain([slotsByDay, 'optionalAccess', _31 => _31.has, 'call', _32 => _32(calendarDayKey(day))]), [slotsByDay]);
|
|
955
1097
|
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,
|
|
956
1098
|
_chunk6FD7ZEBYcjs.DatePickerCalendar,
|
|
957
1099
|
{
|
|
@@ -969,7 +1111,7 @@ function DayCalendar({ monthOffset, onMonthOffsetChange, selectedDay, onSelectDa
|
|
|
969
1111
|
const day = value;
|
|
970
1112
|
if (!day) return;
|
|
971
1113
|
const key = calendarDayKey(day);
|
|
972
|
-
if (_optionalChain([slotsByDay, 'optionalAccess',
|
|
1114
|
+
if (_optionalChain([slotsByDay, 'optionalAccess', _33 => _33.has, 'call', _34 => _34(key)])) onSelectDay(key);
|
|
973
1115
|
},
|
|
974
1116
|
disabledDays: slotsByDay === null ? DISABLE_EVERY_DAY : dayHasNoSlots
|
|
975
1117
|
}
|
|
@@ -1193,7 +1335,7 @@ function MeetingSchedulerDirectory({
|
|
|
1193
1335
|
};
|
|
1194
1336
|
}, [initialData, includeAll, apiBaseUrl]);
|
|
1195
1337
|
const rows = _react.useMemo.call(void 0, () => {
|
|
1196
|
-
const purposes = _nullishCoalesce(_optionalChain([data, 'optionalAccess',
|
|
1338
|
+
const purposes = _nullishCoalesce(_optionalChain([data, 'optionalAccess', _35 => _35.purposes]), () => ( []));
|
|
1197
1339
|
return purposes.flatMap((p) => p.links.map((link) => ({ link, audienceLabel: p.label })));
|
|
1198
1340
|
}, [data]);
|
|
1199
1341
|
const totalPages = _chunkVTYP25OWcjs.pageCount.call(void 0, rows.length, pageSize);
|
|
@@ -1293,7 +1435,7 @@ function SchedulerDegradedCard({
|
|
|
1293
1435
|
] });
|
|
1294
1436
|
}
|
|
1295
1437
|
function isNativelyBookable(availability) {
|
|
1296
|
-
if (
|
|
1438
|
+
if (availability.formFields.some(blocksNativeBooking)) return false;
|
|
1297
1439
|
const consent = availability.legalConsent;
|
|
1298
1440
|
if (consent) {
|
|
1299
1441
|
if (typeof consent.processingConsentText !== "string") return false;
|
|
@@ -1349,7 +1491,7 @@ function HubSpotMeetingScheduler({
|
|
|
1349
1491
|
onStageChangeRef.current = onStageChange;
|
|
1350
1492
|
});
|
|
1351
1493
|
_react.useEffect.call(void 0, () => {
|
|
1352
|
-
_optionalChain([onStageChangeRef, 'access',
|
|
1494
|
+
_optionalChain([onStageChangeRef, 'access', _36 => _36.current, 'optionalCall', _37 => _37(stage)]);
|
|
1353
1495
|
}, [stage]);
|
|
1354
1496
|
const [stash, setStash] = _react.useState.call(void 0, null);
|
|
1355
1497
|
const inFlightRef = _react.useRef.call(void 0, false);
|
|
@@ -1380,8 +1522,8 @@ function HubSpotMeetingScheduler({
|
|
|
1380
1522
|
_react.useEffect.call(void 0, () => {
|
|
1381
1523
|
autoAdvanceCount.current = 0;
|
|
1382
1524
|
}, [meetingId]);
|
|
1383
|
-
const durations = _react.useMemo.call(void 0, () => _nullishCoalesce(_optionalChain([availability, 'optionalAccess',
|
|
1384
|
-
const shownHosts = _nullishCoalesce(_nullishCoalesce(hosts, () => ( _optionalChain([availability, 'optionalAccess',
|
|
1525
|
+
const durations = _react.useMemo.call(void 0, () => _nullishCoalesce(_optionalChain([availability, 'optionalAccess', _38 => _38.durationsMs]), () => ( [])), [_optionalChain([availability, 'optionalAccess', _39 => _39.durationsMs])]);
|
|
1526
|
+
const shownHosts = _nullishCoalesce(_nullishCoalesce(hosts, () => ( _optionalChain([availability, 'optionalAccess', _40 => _40.hosts]))), () => ( []));
|
|
1385
1527
|
const durationMs = _nullishCoalesce(_nullishCoalesce(pickedDurationMs, () => ( durations[0])), () => ( null));
|
|
1386
1528
|
const slots = _react.useMemo.call(void 0, () => {
|
|
1387
1529
|
if (!availability || durationMs == null) return [];
|
|
@@ -1440,7 +1582,7 @@ function HubSpotMeetingScheduler({
|
|
|
1440
1582
|
if (result.ok && result.confirmation) {
|
|
1441
1583
|
setConfirmation(result.confirmation);
|
|
1442
1584
|
setStep("confirmed");
|
|
1443
|
-
_optionalChain([onBooked, 'optionalCall',
|
|
1585
|
+
_optionalChain([onBooked, 'optionalCall', _41 => _41(result.confirmation)]);
|
|
1444
1586
|
return;
|
|
1445
1587
|
}
|
|
1446
1588
|
const code = _nullishCoalesce(result.code, () => ( "TEMPORARILY_UNAVAILABLE"));
|
|
@@ -1488,8 +1630,8 @@ function HubSpotMeetingScheduler({
|
|
|
1488
1630
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: stepPanelClass, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1489
1631
|
BookingFormSkeleton,
|
|
1490
1632
|
{
|
|
1491
|
-
fieldRows: _optionalChain([detailsFormProps, 'optionalAccess',
|
|
1492
|
-
consent: Boolean(_optionalChain([detailsFormProps, 'optionalAccess',
|
|
1633
|
+
fieldRows: _optionalChain([detailsFormProps, 'optionalAccess', _42 => _42.fieldRows]),
|
|
1634
|
+
consent: Boolean(_optionalChain([detailsFormProps, 'optionalAccess', _43 => _43.consent])),
|
|
1493
1635
|
footerNote: preset.footerNote
|
|
1494
1636
|
}
|
|
1495
1637
|
) })
|
|
@@ -1550,7 +1692,7 @@ function HubSpotMeetingScheduler({
|
|
|
1550
1692
|
deferSlot: detailsFirst,
|
|
1551
1693
|
submitLabel: preset.submitLabel,
|
|
1552
1694
|
footerNote: preset.footerNote,
|
|
1553
|
-
initialValues: detailsFirst ? _optionalChain([stash, 'optionalAccess',
|
|
1695
|
+
initialValues: detailsFirst ? _optionalChain([stash, 'optionalAccess', _44 => _44.payload]) : void 0,
|
|
1554
1696
|
isSubmitting,
|
|
1555
1697
|
onSubmit: detailsFirst ? stashDetails : handleSubmit,
|
|
1556
1698
|
honeypotInputProps,
|