@flamingo-stack/openframe-frontend-core 0.0.596-2034.5677.1 → 0.0.596-2034.5678.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 +0 -14
- package/dist/components/meeting-scheduler/booking-form.d.ts.map +1 -1
- package/dist/components/meeting-scheduler/index.cjs +156 -152
- package/dist/components/meeting-scheduler/index.cjs.map +1 -1
- package/dist/components/meeting-scheduler/index.js +145 -141
- package/dist/components/meeting-scheduler/index.js.map +1 -1
- package/dist/schemas/meeting-booking-schema.cjs +63 -29
- package/dist/schemas/meeting-booking-schema.cjs.map +1 -1
- package/dist/schemas/meeting-booking-schema.d.ts +83 -9
- package/dist/schemas/meeting-booking-schema.d.ts.map +1 -1
- package/dist/schemas/meeting-booking-schema.js +61 -30
- package/dist/schemas/meeting-booking-schema.js.map +1 -1
- package/package.json +1 -1
- package/src/components/meeting-scheduler/booking-form.tsx +147 -132
- package/src/schemas/meeting-booking-schema.ts +124 -53
|
@@ -28,20 +28,6 @@ export interface BookingFormConsent {
|
|
|
28
28
|
/** Shown under the row when Continue is pressed unticked. */
|
|
29
29
|
errorMessage?: string;
|
|
30
30
|
}
|
|
31
|
-
/**
|
|
32
|
-
* BookingForm — attendee details + the link's declared custom questions +
|
|
33
|
-
* verbatim legal-consent copy. ContactForm's scaffolding (react-hook-form +
|
|
34
|
-
* zodResolver + lib field primitives); a sibling rather than a `<ContactForm>`
|
|
35
|
-
* configuration because of the dynamic HubSpot `formFields`, the per-checkbox
|
|
36
|
-
* consent model, and the first/last-name field model — none expressible via
|
|
37
|
-
* `hideFields`/`extraTopField`.
|
|
38
|
-
*
|
|
39
|
-
* Bot protection is LOAD-BEARING: without the humanity signals in the body,
|
|
40
|
-
* the host's `verifyHuman` degrades to first-party-only BotID (fails open for
|
|
41
|
-
* external embedders). Honeypot + elapsed-ms are merged into the POST at
|
|
42
|
-
* submit; the parent calls `resetSignals()` after a SLOT_TAKEN refetch so a
|
|
43
|
-
* legitimate retry isn't flagged too-fast.
|
|
44
|
-
*/
|
|
45
31
|
export interface BookingFormProps {
|
|
46
32
|
availability: MeetingAvailability;
|
|
47
33
|
meetingId: string;
|
|
@@ -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":"AAIA,OAAO,KAAK,EAAa,SAAS,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAGvD,OAAO,EAKL,KAAK,mBAAmB,EAIzB,MAAM,sCAAsC,CAAC;AAqB9C;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CACtB;AAED,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;AAqJD,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,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,+BAqTlB;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,gCAelC"}
|
|
@@ -93,10 +93,63 @@ var MEETING_BOOKING_ERROR_CODES = [
|
|
|
93
93
|
"TEMPORARILY_UNAVAILABLE",
|
|
94
94
|
"MEETING_UNAVAILABLE"
|
|
95
95
|
];
|
|
96
|
-
var
|
|
96
|
+
var optionValidator = (field) => _zod.z.string().refine((v) => !v || (_nullishCoalesce(field.options, () => ( []))).includes(v), {
|
|
97
|
+
message: `Please choose a valid option for ${field.label}`
|
|
98
|
+
});
|
|
99
|
+
var FORM_FIELD_TYPES = {
|
|
100
|
+
text: {
|
|
101
|
+
kind: "string",
|
|
102
|
+
hasOptions: false,
|
|
103
|
+
validator: (field) => _zod.z.string().max(1e3, { message: `${field.label} is too long` })
|
|
104
|
+
},
|
|
105
|
+
textarea: {
|
|
106
|
+
kind: "string",
|
|
107
|
+
hasOptions: false,
|
|
108
|
+
validator: (field) => _zod.z.string().max(5e3, { message: `${field.label} is too long` })
|
|
109
|
+
},
|
|
110
|
+
number: {
|
|
111
|
+
kind: "string",
|
|
112
|
+
hasOptions: false,
|
|
113
|
+
validator: (field) => _zod.z.string().max(32, { message: `${field.label} is too long` }).regex(/^-?\d+(\.\d+)?$/, { message: `${field.label} must be a number` })
|
|
114
|
+
},
|
|
115
|
+
select: { kind: "string", hasOptions: true, validator: optionValidator },
|
|
116
|
+
radio: { kind: "string", hasOptions: true, validator: optionValidator },
|
|
117
|
+
checkbox: { kind: "boolean", hasOptions: false, validator: () => _zod.z.boolean() }
|
|
118
|
+
};
|
|
119
|
+
var SUPPORTED_FORM_FIELD_TYPES = Object.keys(FORM_FIELD_TYPES);
|
|
120
|
+
var FORM_FIELD_TYPES_WITH_OPTIONS = SUPPORTED_FORM_FIELD_TYPES.filter(
|
|
121
|
+
(type) => FORM_FIELD_TYPES[type].hasOptions
|
|
122
|
+
);
|
|
97
123
|
function isSupportedFormField(field) {
|
|
98
|
-
return
|
|
124
|
+
return Object.prototype.hasOwnProperty.call(FORM_FIELD_TYPES, field.type);
|
|
99
125
|
}
|
|
126
|
+
var BUILT_IN_BOOKING_FIELDS = [
|
|
127
|
+
{
|
|
128
|
+
name: "firstName",
|
|
129
|
+
label: "First Name",
|
|
130
|
+
type: "text",
|
|
131
|
+
required: true,
|
|
132
|
+
autoComplete: "given-name",
|
|
133
|
+
placeholder: "Enter First Name"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
name: "lastName",
|
|
137
|
+
label: "Last Name",
|
|
138
|
+
type: "text",
|
|
139
|
+
required: true,
|
|
140
|
+
autoComplete: "family-name",
|
|
141
|
+
placeholder: "Enter Last Name"
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: "email",
|
|
145
|
+
label: "Email",
|
|
146
|
+
type: "text",
|
|
147
|
+
required: true,
|
|
148
|
+
inputType: "email",
|
|
149
|
+
autoComplete: "email",
|
|
150
|
+
placeholder: "username@mail.com"
|
|
151
|
+
}
|
|
152
|
+
];
|
|
100
153
|
var IANA_TZ_RE = /^(?:UTC|[A-Za-z_]+(?:\/[A-Za-z0-9_+-]+)+)$/;
|
|
101
154
|
function isValidIanaTimezone(tz) {
|
|
102
155
|
if (!IANA_TZ_RE.test(tz)) return false;
|
|
@@ -118,34 +171,12 @@ function buildBookingSchema(formFields, legalConsent, slot) {
|
|
|
118
171
|
const answers = {};
|
|
119
172
|
for (const field of formFields) {
|
|
120
173
|
if (!isSupportedFormField(field)) continue;
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
break;
|
|
126
|
-
case "select":
|
|
127
|
-
case "radio":
|
|
128
|
-
validator = _zod.z.string().refine((v) => !v || (_nullishCoalesce(field.options, () => ( []))).includes(v), {
|
|
129
|
-
message: `Please choose a valid option for ${field.label}`
|
|
130
|
-
});
|
|
131
|
-
break;
|
|
132
|
-
case "textarea":
|
|
133
|
-
validator = _zod.z.string().max(5e3, { message: `${field.label} is too long` });
|
|
134
|
-
break;
|
|
135
|
-
case "number":
|
|
136
|
-
validator = _zod.z.string().max(32, { message: `${field.label} is too long` }).regex(/^-?\d+(\.\d+)?$/, { message: `${field.label} must be a number` });
|
|
137
|
-
break;
|
|
138
|
-
case "text":
|
|
139
|
-
default:
|
|
140
|
-
validator = _zod.z.string().max(1e3, { message: `${field.label} is too long` });
|
|
141
|
-
break;
|
|
142
|
-
}
|
|
143
|
-
if (field.required) {
|
|
144
|
-
validator = field.type === "checkbox" ? _zod.z.literal(true, { message: `${field.label} is required` }) : validator.min(1, { message: `${field.label} is required` });
|
|
145
|
-
} else if (field.type !== "checkbox") {
|
|
146
|
-
validator = validator.optional().or(_zod.z.literal(""));
|
|
174
|
+
const spec = FORM_FIELD_TYPES[field.type];
|
|
175
|
+
let validator = spec.validator(field);
|
|
176
|
+
if (spec.kind === "boolean") {
|
|
177
|
+
validator = field.required ? _zod.z.literal(true, { message: `${field.label} is required` }) : _zod.z.boolean().optional();
|
|
147
178
|
} else {
|
|
148
|
-
validator =
|
|
179
|
+
validator = field.required ? validator.min(1, { message: `${field.label} is required` }) : validator.optional().or(_zod.z.literal(""));
|
|
149
180
|
}
|
|
150
181
|
answers[field.name] = validator;
|
|
151
182
|
}
|
|
@@ -289,6 +320,80 @@ var SPAN_CLASS = {
|
|
|
289
320
|
4: "md:col-span-4"
|
|
290
321
|
};
|
|
291
322
|
var evenSpan = (count) => Math.min(4, Math.max(1, Math.floor(4 / Math.max(1, count))));
|
|
323
|
+
var INPUT_CLASS = "bg-ods-card border-ods-border text-ods-text-primary placeholder-ods-text-secondary px-3 h-11 md:h-12";
|
|
324
|
+
var TEXTAREA_CLASS = "border-ods-border bg-ods-card px-3 text-ods-text-primary placeholder-ods-text-secondary";
|
|
325
|
+
var placeholderFor = (field) => _nullishCoalesce(field.placeholder, () => ( (field.type === "text" ? `Enter ${field.label}` : field.type === "textarea" ? `Enter text${field.required ? "" : " (optional)"}` : void 0)));
|
|
326
|
+
var FIELD_CONTROLS = {
|
|
327
|
+
text: ({ field, id, registerName, register }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
328
|
+
_chunkUKT2FAPZcjs.Input,
|
|
329
|
+
{
|
|
330
|
+
id,
|
|
331
|
+
type: _nullishCoalesce(field.inputType, () => ( "text")),
|
|
332
|
+
required: field.required,
|
|
333
|
+
autoComplete: field.autoComplete,
|
|
334
|
+
placeholder: placeholderFor(field),
|
|
335
|
+
className: INPUT_CLASS,
|
|
336
|
+
...register(registerName)
|
|
337
|
+
}
|
|
338
|
+
),
|
|
339
|
+
textarea: ({ field, id, registerName, register }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
340
|
+
_chunkJFP4Q54Dcjs.Textarea,
|
|
341
|
+
{
|
|
342
|
+
id,
|
|
343
|
+
placeholder: placeholderFor(field),
|
|
344
|
+
className: TEXTAREA_CLASS,
|
|
345
|
+
...register(registerName)
|
|
346
|
+
}
|
|
347
|
+
),
|
|
348
|
+
number: ({ field, id, registerName, register }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
349
|
+
_chunkUKT2FAPZcjs.Input,
|
|
350
|
+
{
|
|
351
|
+
id,
|
|
352
|
+
type: "number",
|
|
353
|
+
inputMode: "numeric",
|
|
354
|
+
step: "any",
|
|
355
|
+
required: field.required,
|
|
356
|
+
className: INPUT_CLASS,
|
|
357
|
+
...register(registerName)
|
|
358
|
+
}
|
|
359
|
+
),
|
|
360
|
+
select: ({ field, id, registerName, control }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
361
|
+
_reacthookform.Controller,
|
|
362
|
+
{
|
|
363
|
+
control,
|
|
364
|
+
name: registerName,
|
|
365
|
+
render: ({ field: rhf }) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkJFP4Q54Dcjs.Select, { value: _nullishCoalesce(rhf.value, () => ( "")), onValueChange: rhf.onChange, children: [
|
|
366
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJFP4Q54Dcjs.SelectTrigger, { id, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJFP4Q54Dcjs.SelectValue, { placeholder: "Select\u2026" }) }),
|
|
367
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJFP4Q54Dcjs.SelectContent, { children: (_nullishCoalesce(field.options, () => ( []))).map((opt) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJFP4Q54Dcjs.SelectItem, { value: opt, children: opt }, opt)) })
|
|
368
|
+
] })
|
|
369
|
+
}
|
|
370
|
+
),
|
|
371
|
+
radio: ({ field, id, registerName, control }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
372
|
+
_reacthookform.Controller,
|
|
373
|
+
{
|
|
374
|
+
control,
|
|
375
|
+
name: registerName,
|
|
376
|
+
render: ({ field: rhf }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJFP4Q54Dcjs.RadioGroup, { value: _nullishCoalesce(rhf.value, () => ( "")), onValueChange: rhf.onChange, children: (_nullishCoalesce(field.options, () => ( []))).map((opt) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-[var(--spacing-system-xs)]", children: [
|
|
377
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJFP4Q54Dcjs.RadioGroupItem, { id: `${id}-${opt}`, value: opt }),
|
|
378
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkCHIHYC7Qcjs.Label, { htmlFor: `${id}-${opt}`, children: opt })
|
|
379
|
+
] }, opt)) })
|
|
380
|
+
}
|
|
381
|
+
),
|
|
382
|
+
checkbox: ({ id, registerName, control }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
383
|
+
_reacthookform.Controller,
|
|
384
|
+
{
|
|
385
|
+
control,
|
|
386
|
+
name: registerName,
|
|
387
|
+
render: ({ field: rhf }) => (
|
|
388
|
+
// The question's Label above already carries the text and binds to
|
|
389
|
+
// this id — a second inline label would double the visible text AND
|
|
390
|
+
// the accessible name.
|
|
391
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex items-center gap-[var(--spacing-system-xs)]", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkUKT2FAPZcjs.Checkbox, { id, checked: Boolean(rhf.value), onCheckedChange: (v) => rhf.onChange(v === true) }) })
|
|
392
|
+
)
|
|
393
|
+
}
|
|
394
|
+
)
|
|
395
|
+
};
|
|
396
|
+
var builtInId = (name) => `ms-${name.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`)}`;
|
|
292
397
|
function BookingForm({
|
|
293
398
|
availability,
|
|
294
399
|
meetingId,
|
|
@@ -373,120 +478,19 @@ function BookingForm({
|
|
|
373
478
|
const err = _optionalChain([errors, 'access', _12 => _12.formFields, 'optionalAccess', _13 => _13[name]]);
|
|
374
479
|
return _optionalChain([err, 'optionalAccess', _14 => _14.message]);
|
|
375
480
|
};
|
|
376
|
-
const inputClass = "bg-ods-card border-ods-border text-ods-text-primary placeholder-ods-text-secondary px-3 h-11 md:h-12";
|
|
377
481
|
const FORM_STACK = "flex flex-col gap-[var(--spacing-system-l)]";
|
|
378
|
-
const
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
required: true,
|
|
385
|
-
autoComplete: "email",
|
|
386
|
-
placeholder: "jane@company.com",
|
|
387
|
-
"aria-invalid": !!errors.email,
|
|
388
|
-
className: inputClass,
|
|
389
|
-
...register("email")
|
|
390
|
-
}
|
|
391
|
-
) }),
|
|
392
|
-
firstName: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkUKT2FAPZcjs.FieldWrapper, { label: "First Name", htmlFor: "ms-first-name", required: true, error: _optionalChain([errors, 'access', _17 => _17.firstName, 'optionalAccess', _18 => _18.message]), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
393
|
-
_chunkUKT2FAPZcjs.Input,
|
|
394
|
-
{
|
|
395
|
-
id: "ms-first-name",
|
|
396
|
-
required: true,
|
|
397
|
-
autoComplete: "given-name",
|
|
398
|
-
placeholder: "Jane",
|
|
399
|
-
"aria-invalid": !!errors.firstName,
|
|
400
|
-
className: inputClass,
|
|
401
|
-
...register("firstName")
|
|
402
|
-
}
|
|
403
|
-
) }),
|
|
404
|
-
lastName: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkUKT2FAPZcjs.FieldWrapper, { label: "Last Name", htmlFor: "ms-last-name", required: true, error: _optionalChain([errors, 'access', _19 => _19.lastName, 'optionalAccess', _20 => _20.message]), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
405
|
-
_chunkUKT2FAPZcjs.Input,
|
|
406
|
-
{
|
|
407
|
-
id: "ms-last-name",
|
|
408
|
-
required: true,
|
|
409
|
-
autoComplete: "family-name",
|
|
410
|
-
placeholder: "Doe",
|
|
411
|
-
"aria-invalid": !!errors.lastName,
|
|
412
|
-
className: inputClass,
|
|
413
|
-
...register("lastName")
|
|
414
|
-
}
|
|
415
|
-
) })
|
|
416
|
-
};
|
|
417
|
-
const renderDeclaredField = (field) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
418
|
-
_chunkUKT2FAPZcjs.FieldWrapper,
|
|
419
|
-
{
|
|
420
|
-
label: field.label,
|
|
421
|
-
htmlFor: `ms-q-${field.name}`,
|
|
422
|
-
required: field.required,
|
|
423
|
-
error: fieldError(field.name),
|
|
424
|
-
children: [
|
|
425
|
-
field.type === "textarea" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
426
|
-
_chunkJFP4Q54Dcjs.Textarea,
|
|
427
|
-
{
|
|
428
|
-
id: `ms-q-${field.name}`,
|
|
429
|
-
className: "border-ods-border bg-ods-card px-3 text-ods-text-primary placeholder-ods-text-secondary",
|
|
430
|
-
...register(`formFields.${field.name}`)
|
|
431
|
-
}
|
|
432
|
-
),
|
|
433
|
-
field.type === "text" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
434
|
-
_chunkUKT2FAPZcjs.Input,
|
|
435
|
-
{
|
|
436
|
-
id: `ms-q-${field.name}`,
|
|
437
|
-
className: "h-11 border-ods-border bg-ods-card px-3 text-ods-text-primary placeholder-ods-text-secondary md:h-12",
|
|
438
|
-
...register(`formFields.${field.name}`)
|
|
439
|
-
}
|
|
440
|
-
),
|
|
441
|
-
field.type === "number" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
442
|
-
_chunkUKT2FAPZcjs.Input,
|
|
443
|
-
{
|
|
444
|
-
id: `ms-q-${field.name}`,
|
|
445
|
-
type: "number",
|
|
446
|
-
inputMode: "numeric",
|
|
447
|
-
step: "any",
|
|
448
|
-
className: "h-11 border-ods-border bg-ods-card px-3 text-ods-text-primary placeholder-ods-text-secondary md:h-12",
|
|
449
|
-
...register(`formFields.${field.name}`)
|
|
450
|
-
}
|
|
451
|
-
),
|
|
452
|
-
(field.type === "select" || field.type === "radio") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
453
|
-
_reacthookform.Controller,
|
|
454
|
-
{
|
|
455
|
-
control,
|
|
456
|
-
name: `formFields.${field.name}`,
|
|
457
|
-
render: ({ field: rhf }) => field.type === "select" ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkJFP4Q54Dcjs.Select, { value: _nullishCoalesce(rhf.value, () => ( "")), onValueChange: rhf.onChange, children: [
|
|
458
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJFP4Q54Dcjs.SelectTrigger, { id: `ms-q-${field.name}`, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJFP4Q54Dcjs.SelectValue, { placeholder: "Select\u2026" }) }),
|
|
459
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJFP4Q54Dcjs.SelectContent, { children: (_nullishCoalesce(field.options, () => ( []))).map((opt) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJFP4Q54Dcjs.SelectItem, { value: opt, children: opt }, opt)) })
|
|
460
|
-
] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJFP4Q54Dcjs.RadioGroup, { value: _nullishCoalesce(rhf.value, () => ( "")), onValueChange: rhf.onChange, children: (_nullishCoalesce(field.options, () => ( []))).map((opt) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-[var(--spacing-system-xs)]", children: [
|
|
461
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJFP4Q54Dcjs.RadioGroupItem, { id: `ms-q-${field.name}-${opt}`, value: opt }),
|
|
462
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkCHIHYC7Qcjs.Label, { htmlFor: `ms-q-${field.name}-${opt}`, children: opt })
|
|
463
|
-
] }, opt)) })
|
|
464
|
-
}
|
|
465
|
-
),
|
|
466
|
-
field.type === "checkbox" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
467
|
-
_reacthookform.Controller,
|
|
468
|
-
{
|
|
469
|
-
control,
|
|
470
|
-
name: `formFields.${field.name}`,
|
|
471
|
-
render: ({ field: rhf }) => (
|
|
472
|
-
// The question's Label above already carries the text and
|
|
473
|
-
// binds to this id — a second inline label would double the
|
|
474
|
-
// visible text AND the accessible name.
|
|
475
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex items-center gap-[var(--spacing-system-xs)]", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
476
|
-
_chunkUKT2FAPZcjs.Checkbox,
|
|
477
|
-
{
|
|
478
|
-
id: `ms-q-${field.name}`,
|
|
479
|
-
checked: Boolean(rhf.value),
|
|
480
|
-
onCheckedChange: (v) => rhf.onChange(v === true)
|
|
481
|
-
}
|
|
482
|
-
) })
|
|
483
|
-
)
|
|
484
|
-
}
|
|
485
|
-
)
|
|
486
|
-
]
|
|
487
|
-
},
|
|
488
|
-
field.name
|
|
482
|
+
const renderField = (field, where) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkUKT2FAPZcjs.FieldWrapper, { label: field.label, htmlFor: where.id, required: field.required, error: where.error, children: FIELD_CONTROLS[field.type]({ field, id: where.id, registerName: where.registerName, register, control }) }, field.name);
|
|
483
|
+
const builtInFields = Object.fromEntries(
|
|
484
|
+
BUILT_IN_BOOKING_FIELDS.map((field) => [
|
|
485
|
+
field.name,
|
|
486
|
+
renderField(field, { id: builtInId(field.name), registerName: field.name, error: _optionalChain([errors, 'access', _15 => _15[field.name], 'optionalAccess', _16 => _16.message]) })
|
|
487
|
+
])
|
|
489
488
|
);
|
|
489
|
+
const renderDeclaredField = (field) => renderField(field, {
|
|
490
|
+
id: `ms-q-${field.name}`,
|
|
491
|
+
registerName: `formFields.${field.name}`,
|
|
492
|
+
error: fieldError(field.name)
|
|
493
|
+
});
|
|
490
494
|
const declaredByName = new Map(supportedFields.map((f) => [f.name, f]));
|
|
491
495
|
const slotResolves = (name) => Boolean(builtInFields[name] || declaredByName.has(name));
|
|
492
496
|
const slotNode = (name) => {
|
|
@@ -560,7 +564,7 @@ function BookingForm({
|
|
|
560
564
|
// box doesn't shove the submit button down the card. With no error the
|
|
561
565
|
// wrapper is `display:contents` and the panel below is the flex item,
|
|
562
566
|
// exactly as it was.
|
|
563
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkUKT2FAPZcjs.FieldWrapper, { error: _optionalChain([errors, 'access',
|
|
567
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkUKT2FAPZcjs.FieldWrapper, { error: _optionalChain([errors, 'access', _17 => _17.legalConsentResponses, 'optionalAccess', _18 => _18.message]), children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-[var(--spacing-system-xs)]", children: [
|
|
564
568
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
565
569
|
_reacthookform.Controller,
|
|
566
570
|
{
|
|
@@ -580,7 +584,7 @@ function BookingForm({
|
|
|
580
584
|
_chunkJFP4Q54Dcjs.CheckboxBlock,
|
|
581
585
|
{
|
|
582
586
|
id: `ms-consent-${box.communicationTypeId}`,
|
|
583
|
-
checked: _nullishCoalesce(_optionalChain([current, 'optionalAccess',
|
|
587
|
+
checked: _nullishCoalesce(_optionalChain([current, 'optionalAccess', _19 => _19.consented]), () => ( false)),
|
|
584
588
|
onCheckedChange: (v) => rhf.onChange(
|
|
585
589
|
responses.map(
|
|
586
590
|
(r) => r.communicationTypeId === box.communicationTypeId ? { ...r, consented: v } : r
|
|
@@ -658,7 +662,7 @@ function zoneLabel(tz) {
|
|
|
658
662
|
timeZone: tz,
|
|
659
663
|
timeZoneName: "shortOffset"
|
|
660
664
|
}).formatToParts(/* @__PURE__ */ new Date());
|
|
661
|
-
const offset = _nullishCoalesce(_optionalChain([parts, 'access',
|
|
665
|
+
const offset = _nullishCoalesce(_optionalChain([parts, 'access', _20 => _20.find, 'call', _21 => _21((p) => p.type === "timeZoneName"), 'optionalAccess', _22 => _22.value]), () => ( ""));
|
|
662
666
|
return offset ? `${tz.replace(/_/g, " ")} (${offset})` : tz.replace(/_/g, " ");
|
|
663
667
|
} catch (e4) {
|
|
664
668
|
return tz.replace(/_/g, " ");
|
|
@@ -782,7 +786,7 @@ function SchedulerContextPanel({
|
|
|
782
786
|
{
|
|
783
787
|
value: timezone,
|
|
784
788
|
onChange: (tz) => {
|
|
785
|
-
if (tz) _optionalChain([onTimezoneChange, 'optionalCall',
|
|
789
|
+
if (tz) _optionalChain([onTimezoneChange, 'optionalCall', _23 => _23(tz)]);
|
|
786
790
|
},
|
|
787
791
|
options: zoneOptions,
|
|
788
792
|
placeholder: "Search timezone\u2026",
|
|
@@ -866,7 +870,7 @@ function DayCalendar({ monthOffset, onMonthOffsetChange, selectedDay, onSelectDa
|
|
|
866
870
|
const startMonth = new Date(now.getFullYear(), now.getMonth(), 1);
|
|
867
871
|
const endMonth = new Date(now.getFullYear(), now.getMonth() + _chunkJFP4Q54Dcjs.MAX_MONTH_OFFSET + 1, 0);
|
|
868
872
|
const visibleMonth = new Date(now.getFullYear(), now.getMonth() + monthOffset, 1);
|
|
869
|
-
const dayHasNoSlots = _react.useCallback.call(void 0, (day) => !_optionalChain([slotsByDay, 'optionalAccess',
|
|
873
|
+
const dayHasNoSlots = _react.useCallback.call(void 0, (day) => !_optionalChain([slotsByDay, 'optionalAccess', _24 => _24.has, 'call', _25 => _25(calendarDayKey(day))]), [slotsByDay]);
|
|
870
874
|
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,
|
|
871
875
|
_chunkJFP4Q54Dcjs.DatePickerCalendar,
|
|
872
876
|
{
|
|
@@ -884,7 +888,7 @@ function DayCalendar({ monthOffset, onMonthOffsetChange, selectedDay, onSelectDa
|
|
|
884
888
|
const day = value;
|
|
885
889
|
if (!day) return;
|
|
886
890
|
const key = calendarDayKey(day);
|
|
887
|
-
if (_optionalChain([slotsByDay, 'optionalAccess',
|
|
891
|
+
if (_optionalChain([slotsByDay, 'optionalAccess', _26 => _26.has, 'call', _27 => _27(key)])) onSelectDay(key);
|
|
888
892
|
},
|
|
889
893
|
disabledDays: slotsByDay === null ? DISABLE_EVERY_DAY : dayHasNoSlots
|
|
890
894
|
}
|
|
@@ -1122,7 +1126,7 @@ function MeetingSchedulerDirectory({
|
|
|
1122
1126
|
};
|
|
1123
1127
|
}, [initialData, includeAll, apiBaseUrl]);
|
|
1124
1128
|
const rows = _react.useMemo.call(void 0, () => {
|
|
1125
|
-
const purposes = _nullishCoalesce(_optionalChain([data, 'optionalAccess',
|
|
1129
|
+
const purposes = _nullishCoalesce(_optionalChain([data, 'optionalAccess', _28 => _28.purposes]), () => ( []));
|
|
1126
1130
|
return purposes.flatMap((p) => p.links.map((link) => ({ link, audienceLabel: p.label })));
|
|
1127
1131
|
}, [data]);
|
|
1128
1132
|
const totalPages = _chunkH64ZHSYRcjs.pageCount.call(void 0, rows.length, pageSize);
|
|
@@ -1269,8 +1273,8 @@ function HubSpotMeetingScheduler({
|
|
|
1269
1273
|
_react.useEffect.call(void 0, () => {
|
|
1270
1274
|
autoAdvanceCount.current = 0;
|
|
1271
1275
|
}, [meetingId]);
|
|
1272
|
-
const durations = _react.useMemo.call(void 0, () => _nullishCoalesce(_optionalChain([availability, 'optionalAccess',
|
|
1273
|
-
const shownHosts = _nullishCoalesce(_nullishCoalesce(hosts, () => ( _optionalChain([availability, 'optionalAccess',
|
|
1276
|
+
const durations = _react.useMemo.call(void 0, () => _nullishCoalesce(_optionalChain([availability, 'optionalAccess', _29 => _29.durationsMs]), () => ( [])), [_optionalChain([availability, 'optionalAccess', _30 => _30.durationsMs])]);
|
|
1277
|
+
const shownHosts = _nullishCoalesce(_nullishCoalesce(hosts, () => ( _optionalChain([availability, 'optionalAccess', _31 => _31.hosts]))), () => ( []));
|
|
1274
1278
|
const durationMs = _nullishCoalesce(_nullishCoalesce(pickedDurationMs, () => ( durations[0])), () => ( null));
|
|
1275
1279
|
const slots = _react.useMemo.call(void 0, () => {
|
|
1276
1280
|
if (!availability || durationMs == null) return [];
|
|
@@ -1326,7 +1330,7 @@ function HubSpotMeetingScheduler({
|
|
|
1326
1330
|
if (result.ok && result.confirmation) {
|
|
1327
1331
|
setConfirmation(result.confirmation);
|
|
1328
1332
|
setStep("confirmed");
|
|
1329
|
-
_optionalChain([onBooked, 'optionalCall',
|
|
1333
|
+
_optionalChain([onBooked, 'optionalCall', _32 => _32(result.confirmation)]);
|
|
1330
1334
|
return;
|
|
1331
1335
|
}
|
|
1332
1336
|
const code = _nullishCoalesce(result.code, () => ( "TEMPORARILY_UNAVAILABLE"));
|
|
@@ -1423,7 +1427,7 @@ function HubSpotMeetingScheduler({
|
|
|
1423
1427
|
deferSlot: detailsFirst,
|
|
1424
1428
|
submitLabel: detailsFirst ? "Continue" : void 0,
|
|
1425
1429
|
footerNote: detailsFirst ? "Next step: pick a slot that works. Calendar invite lands right after." : void 0,
|
|
1426
|
-
initialValues: detailsFirst ? _optionalChain([stash, 'optionalAccess',
|
|
1430
|
+
initialValues: detailsFirst ? _optionalChain([stash, 'optionalAccess', _33 => _33.payload]) : void 0,
|
|
1427
1431
|
isSubmitting,
|
|
1428
1432
|
onSubmit: detailsFirst ? stashDetails : handleSubmit,
|
|
1429
1433
|
honeypotInputProps,
|