@flamingo-stack/openframe-frontend-core 0.0.596-2034.5669.1 → 0.0.596-2034.5671.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 +22 -2
- package/dist/components/meeting-scheduler/booking-form.d.ts.map +1 -1
- package/dist/components/meeting-scheduler/context-panel.d.ts +1 -9
- package/dist/components/meeting-scheduler/context-panel.d.ts.map +1 -1
- package/dist/components/meeting-scheduler/index.cjs +47 -26
- package/dist/components/meeting-scheduler/index.cjs.map +1 -1
- package/dist/components/meeting-scheduler/index.d.ts +1 -1
- package/dist/components/meeting-scheduler/index.d.ts.map +1 -1
- package/dist/components/meeting-scheduler/index.js +46 -25
- package/dist/components/meeting-scheduler/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/meeting-scheduler/booking-form.tsx +57 -5
- package/src/components/meeting-scheduler/context-panel.tsx +3 -13
- package/src/components/meeting-scheduler/index.tsx +1 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ComponentType } from 'react';
|
|
2
2
|
import { type BookingConfirmation, type MeetingAvailability, type MeetingBookingErrorCode, type MeetingHost } from '../../schemas/meeting-booking-schema';
|
|
3
3
|
import { type BookingFormProps } from './booking-form';
|
|
4
|
-
export { BookingForm, BookingFormSkeleton, type BookingFormProps, type BookingFieldRow, type BookingFieldSlot, } from './booking-form';
|
|
4
|
+
export { BookingForm, BookingFormSkeleton, type BookingFormProps, type BookingFieldRow, type BookingFieldSlot, type BookingFormConsent, } from './booking-form';
|
|
5
5
|
export interface HubSpotMeetingSchedulerProps {
|
|
6
6
|
/** Directory id of the meeting link (from the host's `/api/meetings` payload). */
|
|
7
7
|
meetingId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/meeting-scheduler/index.tsx"],"names":[],"mappings":"AAsCA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAK3C,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,WAAW,EACjB,MAAM,sCAAsC,CAAC;AAI9C,OAAO,EAAoC,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAKzF,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/meeting-scheduler/index.tsx"],"names":[],"mappings":"AAsCA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAK3C,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,WAAW,EACjB,MAAM,sCAAsC,CAAC;AAI9C,OAAO,EAAoC,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAKzF,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,GACxB,MAAM,gBAAgB,CAAC;AAwBxB,MAAM,WAAW,4BAA4B;IAC3C,kFAAkF;IAClF,SAAS,EAAE,MAAM,CAAC;IAClB,2FAA2F;IAC3F,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,mEAAmE;IACnE,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;IACtB,sFAAsF;IACtF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yFAAyF;IACzF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;OAUG;IACH,IAAI,CAAC,EAAE,YAAY,GAAG,eAAe,CAAC;IACtC;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;CAC/C;AA4CD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,eAAO,MAAM,mBAAmB,qCAAqC,CAAC;AAEtE;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,iCAAiC,qBAAqB,CAAC;AAqEpE,wBAAgB,uBAAuB,CAAC,EACtC,SAAS,EACT,UAAe,EACf,mBAAmB,EACnB,KAAK,EACL,WAAW,EACX,KAAK,EACL,eAAe,EACf,WAAW,EACX,MAAM,EACN,QAAQ,EACR,SAAS,EACT,IAAmB,EACnB,WAAW,EAAE,WAAyB,GACvC,EAAE,4BAA4B,+BA+f9B;AAED,OAAO,EACL,yBAAyB,EACzB,oCAAoC,EACpC,KAAK,8BAA8B,GACpC,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,WAAW,EAAE,CAAC;AAC/F,YAAY,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC"}
|
|
@@ -77,7 +77,7 @@ import "../../chunk-3DTTSBDF.js";
|
|
|
77
77
|
import "../../chunk-DCHYNTHI.js";
|
|
78
78
|
|
|
79
79
|
// src/components/meeting-scheduler/index.tsx
|
|
80
|
-
import { useCallback as useCallback3, useEffect as useEffect3, useMemo as useMemo5, useRef as useRef2, useState as
|
|
80
|
+
import { useCallback as useCallback3, useEffect as useEffect3, useMemo as useMemo5, useRef as useRef2, useState as useState4 } from "react";
|
|
81
81
|
|
|
82
82
|
// src/hooks/use-meeting-booking.ts
|
|
83
83
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
@@ -276,7 +276,7 @@ function useMeetingBooking(options) {
|
|
|
276
276
|
|
|
277
277
|
// src/components/meeting-scheduler/booking-form.tsx
|
|
278
278
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
279
|
-
import { Fragment, useEffect, useMemo } from "react";
|
|
279
|
+
import { Fragment, useEffect, useMemo, useState as useState2 } from "react";
|
|
280
280
|
import { useForm, Controller } from "react-hook-form";
|
|
281
281
|
import { Fragment as Fragment2, jsx, jsxs } from "react/jsx-runtime";
|
|
282
282
|
var SPAN_CLASS = {
|
|
@@ -297,6 +297,7 @@ function BookingForm({
|
|
|
297
297
|
submitLabel,
|
|
298
298
|
footerNote,
|
|
299
299
|
fieldRows,
|
|
300
|
+
consent,
|
|
300
301
|
isSubmitting,
|
|
301
302
|
onSubmit,
|
|
302
303
|
honeypotInputProps,
|
|
@@ -340,6 +341,9 @@ function BookingForm({
|
|
|
340
341
|
}
|
|
341
342
|
});
|
|
342
343
|
const priorConsents = initialValues?.legalConsentResponses;
|
|
344
|
+
const [consented, setConsented] = useState2(initialValues?.hostConsent === true);
|
|
345
|
+
const [consentError, setConsentError] = useState2(null);
|
|
346
|
+
const consentMissing = Boolean(consent) && !consented;
|
|
343
347
|
useEffect(() => {
|
|
344
348
|
setValue(
|
|
345
349
|
"legalConsentResponses",
|
|
@@ -350,13 +354,18 @@ function BookingForm({
|
|
|
350
354
|
{ shouldDirty: false }
|
|
351
355
|
);
|
|
352
356
|
}, [consentDefaults, priorConsents, setValue]);
|
|
353
|
-
const
|
|
357
|
+
const submitValid = handleSubmit(async (data) => {
|
|
358
|
+
if (consentMissing) return;
|
|
354
359
|
if (deferSlot) {
|
|
355
|
-
await onSubmit({ ...data, meetingId });
|
|
360
|
+
await onSubmit({ ...data, meetingId, hostConsent: consented });
|
|
356
361
|
return;
|
|
357
362
|
}
|
|
358
|
-
await onSubmit({ ...data, meetingId, startTimeMs, durationMs, timezone, ...getSignals() });
|
|
363
|
+
await onSubmit({ ...data, meetingId, hostConsent: consented, startTimeMs, durationMs, timezone, ...getSignals() });
|
|
359
364
|
});
|
|
365
|
+
const submit = (event) => {
|
|
366
|
+
if (consentMissing) setConsentError(consent?.errorMessage ?? "Please agree to continue.");
|
|
367
|
+
return submitValid(event);
|
|
368
|
+
};
|
|
360
369
|
const fieldError = (name) => {
|
|
361
370
|
const err = errors.formFields?.[name];
|
|
362
371
|
return err?.message;
|
|
@@ -508,6 +517,21 @@ function BookingForm({
|
|
|
508
517
|
] }),
|
|
509
518
|
supportedFields.map((field) => /* @__PURE__ */ jsx(Fragment, { children: renderDeclaredField(field) }, field.name))
|
|
510
519
|
] }),
|
|
520
|
+
consent && /* @__PURE__ */ jsx(
|
|
521
|
+
CheckboxBlock,
|
|
522
|
+
{
|
|
523
|
+
id: "ms-host-consent",
|
|
524
|
+
checked: consented,
|
|
525
|
+
onCheckedChange: (v) => {
|
|
526
|
+
setConsented(v);
|
|
527
|
+
if (v) setConsentError(null);
|
|
528
|
+
},
|
|
529
|
+
disabled: isSubmitting,
|
|
530
|
+
error: consentError ?? void 0,
|
|
531
|
+
label: consent.label,
|
|
532
|
+
description: consent.description
|
|
533
|
+
}
|
|
534
|
+
),
|
|
511
535
|
legalConsent && // Same out-of-flow message as the fields above, so a missed consent
|
|
512
536
|
// box doesn't shove the submit button down the card. With no error the
|
|
513
537
|
// wrapper is `display:contents` and the panel below is the flex item,
|
|
@@ -653,7 +677,6 @@ function SchedulerContextPanel({
|
|
|
653
677
|
onBack,
|
|
654
678
|
backLabel = "Back",
|
|
655
679
|
locked = false,
|
|
656
|
-
fixedDuration = false,
|
|
657
680
|
showTimezone = true,
|
|
658
681
|
className
|
|
659
682
|
}) {
|
|
@@ -697,9 +720,8 @@ function SchedulerContextPanel({
|
|
|
697
720
|
" hosts on this calendar"
|
|
698
721
|
] })
|
|
699
722
|
] }),
|
|
700
|
-
locked ||
|
|
701
|
-
// Post-selection,
|
|
702
|
-
// length: a static line,
|
|
723
|
+
locked || durationsMs.length <= 1 ? (
|
|
724
|
+
// Post-selection, or a link that offers one length: a static line,
|
|
703
725
|
// which is what sits beside the host on the header-strip layouts.
|
|
704
726
|
selectedDurationMs != null && /* @__PURE__ */ jsxs3("p", { className: "shrink-0 text-ods-text-secondary text-h6", children: [
|
|
705
727
|
formatDurationCompact(selectedDurationMs / 1e3),
|
|
@@ -709,7 +731,7 @@ function SchedulerContextPanel({
|
|
|
709
731
|
] }),
|
|
710
732
|
title && /* @__PURE__ */ jsx3("p", { className: "text-ods-text-primary text-h3", children: title }),
|
|
711
733
|
description && /* @__PURE__ */ jsx3("p", { className: "text-ods-text-secondary text-h6", children: description }),
|
|
712
|
-
!locked &&
|
|
734
|
+
!locked && durationsMs.length > 1 && /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-[var(--spacing-system-xxs)]", children: [
|
|
713
735
|
/* @__PURE__ */ jsx3("p", { className: FIELD_LABEL_CLASS, children: "Duration" }),
|
|
714
736
|
/* @__PURE__ */ jsx3("div", { className: "flex flex-wrap gap-[var(--spacing-system-xs)]", children: durationsMs.map((ms) => /* @__PURE__ */ jsx3(
|
|
715
737
|
Button,
|
|
@@ -968,7 +990,7 @@ function SlotPicker({
|
|
|
968
990
|
|
|
969
991
|
// src/components/meeting-scheduler/directory.tsx
|
|
970
992
|
import { ChevronRight as ChevronRight2 } from "lucide-react";
|
|
971
|
-
import { useEffect as useEffect2, useMemo as useMemo4, useState as
|
|
993
|
+
import { useEffect as useEffect2, useMemo as useMemo4, useState as useState3 } from "react";
|
|
972
994
|
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
973
995
|
function useNextAvailableLabel(ms) {
|
|
974
996
|
const hydrated = useIsHydrated();
|
|
@@ -1045,10 +1067,10 @@ function MeetingSchedulerDirectory({
|
|
|
1045
1067
|
contactHref,
|
|
1046
1068
|
className
|
|
1047
1069
|
}) {
|
|
1048
|
-
const [data, setData] =
|
|
1049
|
-
const [isLoading, setIsLoading] =
|
|
1050
|
-
const [error, setError] =
|
|
1051
|
-
const [page, setPage] =
|
|
1070
|
+
const [data, setData] = useState3(initialData);
|
|
1071
|
+
const [isLoading, setIsLoading] = useState3(initialData === null);
|
|
1072
|
+
const [error, setError] = useState3(null);
|
|
1073
|
+
const [page, setPage] = useState3(1);
|
|
1052
1074
|
useEffect2(() => {
|
|
1053
1075
|
if (initialData !== null) return void 0;
|
|
1054
1076
|
const controller = new AbortController();
|
|
@@ -1188,7 +1210,7 @@ function HubSpotMeetingScheduler({
|
|
|
1188
1210
|
} = useMeetingBooking({ meetingId, apiBaseUrl, initialAvailability });
|
|
1189
1211
|
const detailsFirst = flow === "details-first";
|
|
1190
1212
|
const hydrated = useIsHydrated();
|
|
1191
|
-
const [pickedTimezone, setTimezone] =
|
|
1213
|
+
const [pickedTimezone, setTimezone] = useState4(null);
|
|
1192
1214
|
const resolvedLocalTimezone = useMemo5(() => {
|
|
1193
1215
|
if (!hydrated) return null;
|
|
1194
1216
|
try {
|
|
@@ -1198,18 +1220,18 @@ function HubSpotMeetingScheduler({
|
|
|
1198
1220
|
}
|
|
1199
1221
|
}, [hydrated]);
|
|
1200
1222
|
const timezone = pickedTimezone ?? displayTimezone ?? resolvedLocalTimezone;
|
|
1201
|
-
const [step, setStep] =
|
|
1202
|
-
const [stash, setStash] =
|
|
1223
|
+
const [step, setStep] = useState4(detailsFirst ? "details" : "slot");
|
|
1224
|
+
const [stash, setStash] = useState4(null);
|
|
1203
1225
|
const formOnly = detailsFirst && step === "details";
|
|
1204
|
-
const [pickedDurationMs, setDurationMs] =
|
|
1205
|
-
const [pickedDay, setSelectedDay] =
|
|
1206
|
-
const [selectedSlot, setSelectedSlot] =
|
|
1207
|
-
const [confirmation, setConfirmation] =
|
|
1208
|
-
const [bookingError, setBookingError] =
|
|
1226
|
+
const [pickedDurationMs, setDurationMs] = useState4(null);
|
|
1227
|
+
const [pickedDay, setSelectedDay] = useState4(null);
|
|
1228
|
+
const [selectedSlot, setSelectedSlot] = useState4(null);
|
|
1229
|
+
const [confirmation, setConfirmation] = useState4(null);
|
|
1230
|
+
const [bookingError, setBookingError] = useState4(null);
|
|
1209
1231
|
const { honeypotInputProps, getSignals, resetSignals } = useHumanitySignals();
|
|
1210
1232
|
const { toast } = useToast();
|
|
1211
1233
|
const autoAdvanceCount = useRef2(0);
|
|
1212
|
-
const [machineFor, setMachineFor] =
|
|
1234
|
+
const [machineFor, setMachineFor] = useState4(meetingId);
|
|
1213
1235
|
if (machineFor !== meetingId) {
|
|
1214
1236
|
setMachineFor(meetingId);
|
|
1215
1237
|
setStep(detailsFirst ? "details" : "slot");
|
|
@@ -1343,7 +1365,6 @@ function HubSpotMeetingScheduler({
|
|
|
1343
1365
|
onBack: detailsFirst ? step === "slot" ? backToDetails : onBack : step === "details" ? backToSlot : onBack,
|
|
1344
1366
|
locked: detailsFirst ? step === "confirmed" || isSubmitting : step !== "slot",
|
|
1345
1367
|
showTimezone: step !== "confirmed",
|
|
1346
|
-
fixedDuration: detailsFirst,
|
|
1347
1368
|
className: CONTEXT_PANEL_CLASS
|
|
1348
1369
|
}
|
|
1349
1370
|
),
|