@riverbankcms/sdk 0.139.0 → 0.140.0
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/README.md +1 -1
- package/dist/{PreviewEditorSidebar-BDeenhi3.mjs → PreviewEditorSidebar-CUyTzd5z.mjs} +4 -4
- package/dist/{PreviewEditorUI-DSRhgjF5.mjs → PreviewEditorUI-Agkw4v5i.mjs} +3 -3
- package/dist/{PreviewQueryProvider-D2K8GLUG.mjs → PreviewQueryProvider-CN0ewic5.mjs} +1 -1
- package/dist/{SdkPreviewModeRuntime-CL7wSnYu.mjs → SdkPreviewModeRuntime-DdbeAdS8.mjs} +22 -8
- package/dist/{SiteChromeCustomizeContext-BhDn-5ir.mjs → SiteChromeCustomizeContext-CqGOz-Kv.mjs} +2053 -1110
- package/dist/_dts/ai/src/contracts/proposals.d.ts +165 -165
- package/dist/_dts/ai/src/contracts/siteStyleProposalSchemas.d.ts +212 -212
- package/dist/_dts/api/src/accessAdmin.d.ts +74 -104
- package/dist/_dts/api/src/aiEndpoints.d.ts +5 -1
- package/dist/_dts/api/src/authSubmission.d.ts +46 -0
- package/dist/_dts/api/src/billing.d.ts +8 -4
- package/dist/_dts/api/src/billingEndpointDefinitions.d.ts +23 -0
- package/dist/_dts/api/src/billingEndpointTypes.d.ts +26 -0
- package/dist/_dts/api/src/blocks.d.ts +2 -0
- package/dist/_dts/api/src/bookingRecords.d.ts +1 -2
- package/dist/_dts/api/src/commercePortalEndpoints.d.ts +8 -1
- package/dist/_dts/api/src/communications.d.ts +0 -1
- package/dist/_dts/api/src/contentRuntime.d.ts +8 -3
- package/dist/_dts/api/src/endpoints.d.ts +93 -64
- package/dist/_dts/api/src/event-destination-policy.d.ts +2 -1
- package/dist/_dts/api/src/footerSettings.d.ts +9 -6
- package/dist/_dts/api/src/index.d.ts +5 -6
- package/dist/_dts/api/src/indexCoreTypes.d.ts +1 -1
- package/dist/_dts/api/src/indexExtendedTypes.d.ts +1 -1
- package/dist/_dts/api/src/mailingListIntegration.d.ts +8 -2
- package/dist/_dts/api/src/navigation/dashboardSettingsNav.d.ts +1 -1
- package/dist/_dts/api/src/navigation/types.d.ts +1 -1
- package/dist/_dts/api/src/onboarding/confirmationResend.d.ts +25 -0
- package/dist/_dts/api/src/onboarding/surfaceData.d.ts +32 -32
- package/dist/_dts/api/src/publicBookingAvailabilityEndpointDefinitions.d.ts +8 -0
- package/dist/_dts/api/src/publicExperience/commerceEndpoints.d.ts +1 -0
- package/dist/_dts/api/src/publicExperience/eventEndpoints.d.ts +11 -3
- package/dist/_dts/api/src/publicExperience/sharedTypes.d.ts +3 -29
- package/dist/_dts/api/src/publicOnboardingAttemptEndpointDefinitions.d.ts +65 -0
- package/dist/_dts/api/src/saveOutcome.d.ts +20 -0
- package/dist/_dts/api/src/sdkContracts.d.ts +3 -22
- package/dist/_dts/api/src/sdkPushContracts.d.ts +18 -0
- package/dist/_dts/api/src/sdkThemeWire.d.ts +44 -44
- package/dist/_dts/api/src/settings/permissions.d.ts +12 -0
- package/dist/_dts/api/src/siteManagementEndpoints.d.ts +9 -5
- package/dist/_dts/api/src/siteOnboarding.d.ts +2 -9
- package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +2 -4
- package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +3 -1
- package/dist/_dts/api/src/siteSettings.d.ts +20 -7
- package/dist/_dts/api/src/types.d.ts +77 -77
- package/dist/_dts/api/src/wholeSeriesRuns.d.ts +2 -37
- package/dist/_dts/billing/src/membership/index.d.ts +3 -0
- package/dist/_dts/billing/src/plans/types.d.ts +3 -0
- package/dist/_dts/billing/src/site-arrangements.d.ts +14 -3
- package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +16 -4
- package/dist/_dts/blocks/src/pageRenderAdmission.d.ts +2 -0
- package/dist/_dts/blocks/src/pageRendererContracts.d.ts +5 -0
- package/dist/_dts/blocks/src/portal/types.d.ts +2 -4
- package/dist/_dts/blocks/src/portal/waitlist-types.d.ts +35 -0
- package/dist/_dts/blocks/src/system/blocks/event-registration.d.ts +2 -0
- package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +42 -0
- package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +4 -0
- package/dist/_dts/blocks/src/system/data/index.d.ts +2 -2
- package/dist/_dts/blocks/src/system/data/prefetchBlockData.d.ts +2 -1
- package/dist/_dts/blocks/src/system/data/types.d.ts +9 -0
- package/dist/_dts/blocks/src/system/registry.d.ts +1 -0
- package/dist/_dts/blocks/src/system/runtime/api/client.d.ts +0 -28
- package/dist/_dts/blocks/src/system/runtime/api/index.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/api/types/events.d.ts +7 -3
- package/dist/_dts/blocks/src/system/runtime/api/types/portal.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/api/types/waitlist-claims.d.ts +7 -2
- package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +30 -6
- package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +15 -3
- package/dist/_dts/blocks/src/system/runtime/nodes/appointment-services.d.ts +43 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationSurface.d.ts +1 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/TicketSelectionStep.d.ts +2 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/checkoutRecovery.d.ts +14 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/eventSourceRecovery.d.ts +56 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +6 -8
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useCheckoutRecovery.d.ts +8 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +8 -7
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +10 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventSourceRecovery.d.ts +18 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.client.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +24 -6
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.server.d.ts +4 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.interactive.d.ts +6 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.types.d.ts +1 -0
- package/dist/_dts/blocks/src/system/runtime/resolver.d.ts +1 -0
- package/dist/_dts/blocks/src/system/runtime/shared/components/index.d.ts +2 -6
- package/dist/_dts/blocks/src/system/runtime/shared/index.d.ts +2 -2
- package/dist/_dts/blocks/src/system/runtime/shared/useWaitlistClaim.d.ts +2 -0
- package/dist/_dts/commerce/src/purchase/event-registration-errors.d.ts +4 -0
- package/dist/_dts/commerce/src/purchase/orderItemMetadata.d.ts +27 -4
- package/dist/_dts/content-editor/src/controller/EntryControllerProvider.d.ts +2 -1
- package/dist/_dts/content-editor/src/hooks/useBlockAutosave.d.ts +3 -1
- package/dist/_dts/content-editor/src/useFooterComposerState.d.ts +3 -0
- package/dist/_dts/core/src/branded.d.ts +0 -8
- package/dist/_dts/core/src/index.d.ts +1 -0
- package/dist/_dts/core/src/mailing-list-setup-parser.d.ts +1 -1
- package/dist/_dts/core/src/mailing-list-setup.d.ts +14 -1
- package/dist/_dts/core/src/mailing-list-submission.d.ts +7 -27
- package/dist/_dts/core/src/participants.d.ts +2 -29
- package/dist/_dts/core/src/public-experience.d.ts +4 -0
- package/dist/_dts/core/src/public-profile.d.ts +27 -1
- package/dist/_dts/core/src/site-route-target.d.ts +9 -2
- package/dist/_dts/db/src/generated/supabase/database.types.d.ts +293 -606
- package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/MailingListGlobalSettingsSummary.d.ts +10 -0
- package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/MailingListTargetingField.d.ts +3 -2
- package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/context.d.ts +3 -2
- package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/loaders.d.ts +3 -2
- package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/targetingState.d.ts +19 -0
- package/dist/_dts/sdk/src/public-api/contracts.d.ts +14 -20
- package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +2 -0
- package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +2 -0
- package/dist/_dts/sdk/src/rendering/helpers/pageRuntimeSupport.d.ts +7 -1
- package/dist/_dts/sdk/src/rendering/helpers/templateContent.d.ts +1 -0
- package/dist/_dts/sdk/src/version.d.ts +1 -1
- package/dist/_dts/theme-core/src/accordions/types.d.ts +3 -3
- package/dist/_dts/theme-core/src/cards/types.d.ts +21 -21
- package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
- package/dist/_dts/theme-core/src/header/interactionPalette.d.ts +8 -2
- package/dist/_dts/theme-core/src/header/legacyHeaderVariant.d.ts +2 -2
- package/dist/_dts/theme-core/src/inputs/types.d.ts +2 -2
- package/dist/_dts/theme-core/src/mock-themes/all.d.ts +54 -54
- package/dist/_dts/theme-core/src/runtime/buildThemeRuntimeFromBridge.d.ts +1 -4
- package/dist/_dts/theme-core/src/schema.d.ts +84 -84
- package/dist/_dts/theme-core/src/shared/componentStyles.d.ts +1 -1
- package/dist/_dts/theme-core/src/site-styles/backgroundAppearance.d.ts +2 -2
- package/dist/_dts/theme-core/src/surfaces/foregroundInteraction.d.ts +77 -0
- package/dist/_dts/theme-core/src/surfaces/index.d.ts +1 -0
- package/dist/_dts/theme-core/src/typography/generateTypographyCss.d.ts +2 -2
- package/dist/_dts/ui/src/lib/use-delayed-flag.d.ts +9 -0
- package/dist/_dts/ui/src/pending-button.d.ts +10 -0
- package/dist/client/{BookingConsentAgreement-CZvTDtsK.mjs → BookingConsentAgreement-CuKa82V4.mjs} +4 -4
- package/dist/client/{DiscountCodeDisclosure-D-DsLCMU.mjs → DiscountCodeDisclosure-BbYieKWB.mjs} +1 -1
- package/dist/client/{EventCombined.client-dWqgd5ZO.mjs → EventCombined.client-LTfR1Aby.mjs} +6 -6
- package/dist/client/{EventListing.client-BMRa9IYp.mjs → EventListing.client-DUHpYSuo.mjs} +2 -2
- package/dist/client/{LeafletStaticMap-D21W9kBZ.mjs → LeafletStaticMap-CHRupL6m.mjs} +1 -1
- package/dist/client/{accordion-FxF_ta47.mjs → accordion-6HiIFxNL.mjs} +1 -1
- package/dist/client/{bookingForm-YnwW4TGw.mjs → bookingForm-Dlmid43H.mjs} +7 -7
- package/dist/client/bookings.mjs +325 -140
- package/dist/client/{carousel-vng7fFT5.mjs → carousel-DmkZRRq_.mjs} +2 -2
- package/dist/client/{carousel.client-59G_WMr4.mjs → carousel.client-DQTjCVQT.mjs} +1 -1
- package/dist/client/{cart-DEPDsjNk.mjs → cart-CIC24330.mjs} +3 -3
- package/dist/client/{checkout-CZRWu9rW.mjs → checkout-D1Zw9imo.mjs} +3 -3
- package/dist/client/{checkoutUrls-BuseL0dw.mjs → checkoutUrls-FL6lRkrt.mjs} +1 -1
- package/dist/client/client.mjs +1717 -882
- package/dist/client/{colorStyles-CrxJrPjJ.mjs → colorStyles-3013aRAY.mjs} +3 -1
- package/dist/client/{context-DvU_WUmd.mjs → context-Cy1OayHx.mjs} +6 -19
- package/dist/client/{dates-wnPMiRl5.mjs → dates-aDcfoLHr.mjs} +2 -2
- package/dist/client/{eventCalendar-BA3Q5L15.mjs → eventCalendar-FQxMPAjf.mjs} +8 -8
- package/dist/client/{eventCombined-51wgR-1R.mjs → eventCombined-Dr3ac6Hb.mjs} +3 -3
- package/dist/client/{eventDetails-modaetpm.mjs → eventDetails-D-AzUHFQ.mjs} +4 -4
- package/dist/client/{eventListing-D8t2J3Kv.mjs → eventListing-B3XxBf3i.mjs} +3 -3
- package/dist/client/{eventRegistration-CYqtkCE_.mjs → eventRegistration-I6EaokFD.mjs} +500 -152
- package/dist/client/{form-CBKXN5In.mjs → form-BbWckVWY.mjs} +3 -3
- package/dist/client/{headerSection-DylDqNrs.mjs → headerSection-C9qU4Y7x.mjs} +2 -2
- package/dist/client/hooks.mjs +445 -180
- package/dist/client/{locationMap-CvWrG0vZ.mjs → locationMap-CLCShvlG.mjs} +3 -3
- package/dist/client/{media-BOHuueS5.mjs → media-DHpfFwd3.mjs} +1 -1
- package/dist/client/{newsletterForm-Btwk70zw.mjs → newsletterForm-Briukxzi.mjs} +130 -87
- package/dist/client/{pricing-Uzw-GQ6Y.mjs → pricing-Copadu-2.mjs} +1 -1
- package/dist/client/{productDetail-JLcUYKnd.mjs → productDetail-oujlRd-r.mjs} +3 -3
- package/dist/client/{productList-FM0cbUzj.mjs → productList-BRiIRUcd.mjs} +3 -3
- package/dist/client/{propsDecoder-DYzafZb2.mjs → propsDecoder-CB2KS_ko.mjs} +130 -24
- package/dist/client/rendering/client.mjs +911 -400
- package/dist/client/rendering/islands.mjs +19 -19
- package/dist/client/rendering.mjs +1696 -818
- package/dist/client/{scrollToBlock-CvXszexS.mjs → scrollToBlock-B1IS1_ua.mjs} +1 -1
- package/dist/client/{shop-BIcjvy5a.mjs → shop-Vn6yNFED.mjs} +6 -6
- package/dist/client/{shop-commerce-BZQsy7xw.mjs → shop-commerce-BVTqipYp.mjs} +7 -7
- package/dist/client/{shop-commerce-store-D5V7XAb5.mjs → shop-commerce-store-BVnJVy7v.mjs} +1 -1
- package/dist/client/{shopShared-DowkXevB.mjs → shopShared-COIeK77T.mjs} +4 -4
- package/dist/client/{useEventFilters-oMoTw_JE.mjs → useEventFilters-DzIUcS9n.mjs} +7 -7
- package/dist/preview-next/before-render.mjs +119 -64
- package/dist/preview-next/client/runtime.mjs +4 -4
- package/dist/preview-next/keepAlive.mjs +119 -64
- package/dist/preview-next/middleware.mjs +119 -64
- package/dist/{previewAuthStore-COUyAKaX.mjs → previewAuthStore-Gjb6r6vz.mjs} +119 -64
- package/dist/{sdk-runtime-D4k2LSGF.mjs → sdk-runtime-CnCLvZRv.mjs} +2 -2
- package/dist/{separator-UGtpag4Z.mjs → separator-DKDRJ1oH.mjs} +1 -1
- package/dist/server/components.mjs +787 -323
- package/dist/server/config-validation.mjs +328 -79
- package/dist/server/config.mjs +332 -83
- package/dist/server/data.mjs +441 -180
- package/dist/server/index.mjs +126 -66
- package/dist/server/next.mjs +1031 -595
- package/dist/server/page-converter.mjs +183 -74
- package/dist/server/prebuild.mjs +1 -1
- package/dist/server/rendering/server.mjs +1068 -592
- package/dist/server/rendering.mjs +802 -324
- package/dist/server/routing.mjs +506 -214
- package/dist/server/server.mjs +468 -244
- package/dist/server/theme-bridge.mjs +433 -100
- package/dist/server/theme.mjs +8 -2
- package/dist/styles/index.css +237 -43
- package/package.json +1 -1
- package/dist/_dts/blocks/src/system/runtime/shared/components/BookingOptionCompactRow.d.ts +0 -29
- package/dist/_dts/blocks/src/system/runtime/shared/components/BookingOptionList.d.ts +0 -13
package/dist/{SiteChromeCustomizeContext-BhDn-5ir.mjs → SiteChromeCustomizeContext-CqGOz-Kv.mjs}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { d as unwrapResponse, l as ApiEnvelopeError, s as ApiRequestError, u as extractApiEnvelopeErrorDetails } from "./previewAuthStore-
|
|
2
|
+
import { d as unwrapResponse, l as ApiEnvelopeError, s as ApiRequestError, u as extractApiEnvelopeErrorDetails } from "./previewAuthStore-Gjb6r6vz.mjs";
|
|
3
3
|
import * as React$1 from "react";
|
|
4
4
|
import React, { Component, Fragment, cloneElement, createContext, createElement, createRef, forwardRef, isValidElement, memo, startTransition, useCallback, useContext, useDebugValue, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useReducer, useRef, useState, useSyncExternalStore } from "react";
|
|
5
5
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -82,11 +82,13 @@ const unsafeAsPassId = (id) => id;
|
|
|
82
82
|
const unsafeAsCustomerPassId = (id) => id;
|
|
83
83
|
const unsafeAsAppointmentServiceId = (id) => id;
|
|
84
84
|
const unsafeAsAppointmentResourceId = (id) => id;
|
|
85
|
+
const unsafeAsContentVersionId = (id) => id;
|
|
85
86
|
const parseSiteId = (value) => parseUuidBrand(value, unsafeAsSiteId);
|
|
86
87
|
const parseApiKeyId = (value) => parseUuidBrand(value, unsafeAsApiKeyId);
|
|
87
88
|
const parseEventOfferingId = (value) => parseUuidBrand(value, unsafeAsEventOfferingId);
|
|
88
89
|
const parseUserId = (value) => parseUuidBrand(value, unsafeAsUserId);
|
|
89
90
|
const parseMediaAssetId = (value) => parseUuidBrand(value, unsafeAsMediaAssetId);
|
|
91
|
+
const parseContentVersionId = (value) => parseUuidBrand(value, unsafeAsContentVersionId);
|
|
90
92
|
const parseFormId = (value) => parseUuidBrand(value, unsafeAsFormId);
|
|
91
93
|
const parseEventSeriesId = (value) => parseUuidBrand(value, unsafeAsEventSeriesId);
|
|
92
94
|
//#endregion
|
|
@@ -396,7 +398,7 @@ function parseEventPageSurfaceDestinationMode(value) {
|
|
|
396
398
|
return value === "cms-managed" || value === "system-managed" ? value : void 0;
|
|
397
399
|
}
|
|
398
400
|
function parseEventPageSurfaceSubject(value) {
|
|
399
|
-
if (!isRecord$
|
|
401
|
+
if (!isRecord$29(value)) return err$1({ kind: "notObject" });
|
|
400
402
|
switch (value.kind) {
|
|
401
403
|
case "eventSeries": {
|
|
402
404
|
const eventSeriesId = parseEventSeriesId(value.eventSeriesId);
|
|
@@ -451,7 +453,7 @@ function parseEventSeriesIdList(values) {
|
|
|
451
453
|
}
|
|
452
454
|
return ok$2(parsed);
|
|
453
455
|
}
|
|
454
|
-
function isRecord$
|
|
456
|
+
function isRecord$29(value) {
|
|
455
457
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
456
458
|
}
|
|
457
459
|
//#endregion
|
|
@@ -1101,7 +1103,7 @@ const knownSocialPlatforms = [
|
|
|
1101
1103
|
"x",
|
|
1102
1104
|
"youtube"
|
|
1103
1105
|
];
|
|
1104
|
-
function isRecord$
|
|
1106
|
+
function isRecord$28(value) {
|
|
1105
1107
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1106
1108
|
}
|
|
1107
1109
|
function trimmedOptionalString(value) {
|
|
@@ -1111,7 +1113,7 @@ function trimmedOptionalString(value) {
|
|
|
1111
1113
|
return trimmed.length > 0 ? trimmed : null;
|
|
1112
1114
|
}
|
|
1113
1115
|
function parsePublicContactDetails(value) {
|
|
1114
|
-
if (!isRecord$
|
|
1116
|
+
if (!isRecord$28(value)) return err$1({
|
|
1115
1117
|
code: "invalid_shape",
|
|
1116
1118
|
path: "contact",
|
|
1117
1119
|
message: "Contact details must be an object."
|
|
@@ -1191,7 +1193,7 @@ function minutesSinceMidnight(value) {
|
|
|
1191
1193
|
}
|
|
1192
1194
|
function parseOpeningHoursDay(value, expectedWeekday, index) {
|
|
1193
1195
|
const path = `openingHours.days.${index}`;
|
|
1194
|
-
if (!isRecord$
|
|
1196
|
+
if (!isRecord$28(value) || value.weekday !== expectedWeekday) return err$1({
|
|
1195
1197
|
code: "invalid_weekdays",
|
|
1196
1198
|
path,
|
|
1197
1199
|
message: `Expected ${expectedWeekday} in calendar order.`
|
|
@@ -1208,7 +1210,7 @@ function parseOpeningHoursDay(value, expectedWeekday, index) {
|
|
|
1208
1210
|
const intervals = [];
|
|
1209
1211
|
for (const [intervalIndex, rawInterval] of value.intervals.entries()) {
|
|
1210
1212
|
const intervalPath = `${path}.intervals.${intervalIndex}`;
|
|
1211
|
-
if (!isRecord$
|
|
1213
|
+
if (!isRecord$28(rawInterval)) return err$1({
|
|
1212
1214
|
code: "invalid_interval",
|
|
1213
1215
|
path: intervalPath,
|
|
1214
1216
|
message: "Opening interval is invalid."
|
|
@@ -1250,7 +1252,7 @@ function parseOpeningHoursDay(value, expectedWeekday, index) {
|
|
|
1250
1252
|
});
|
|
1251
1253
|
}
|
|
1252
1254
|
function parseWeeklyOpeningHours(value) {
|
|
1253
|
-
if (!isRecord$
|
|
1255
|
+
if (!isRecord$28(value) || !Array.isArray(value.days) || value.days.length !== publicProfileWeekdays.length) return err$1({
|
|
1254
1256
|
code: "invalid_weekdays",
|
|
1255
1257
|
path: "openingHours.days",
|
|
1256
1258
|
message: "Opening hours must include all seven weekdays."
|
|
@@ -1319,7 +1321,7 @@ function parsePublicSocialLinks(value) {
|
|
|
1319
1321
|
const ids = /* @__PURE__ */ new Set();
|
|
1320
1322
|
for (const [index, rawLink] of value.entries()) {
|
|
1321
1323
|
const path = `socialLinks.${index}`;
|
|
1322
|
-
if (!isRecord$
|
|
1324
|
+
if (!isRecord$28(rawLink)) return err$1({
|
|
1323
1325
|
code: "invalid_social_link",
|
|
1324
1326
|
path,
|
|
1325
1327
|
message: "Social link is invalid."
|
|
@@ -1362,7 +1364,7 @@ function parsePublicSocialLinks(value) {
|
|
|
1362
1364
|
return ok$2(links);
|
|
1363
1365
|
}
|
|
1364
1366
|
function parsePublicProfile(value) {
|
|
1365
|
-
if (!isRecord$
|
|
1367
|
+
if (!isRecord$28(value)) return err$1({
|
|
1366
1368
|
code: "invalid_shape",
|
|
1367
1369
|
path: "",
|
|
1368
1370
|
message: "Public profile must be an object."
|
|
@@ -1375,11 +1377,54 @@ function parsePublicProfile(value) {
|
|
|
1375
1377
|
if (!socialLinks.ok) return socialLinks;
|
|
1376
1378
|
const addressVisibility = parseAddressVisibility(value.addressVisibility);
|
|
1377
1379
|
if (!addressVisibility.ok) return addressVisibility;
|
|
1380
|
+
const contactVisibility = parseContactVisibility(value.contactVisibility);
|
|
1381
|
+
if (!contactVisibility.ok) return contactVisibility;
|
|
1382
|
+
const premises = parsePremises(value.premises);
|
|
1383
|
+
if (!premises.ok) return premises;
|
|
1378
1384
|
return ok$2({
|
|
1379
1385
|
contact: contact.value,
|
|
1386
|
+
contactVisibility: contactVisibility.value,
|
|
1380
1387
|
openingHours: openingHours.value,
|
|
1381
1388
|
socialLinks: socialLinks.value,
|
|
1382
|
-
addressVisibility: addressVisibility.value
|
|
1389
|
+
addressVisibility: addressVisibility.value,
|
|
1390
|
+
premises: premises.value
|
|
1391
|
+
});
|
|
1392
|
+
}
|
|
1393
|
+
function parseFieldVisibility(value, path) {
|
|
1394
|
+
if (value === void 0 || value === null) return ok$2("shown");
|
|
1395
|
+
if (value === "shown" || value === "hidden") return ok$2(value);
|
|
1396
|
+
return err$1({
|
|
1397
|
+
code: "invalid_contact_visibility",
|
|
1398
|
+
path,
|
|
1399
|
+
message: "Contact visibility must be shown or hidden."
|
|
1400
|
+
});
|
|
1401
|
+
}
|
|
1402
|
+
function parseContactVisibility(value) {
|
|
1403
|
+
if (value === void 0 || value === null) return ok$2({
|
|
1404
|
+
phone: "shown",
|
|
1405
|
+
email: "shown"
|
|
1406
|
+
});
|
|
1407
|
+
if (!isRecord$28(value)) return err$1({
|
|
1408
|
+
code: "invalid_contact_visibility",
|
|
1409
|
+
path: "contactVisibility",
|
|
1410
|
+
message: "Contact visibility must be an object."
|
|
1411
|
+
});
|
|
1412
|
+
const phone = parseFieldVisibility(value.phone, "contactVisibility.phone");
|
|
1413
|
+
if (!phone.ok) return phone;
|
|
1414
|
+
const email = parseFieldVisibility(value.email, "contactVisibility.email");
|
|
1415
|
+
if (!email.ok) return email;
|
|
1416
|
+
return ok$2({
|
|
1417
|
+
phone: phone.value,
|
|
1418
|
+
email: email.value
|
|
1419
|
+
});
|
|
1420
|
+
}
|
|
1421
|
+
function parsePremises(value) {
|
|
1422
|
+
if (value === void 0 || value === null) return ok$2(null);
|
|
1423
|
+
if (typeof value === "boolean") return ok$2(value);
|
|
1424
|
+
return err$1({
|
|
1425
|
+
code: "invalid_premises",
|
|
1426
|
+
path: "premises",
|
|
1427
|
+
message: "Premises must be true or false."
|
|
1383
1428
|
});
|
|
1384
1429
|
}
|
|
1385
1430
|
function parseAddressVisibility(value) {
|
|
@@ -1393,7 +1438,7 @@ function parseAddressVisibility(value) {
|
|
|
1393
1438
|
}
|
|
1394
1439
|
//#endregion
|
|
1395
1440
|
//#region ../core/src/rich-text.ts
|
|
1396
|
-
function isRecord$
|
|
1441
|
+
function isRecord$27(value) {
|
|
1397
1442
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1398
1443
|
}
|
|
1399
1444
|
function hasOnlyKeys(value, allowed) {
|
|
@@ -1413,15 +1458,15 @@ function isDenseArrayOf(value, predicate) {
|
|
|
1413
1458
|
return true;
|
|
1414
1459
|
}
|
|
1415
1460
|
function isTipTapMark(value) {
|
|
1416
|
-
return isRecord$
|
|
1461
|
+
return isRecord$27(value) && hasOnlyKeys(value, markKeys) && typeof value.type === "string" && value.type.length > 0 && (value.attrs === void 0 || isRecord$27(value.attrs));
|
|
1417
1462
|
}
|
|
1418
1463
|
function isTipTapNode(value) {
|
|
1419
|
-
if (!isRecord$
|
|
1464
|
+
if (!isRecord$27(value) || !hasOnlyKeys(value, nodeKeys) || typeof value.type !== "string" || value.type.length === 0 || value.type === "doc" || value.attrs !== void 0 && !isRecord$27(value.attrs) || value.marks !== void 0 && (!Array.isArray(value.marks) || !isDenseArrayOf(value.marks, isTipTapMark)) || value.content !== void 0 && (!Array.isArray(value.content) || !isDenseArrayOf(value.content, isTipTapNode))) return false;
|
|
1420
1465
|
if (value.type === "text") return typeof value.text === "string" && value.text.length > 0 && value.content === void 0;
|
|
1421
1466
|
return value.text === void 0;
|
|
1422
1467
|
}
|
|
1423
1468
|
function isCanonicalRichTextDoc(value) {
|
|
1424
|
-
return isRecord$
|
|
1469
|
+
return isRecord$27(value) && hasOnlyKeys(value, rootKeys) && value.type === "doc" && Array.isArray(value.content) && isDenseArrayOf(value.content, isTipTapNode);
|
|
1425
1470
|
}
|
|
1426
1471
|
//#endregion
|
|
1427
1472
|
//#region ../core/src/mailing-list-identifiers.ts
|
|
@@ -1438,22 +1483,28 @@ function parsePositiveInteger$1(value) {
|
|
|
1438
1483
|
function parseNewsletterListId(value) {
|
|
1439
1484
|
return parseTrimmedMatchingString(value, UUID_PATTERN);
|
|
1440
1485
|
}
|
|
1486
|
+
function parseMailchimpAccountId(value) {
|
|
1487
|
+
return parseTrimmedMatchingString(value, OPAQUE_ID_PATTERN);
|
|
1488
|
+
}
|
|
1441
1489
|
function parseMailchimpAudienceId(value) {
|
|
1442
1490
|
return parseTrimmedMatchingString(value, OPAQUE_ID_PATTERN);
|
|
1443
1491
|
}
|
|
1444
1492
|
function parseMailchimpInterestId(value) {
|
|
1445
1493
|
return parseTrimmedMatchingString(value, OPAQUE_ID_PATTERN);
|
|
1446
1494
|
}
|
|
1495
|
+
function parseBrevoAccountId(value) {
|
|
1496
|
+
return parseTrimmedMatchingString(value, OPAQUE_ID_PATTERN);
|
|
1497
|
+
}
|
|
1447
1498
|
function parseBrevoListId(value) {
|
|
1448
1499
|
return parsePositiveInteger$1(value);
|
|
1449
1500
|
}
|
|
1450
1501
|
//#endregion
|
|
1451
1502
|
//#region ../core/src/mailing-list-targeting-parser.ts
|
|
1452
1503
|
function parseMailingListPlacementTargeting(value) {
|
|
1453
|
-
if (!isRecord$
|
|
1504
|
+
if (!isRecord$26(value)) return targetingError("shape");
|
|
1454
1505
|
if (value.mode === "default") return ok$2({ mode: "default" });
|
|
1455
1506
|
if (value.mode !== "custom") return targetingError("mode");
|
|
1456
|
-
if (!isRecord$
|
|
1507
|
+
if (!isRecord$26(value.selection)) return targetingError("selection");
|
|
1457
1508
|
switch (value.provider) {
|
|
1458
1509
|
case "native": return parseNativeTargeting(value.selection);
|
|
1459
1510
|
case "brevo": return parseBrevoTargeting(value.selection);
|
|
@@ -1462,7 +1513,7 @@ function parseMailingListPlacementTargeting(value) {
|
|
|
1462
1513
|
}
|
|
1463
1514
|
}
|
|
1464
1515
|
function parseMailingListVisitorSelection(value) {
|
|
1465
|
-
if (!isRecord$
|
|
1516
|
+
if (!isRecord$26(value)) return visitorSelectionError("shape");
|
|
1466
1517
|
switch (value.provider) {
|
|
1467
1518
|
case "native": {
|
|
1468
1519
|
const topicIds = parseVisitorIds(value.topicIds, parseNewsletterListId);
|
|
@@ -1595,7 +1646,7 @@ function parseVisitorIds(value, parseId) {
|
|
|
1595
1646
|
}
|
|
1596
1647
|
return parsed;
|
|
1597
1648
|
}
|
|
1598
|
-
function isRecord$
|
|
1649
|
+
function isRecord$26(value) {
|
|
1599
1650
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1600
1651
|
}
|
|
1601
1652
|
function targetingError(field) {
|
|
@@ -1612,7 +1663,7 @@ function visitorSelectionError(field) {
|
|
|
1612
1663
|
}
|
|
1613
1664
|
//#endregion
|
|
1614
1665
|
//#region ../core/src/footer-engagement.ts
|
|
1615
|
-
function isRecord$
|
|
1666
|
+
function isRecord$25(value) {
|
|
1616
1667
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1617
1668
|
}
|
|
1618
1669
|
function invalid(path, message) {
|
|
@@ -1638,7 +1689,7 @@ function parseEngagementBase(value, base, path) {
|
|
|
1638
1689
|
if (heading.value === null) return err$1(invalid(`${path}.heading`, "Footer engagement heading cannot be empty."));
|
|
1639
1690
|
const treatment = parseTreatment(value.treatment, `${path}.treatment`);
|
|
1640
1691
|
if (!treatment.ok) return treatment;
|
|
1641
|
-
if (!isRecord$
|
|
1692
|
+
if (!isRecord$25(value.source)) return err$1(invalid(`${path}.source`, "Footer engagement source is invalid."));
|
|
1642
1693
|
const intro = parseBoundedText(value.source.intro, `${path}.source.intro`, {
|
|
1643
1694
|
maxLength: 240,
|
|
1644
1695
|
optional: true
|
|
@@ -1681,7 +1732,7 @@ function parseFooterEngagementSectionValue(value, sectionBase, path) {
|
|
|
1681
1732
|
const base = parseEngagementBase(value, sectionBase, path);
|
|
1682
1733
|
if (!base.ok) return base;
|
|
1683
1734
|
const source = value.source;
|
|
1684
|
-
if (!isRecord$
|
|
1735
|
+
if (!isRecord$25(source)) return err$1(invalid(`${path}.source`, "Footer engagement source is invalid."));
|
|
1685
1736
|
switch (source.kind) {
|
|
1686
1737
|
case "standard-contact": return parseStandardContact(source, base.value, `${path}.source`);
|
|
1687
1738
|
case "mailing-list": return parseMailingList(source, base.value, `${path}.source`);
|
|
@@ -1784,7 +1835,7 @@ function unsafeAsFooterModuleId(value) {
|
|
|
1784
1835
|
function parseFooterModuleId(value) {
|
|
1785
1836
|
return parseSectionId(value, "sectionId");
|
|
1786
1837
|
}
|
|
1787
|
-
function isRecord$
|
|
1838
|
+
function isRecord$24(value) {
|
|
1788
1839
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1789
1840
|
}
|
|
1790
1841
|
function isRichText(value) {
|
|
@@ -1810,7 +1861,7 @@ function parseHeading(value, path) {
|
|
|
1810
1861
|
}
|
|
1811
1862
|
function parseFooterSection(value, index) {
|
|
1812
1863
|
const path = `sections.${index}`;
|
|
1813
|
-
if (!isRecord$
|
|
1864
|
+
if (!isRecord$24(value)) return err$1({
|
|
1814
1865
|
code: "invalid_section",
|
|
1815
1866
|
path,
|
|
1816
1867
|
message: "Footer section must be an object."
|
|
@@ -1839,7 +1890,7 @@ function parseFooterSection(value, index) {
|
|
|
1839
1890
|
});
|
|
1840
1891
|
break;
|
|
1841
1892
|
case "navigation":
|
|
1842
|
-
if (isRecord$
|
|
1893
|
+
if (isRecord$24(value.source) && value.source.kind === "menu-role" && value.source.role === "main") return ok$2({
|
|
1843
1894
|
...base,
|
|
1844
1895
|
kind: "navigation",
|
|
1845
1896
|
heading: heading.value,
|
|
@@ -1850,7 +1901,7 @@ function parseFooterSection(value, index) {
|
|
|
1850
1901
|
});
|
|
1851
1902
|
break;
|
|
1852
1903
|
case "legal-navigation":
|
|
1853
|
-
if (isRecord$
|
|
1904
|
+
if (isRecord$24(value.source) && value.source.kind === "menu-role" && value.source.role === "legal-policy") return ok$2({
|
|
1854
1905
|
...base,
|
|
1855
1906
|
kind: "legal-navigation",
|
|
1856
1907
|
heading: heading.value,
|
|
@@ -1861,7 +1912,7 @@ function parseFooterSection(value, index) {
|
|
|
1861
1912
|
});
|
|
1862
1913
|
break;
|
|
1863
1914
|
case "business-address":
|
|
1864
|
-
if (isRecord$
|
|
1915
|
+
if (isRecord$24(value.source) && value.source.kind === "business-address") return ok$2({
|
|
1865
1916
|
...base,
|
|
1866
1917
|
kind: "business-address",
|
|
1867
1918
|
heading: heading.value,
|
|
@@ -1871,7 +1922,7 @@ function parseFooterSection(value, index) {
|
|
|
1871
1922
|
case "contact":
|
|
1872
1923
|
case "opening-hours":
|
|
1873
1924
|
case "social-links":
|
|
1874
|
-
if (isRecord$
|
|
1925
|
+
if (isRecord$24(value.source) && value.source.kind === "public-profile") return ok$2({
|
|
1875
1926
|
...base,
|
|
1876
1927
|
kind: value.kind,
|
|
1877
1928
|
heading: heading.value,
|
|
@@ -2091,7 +2142,7 @@ const defaultSections = (legacy, options) => {
|
|
|
2091
2142
|
];
|
|
2092
2143
|
};
|
|
2093
2144
|
function normalizeLegacyFooterContentToV1(value, options = {}) {
|
|
2094
|
-
if (!isRecord$
|
|
2145
|
+
if (!isRecord$24(value)) return err$1({
|
|
2095
2146
|
code: "invalid_shape",
|
|
2096
2147
|
path: "",
|
|
2097
2148
|
message: "Legacy footer content must be an object."
|
|
@@ -2108,6 +2159,39 @@ function normalizeFooterNavigationLayout(value) {
|
|
|
2108
2159
|
return value === "stack" ? "stack" : defaultFooterNavigationLayout;
|
|
2109
2160
|
}
|
|
2110
2161
|
//#endregion
|
|
2162
|
+
//#region ../core/src/mailing-list-setup.ts
|
|
2163
|
+
function isRecord$23(value) {
|
|
2164
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2165
|
+
}
|
|
2166
|
+
/** The name shown to people for each provider; the native one is the product brand. */
|
|
2167
|
+
function mailingListProviderName(provider) {
|
|
2168
|
+
switch (provider) {
|
|
2169
|
+
case "native": return "Macadamia";
|
|
2170
|
+
case "mailchimp": return "Mailchimp";
|
|
2171
|
+
case "brevo": return "Brevo";
|
|
2172
|
+
}
|
|
2173
|
+
}
|
|
2174
|
+
const DEFAULT_MAILING_LIST_SUCCESS_MESSAGE = "Thanks — you're on the list.";
|
|
2175
|
+
function parseMailingListProviderScope(value) {
|
|
2176
|
+
if (!isRecord$23(value)) return err$1("invalid_mailing_list_provider_scope");
|
|
2177
|
+
if (value.provider === "native") return ok$2({ provider: "native" });
|
|
2178
|
+
if (value.provider === "brevo") {
|
|
2179
|
+
const accountId = parseBrevoAccountId(value.accountId);
|
|
2180
|
+
return accountId !== null ? ok$2({
|
|
2181
|
+
provider: "brevo",
|
|
2182
|
+
accountId
|
|
2183
|
+
}) : err$1("invalid_mailing_list_provider_scope");
|
|
2184
|
+
}
|
|
2185
|
+
if (value.provider === "mailchimp") {
|
|
2186
|
+
const accountId = parseMailchimpAccountId(value.accountId);
|
|
2187
|
+
return accountId !== null ? ok$2({
|
|
2188
|
+
provider: "mailchimp",
|
|
2189
|
+
accountId
|
|
2190
|
+
}) : err$1("invalid_mailing_list_provider_scope");
|
|
2191
|
+
}
|
|
2192
|
+
return err$1("invalid_mailing_list_provider_scope");
|
|
2193
|
+
}
|
|
2194
|
+
//#endregion
|
|
2111
2195
|
//#region ../core/src/mailing-list-setup-parser.ts
|
|
2112
2196
|
function parseMailingListGlobalForm(value) {
|
|
2113
2197
|
if (!isRecord$22(value)) return formError("shape");
|
|
@@ -2116,12 +2200,15 @@ function parseMailingListGlobalForm(value) {
|
|
|
2116
2200
|
if (typeof value.includeOptionalPhone !== "boolean") return formError("includeOptionalPhone");
|
|
2117
2201
|
const buttonLabel = parseRequiredString(value.buttonLabel);
|
|
2118
2202
|
if (buttonLabel === null) return formError("buttonLabel");
|
|
2203
|
+
const successMessage = parseRequiredString(value.successMessage);
|
|
2204
|
+
if (successMessage === null) return formError("successMessage");
|
|
2119
2205
|
const privacyNote = parseOptionalString(value.privacyNote);
|
|
2120
2206
|
if (privacyNote === void 0) return formError("privacyNote");
|
|
2121
2207
|
return ok$2({
|
|
2122
2208
|
fields,
|
|
2123
2209
|
includeOptionalPhone: value.includeOptionalPhone,
|
|
2124
2210
|
buttonLabel,
|
|
2211
|
+
successMessage,
|
|
2125
2212
|
privacyNote
|
|
2126
2213
|
});
|
|
2127
2214
|
}
|
|
@@ -2351,11 +2438,17 @@ function parseMailingListSignedSourceToken(value) {
|
|
|
2351
2438
|
const parsed = typeof value === "string" ? value.trim() : "";
|
|
2352
2439
|
return /^[A-Za-z0-9._~-]{16,1000}$/u.test(parsed) ? parsed : null;
|
|
2353
2440
|
}
|
|
2354
|
-
function
|
|
2355
|
-
const parsed =
|
|
2356
|
-
return parsed
|
|
2441
|
+
function parseMailingListContentVersionId(value) {
|
|
2442
|
+
const parsed = parseContentVersionId(value);
|
|
2443
|
+
return parsed.ok ? parsed.value : null;
|
|
2444
|
+
}
|
|
2445
|
+
function buildMailingListSignupBlockSourceRef(blockId, contentVersionId) {
|
|
2446
|
+
const parsedBlockId = parseMailingListBlockId(blockId);
|
|
2447
|
+
const parsedContentVersionId = parseMailingListContentVersionId(contentVersionId);
|
|
2448
|
+
return parsedBlockId !== null && parsedContentVersionId !== null ? {
|
|
2357
2449
|
tag: "block_ref",
|
|
2358
|
-
blockId:
|
|
2450
|
+
blockId: parsedBlockId,
|
|
2451
|
+
contentVersionId: parsedContentVersionId
|
|
2359
2452
|
} : null;
|
|
2360
2453
|
}
|
|
2361
2454
|
//#endregion
|
|
@@ -72308,7 +72401,7 @@ function labelNav() {
|
|
|
72308
72401
|
}
|
|
72309
72402
|
//#endregion
|
|
72310
72403
|
//#region ../../node_modules/.pnpm/react-day-picker@9.13.0_react@19.2.7/node_modules/react-day-picker/dist/esm/labels/labelNext.js
|
|
72311
|
-
const defaultLabel
|
|
72404
|
+
const defaultLabel = "Go to the Next Month";
|
|
72312
72405
|
/**
|
|
72313
72406
|
* Generates the ARIA label for the "next month" button.
|
|
72314
72407
|
*
|
|
@@ -72320,7 +72413,7 @@ const defaultLabel$1 = "Go to the Next Month";
|
|
|
72320
72413
|
* @see https://daypicker.dev/docs/translation#aria-labels
|
|
72321
72414
|
*/
|
|
72322
72415
|
function labelNext(_month, _options) {
|
|
72323
|
-
return defaultLabel
|
|
72416
|
+
return defaultLabel;
|
|
72324
72417
|
}
|
|
72325
72418
|
//#endregion
|
|
72326
72419
|
//#region ../../node_modules/.pnpm/react-day-picker@9.13.0_react@19.2.7/node_modules/react-day-picker/dist/esm/labels/labelPrevious.js
|
|
@@ -81197,6 +81290,442 @@ function themeButtonClassName(spec) {
|
|
|
81197
81290
|
].filter(Boolean).join(" ");
|
|
81198
81291
|
}
|
|
81199
81292
|
//#endregion
|
|
81293
|
+
//#region ../theme-core/src/tokens/tokens.ts
|
|
81294
|
+
const defaultThemeTokens = {
|
|
81295
|
+
color: {
|
|
81296
|
+
"background/base": "#ffffff",
|
|
81297
|
+
"background/elevated": "#f5f5f5",
|
|
81298
|
+
"surface/base": "#ffffff",
|
|
81299
|
+
"surface/subtle": "#f9f9fb",
|
|
81300
|
+
"surface/inverted": "#111111",
|
|
81301
|
+
"content/primary": "#111111",
|
|
81302
|
+
"content/secondary": "#3f3f46",
|
|
81303
|
+
"accent/primary": "#2563eb",
|
|
81304
|
+
"accent/secondary": "#1d4ed8",
|
|
81305
|
+
"border/base": "#e5e7eb"
|
|
81306
|
+
},
|
|
81307
|
+
typography: {
|
|
81308
|
+
"display/hero": {
|
|
81309
|
+
fontSize: "clamp(48px, 8vw, 96px)",
|
|
81310
|
+
lineHeight: "1.05",
|
|
81311
|
+
fontWeight: "700"
|
|
81312
|
+
},
|
|
81313
|
+
"display/section": {
|
|
81314
|
+
fontSize: "clamp(40px, 6vw, 72px)",
|
|
81315
|
+
lineHeight: "1.1",
|
|
81316
|
+
fontWeight: "700"
|
|
81317
|
+
},
|
|
81318
|
+
"heading/large": {
|
|
81319
|
+
fontSize: "clamp(32px, 4vw, 48px)",
|
|
81320
|
+
lineHeight: "1.2",
|
|
81321
|
+
fontWeight: "600"
|
|
81322
|
+
},
|
|
81323
|
+
"heading/medium": {
|
|
81324
|
+
fontSize: "clamp(24px, 3vw, 32px)",
|
|
81325
|
+
lineHeight: "1.25",
|
|
81326
|
+
fontWeight: "600"
|
|
81327
|
+
},
|
|
81328
|
+
"heading/small": {
|
|
81329
|
+
fontSize: "20px",
|
|
81330
|
+
lineHeight: "1.3",
|
|
81331
|
+
fontWeight: "600"
|
|
81332
|
+
},
|
|
81333
|
+
"body/normal": {
|
|
81334
|
+
fontSize: "16px",
|
|
81335
|
+
lineHeight: "1.6",
|
|
81336
|
+
fontWeight: "400"
|
|
81337
|
+
},
|
|
81338
|
+
"body/small": {
|
|
81339
|
+
fontSize: "14px",
|
|
81340
|
+
lineHeight: "1.5",
|
|
81341
|
+
fontWeight: "400"
|
|
81342
|
+
},
|
|
81343
|
+
caption: {
|
|
81344
|
+
fontSize: "12px",
|
|
81345
|
+
lineHeight: "1.4",
|
|
81346
|
+
fontWeight: "500"
|
|
81347
|
+
}
|
|
81348
|
+
},
|
|
81349
|
+
spacing: {
|
|
81350
|
+
none: "0px",
|
|
81351
|
+
"3xs": "4px",
|
|
81352
|
+
"2xs": "8px",
|
|
81353
|
+
xs: "12px",
|
|
81354
|
+
sm: "16px",
|
|
81355
|
+
md: "24px",
|
|
81356
|
+
lg: "32px",
|
|
81357
|
+
xl: "40px",
|
|
81358
|
+
"2xl": "56px",
|
|
81359
|
+
"3xl": "72px"
|
|
81360
|
+
},
|
|
81361
|
+
radius: {
|
|
81362
|
+
none: "0px",
|
|
81363
|
+
xs: "2px",
|
|
81364
|
+
sm: "4px",
|
|
81365
|
+
md: "8px",
|
|
81366
|
+
lg: "12px",
|
|
81367
|
+
pill: "999px",
|
|
81368
|
+
full: "9999px"
|
|
81369
|
+
},
|
|
81370
|
+
shadow: {
|
|
81371
|
+
none: "none",
|
|
81372
|
+
soft: "0px 2px 8px rgba(15, 23, 42, 0.08)",
|
|
81373
|
+
medium: "0px 6px 18px rgba(15, 23, 42, 0.12)",
|
|
81374
|
+
strong: "0px 12px 36px rgba(15, 23, 42, 0.16)"
|
|
81375
|
+
},
|
|
81376
|
+
palette: {
|
|
81377
|
+
surface: "#ffffff",
|
|
81378
|
+
"neutral-50": "#f9fafb",
|
|
81379
|
+
"neutral-900": "#111827",
|
|
81380
|
+
primary: "#2563eb",
|
|
81381
|
+
"primary-50": "#eff6ff",
|
|
81382
|
+
"primary-500": "#2563eb",
|
|
81383
|
+
"primary-900": "#1d4ed8",
|
|
81384
|
+
secondary: "#9333ea",
|
|
81385
|
+
"secondary-50": "#f3e8ff",
|
|
81386
|
+
"secondary-500": "#9333ea",
|
|
81387
|
+
"secondary-900": "#4c1d95",
|
|
81388
|
+
accent: "#f97316",
|
|
81389
|
+
"accent-50": "#fff7ed",
|
|
81390
|
+
"accent-500": "#f97316",
|
|
81391
|
+
"accent-900": "#7c2d12"
|
|
81392
|
+
}
|
|
81393
|
+
};
|
|
81394
|
+
/**
|
|
81395
|
+
* Project the expanded semantic palette into the token buckets consumed by
|
|
81396
|
+
* runtime transforms. Keep this mapping shared by full themes and the
|
|
81397
|
+
* tokens-only hosted-booking runtime so the two paths cannot drift.
|
|
81398
|
+
*/
|
|
81399
|
+
function buildThemeTokens(palette) {
|
|
81400
|
+
const tokens = cloneThemeTokens(defaultThemeTokens);
|
|
81401
|
+
const paletteStrings = {};
|
|
81402
|
+
for (const [key, value] of Object.entries(palette)) if (typeof value === "string" && value.trim().length > 0) paletteStrings[key] = value;
|
|
81403
|
+
tokens.palette = paletteStrings;
|
|
81404
|
+
const resolveColor = (...keys) => {
|
|
81405
|
+
for (const key of keys) {
|
|
81406
|
+
const value = paletteStrings[key];
|
|
81407
|
+
if (value) return value;
|
|
81408
|
+
}
|
|
81409
|
+
};
|
|
81410
|
+
const assignColor = (token, ...keys) => {
|
|
81411
|
+
const value = resolveColor(...keys);
|
|
81412
|
+
if (value) tokens.color[token] = value;
|
|
81413
|
+
};
|
|
81414
|
+
assignColor("background/base", "background", "surface", "primary-50");
|
|
81415
|
+
assignColor("background/elevated", "surface", "background");
|
|
81416
|
+
assignColor("surface/base", "surface", "background");
|
|
81417
|
+
assignColor("surface/subtle", "neutral-100", "surface", "background");
|
|
81418
|
+
assignColor("surface/inverted", "neutral-900", "text", "primary-900");
|
|
81419
|
+
assignColor("content/primary", "text", "body", "neutral-900");
|
|
81420
|
+
assignColor("content/secondary", "mutedText", "secondary", "neutral-600");
|
|
81421
|
+
assignColor("accent/primary", "primary", "accent");
|
|
81422
|
+
assignColor("accent/secondary", "accent", "secondary", "primary-400");
|
|
81423
|
+
assignColor("border/base", "border", "neutral-300");
|
|
81424
|
+
return tokens;
|
|
81425
|
+
}
|
|
81426
|
+
function cloneThemeTokens(source) {
|
|
81427
|
+
return JSON.parse(JSON.stringify(source));
|
|
81428
|
+
}
|
|
81429
|
+
//#endregion
|
|
81430
|
+
//#region ../theme-core/src/palette/utils/opaqueSurfaceColor.ts
|
|
81431
|
+
/** Resolve an opaque colour, compositing alpha against an explicit underlay. */
|
|
81432
|
+
function resolveOpaqueSurfaceHex(reference, palette, underlayReference) {
|
|
81433
|
+
const opaque = resolveConcreteColorHex(reference, palette);
|
|
81434
|
+
if (opaque) return opaque;
|
|
81435
|
+
if (!underlayReference) return null;
|
|
81436
|
+
const underlayHex = resolveConcreteColorHex(underlayReference, palette);
|
|
81437
|
+
if (!underlayHex) return null;
|
|
81438
|
+
const parts = parseColorTokenParts(reference);
|
|
81439
|
+
if (parts.kind === "token" && parts.opacityPercent !== null) {
|
|
81440
|
+
const foregroundHex = normalizePaletteHex(palette[parts.token] ?? "");
|
|
81441
|
+
return foregroundHex ? compositeHex(foregroundHex, underlayHex, parts.opacityPercent / 100) : null;
|
|
81442
|
+
}
|
|
81443
|
+
const rgba = parseRgba(parts.kind === "raw" ? parts.value : reference);
|
|
81444
|
+
return rgba ? compositeHex(rgbToHex$1(rgba.r, rgba.g, rgba.b), underlayHex, rgba.alpha) : null;
|
|
81445
|
+
}
|
|
81446
|
+
/** Resolve a colour reference only when it is already fully opaque. */
|
|
81447
|
+
function resolveConcreteColorHex(reference, palette) {
|
|
81448
|
+
const literalHex = normalizePaletteHex(reference);
|
|
81449
|
+
if (literalHex) return literalHex;
|
|
81450
|
+
const parts = parseColorTokenParts(reference);
|
|
81451
|
+
if (parts.kind === "token") {
|
|
81452
|
+
if (parts.opacityPercent !== null) return null;
|
|
81453
|
+
return normalizePaletteHex(palette[parts.token] ?? "");
|
|
81454
|
+
}
|
|
81455
|
+
const literal = parts.kind === "raw" ? parts.value : reference;
|
|
81456
|
+
if (literal.toLowerCase() === "black") return "#000000";
|
|
81457
|
+
if (literal.toLowerCase() === "white") return "#ffffff";
|
|
81458
|
+
return normalizePaletteHex(literal);
|
|
81459
|
+
}
|
|
81460
|
+
function compositeHex(foregroundHex, underlayHex, alpha) {
|
|
81461
|
+
const foreground = hexToRgb(foregroundHex);
|
|
81462
|
+
const underlay = hexToRgb(underlayHex);
|
|
81463
|
+
const channel = (foregroundValue, underlayValue) => Math.round(foregroundValue * alpha + underlayValue * (1 - alpha));
|
|
81464
|
+
return rgbToHex$1(channel(foreground.r, underlay.r), channel(foreground.g, underlay.g), channel(foreground.b, underlay.b));
|
|
81465
|
+
}
|
|
81466
|
+
function parseRgba(value) {
|
|
81467
|
+
const match = value.trim().match(/^rgba?\(\s*([\d.]+)(?:\s*,\s*|\s+)([\d.]+)(?:\s*,\s*|\s+)([\d.]+)(?:\s*(?:,|\/)\s*([\d.]+%?))?\s*\)$/i);
|
|
81468
|
+
if (!match) return null;
|
|
81469
|
+
const [, rSource, gSource, bSource] = match;
|
|
81470
|
+
if (!rSource || !gSource || !bSource) return null;
|
|
81471
|
+
const r = Number(rSource);
|
|
81472
|
+
const g = Number(gSource);
|
|
81473
|
+
const b = Number(bSource);
|
|
81474
|
+
const alpha = parseAlpha(match[4]);
|
|
81475
|
+
if (alpha === null || !isRgbChannel(r) || !isRgbChannel(g) || !isRgbChannel(b)) return null;
|
|
81476
|
+
return {
|
|
81477
|
+
r,
|
|
81478
|
+
g,
|
|
81479
|
+
b,
|
|
81480
|
+
alpha
|
|
81481
|
+
};
|
|
81482
|
+
}
|
|
81483
|
+
function parseAlpha(source) {
|
|
81484
|
+
if (!source) return 1;
|
|
81485
|
+
const value = source.endsWith("%") ? Number(source.slice(0, -1)) / 100 : Number(source);
|
|
81486
|
+
return Number.isFinite(value) && value >= 0 && value <= 1 ? value : null;
|
|
81487
|
+
}
|
|
81488
|
+
function isRgbChannel(value) {
|
|
81489
|
+
return Number.isFinite(value) && value >= 0 && value <= 255;
|
|
81490
|
+
}
|
|
81491
|
+
//#endregion
|
|
81492
|
+
//#region ../theme-core/src/surfaces/resolveSurfaceForeground.ts
|
|
81493
|
+
const FALLBACK_TEXT_TOKENS = [
|
|
81494
|
+
"text",
|
|
81495
|
+
"primaryForeground",
|
|
81496
|
+
"secondaryForeground",
|
|
81497
|
+
"accentForeground",
|
|
81498
|
+
"neutral-950",
|
|
81499
|
+
"neutral-50"
|
|
81500
|
+
];
|
|
81501
|
+
const CANONICAL_EQUIVALENT_TOKEN_ORDER = [
|
|
81502
|
+
"text",
|
|
81503
|
+
"primaryForeground",
|
|
81504
|
+
"secondaryForeground",
|
|
81505
|
+
"accentForeground",
|
|
81506
|
+
"onPrimary",
|
|
81507
|
+
"onSecondary",
|
|
81508
|
+
"onAccent",
|
|
81509
|
+
"onSurface",
|
|
81510
|
+
"neutral-950",
|
|
81511
|
+
"neutral-50"
|
|
81512
|
+
];
|
|
81513
|
+
/**
|
|
81514
|
+
* Resolve the complete foreground contract for an effective page/section or
|
|
81515
|
+
* site-chrome background.
|
|
81516
|
+
*
|
|
81517
|
+
* Deterministic colour backgrounds are validated at ordinary-text WCAG AA.
|
|
81518
|
+
* Existing image/video/gradient treatments are trusted only when they already
|
|
81519
|
+
* carry a usable foreground token; this function deliberately does not claim
|
|
81520
|
+
* pixel-level contrast proof for media.
|
|
81521
|
+
*/
|
|
81522
|
+
function resolveSurfaceForeground(background, palette, candidates = {}, options = {}) {
|
|
81523
|
+
const authored = foregroundCandidates(background, candidates);
|
|
81524
|
+
if (background === null) return resolveDeterministicForeground("background", {
|
|
81525
|
+
...authored,
|
|
81526
|
+
text: authored.text ?? "text"
|
|
81527
|
+
}, palette);
|
|
81528
|
+
if (background.type === "color") {
|
|
81529
|
+
const backgroundReference = normalizedReference(background.color);
|
|
81530
|
+
if (!backgroundReference || backgroundReference === "transparent") return { kind: "unknown" };
|
|
81531
|
+
return resolveDeterministicForeground(backgroundReference, authored, palette, options.compositeBase);
|
|
81532
|
+
}
|
|
81533
|
+
return resolveTrustedTreatmentForeground(authored, palette);
|
|
81534
|
+
}
|
|
81535
|
+
function foregroundCandidates(background, overrides) {
|
|
81536
|
+
return {
|
|
81537
|
+
text: overrides.text ?? background?.textColor ?? null,
|
|
81538
|
+
heading: overrides.heading ?? background?.headingColor ?? null,
|
|
81539
|
+
link: overrides.link ?? background?.linkColor ?? null,
|
|
81540
|
+
supporting: overrides.supporting ?? background?.supportingColor ?? null
|
|
81541
|
+
};
|
|
81542
|
+
}
|
|
81543
|
+
function resolveDeterministicForeground(backgroundReference, candidates, palette, compositeBase) {
|
|
81544
|
+
const backgroundHex = resolveOpaqueSurfaceHex(backgroundReference, palette, compositeBase);
|
|
81545
|
+
if (!backgroundHex) return resolveTrustedTreatmentForeground(candidates, palette);
|
|
81546
|
+
const backgroundToken = paletteToken(backgroundReference);
|
|
81547
|
+
const derivedOnToken = backgroundToken ? onColorTokenName(backgroundToken) : null;
|
|
81548
|
+
const text = firstSafeToken([
|
|
81549
|
+
candidates.text,
|
|
81550
|
+
derivedOnToken,
|
|
81551
|
+
...FALLBACK_TEXT_TOKENS
|
|
81552
|
+
], backgroundHex, palette, derivedOnToken ? [derivedOnToken] : []);
|
|
81553
|
+
if (!text) return { kind: "unknown" };
|
|
81554
|
+
return {
|
|
81555
|
+
kind: "known",
|
|
81556
|
+
roles: {
|
|
81557
|
+
text,
|
|
81558
|
+
heading: safeTokenOr(candidates.heading, text, backgroundHex, palette),
|
|
81559
|
+
link: safeTokenOr(candidates.link, text, backgroundHex, palette),
|
|
81560
|
+
supporting: safeTokenOr(candidates.supporting, text, backgroundHex, palette)
|
|
81561
|
+
}
|
|
81562
|
+
};
|
|
81563
|
+
}
|
|
81564
|
+
function resolveTrustedTreatmentForeground(candidates, palette) {
|
|
81565
|
+
const text = canonicalToken(candidates.text, palette);
|
|
81566
|
+
if (!text) return { kind: "unknown" };
|
|
81567
|
+
return {
|
|
81568
|
+
kind: "known",
|
|
81569
|
+
roles: {
|
|
81570
|
+
text,
|
|
81571
|
+
heading: canonicalToken(candidates.heading, palette) ?? text,
|
|
81572
|
+
link: canonicalToken(candidates.link, palette) ?? text,
|
|
81573
|
+
supporting: canonicalToken(candidates.supporting, palette) ?? text
|
|
81574
|
+
}
|
|
81575
|
+
};
|
|
81576
|
+
}
|
|
81577
|
+
function safeTokenOr(candidate, fallback, backgroundHex, palette) {
|
|
81578
|
+
return firstSafeToken([candidate], backgroundHex, palette) ?? fallback;
|
|
81579
|
+
}
|
|
81580
|
+
function firstSafeToken(candidates, backgroundHex, palette, preferredEquivalentTokens = []) {
|
|
81581
|
+
const seen = /* @__PURE__ */ new Set();
|
|
81582
|
+
for (const candidate of candidates) {
|
|
81583
|
+
const token = canonicalToken(candidate, palette, preferredEquivalentTokens);
|
|
81584
|
+
if (!token || seen.has(token)) continue;
|
|
81585
|
+
seen.add(token);
|
|
81586
|
+
const foregroundHex = resolveConcreteColorHex(token, palette);
|
|
81587
|
+
if (foregroundHex && contrastRatio$1(backgroundHex, foregroundHex) >= 4.5) return token;
|
|
81588
|
+
}
|
|
81589
|
+
return null;
|
|
81590
|
+
}
|
|
81591
|
+
function canonicalToken(reference, palette, preferredEquivalentTokens = []) {
|
|
81592
|
+
const normalized = normalizedReference(reference);
|
|
81593
|
+
if (!normalized || normalized === "transparent") return null;
|
|
81594
|
+
const direct = parseThemeColorToken(normalized);
|
|
81595
|
+
if (direct && resolveConcreteColorHex(direct, palette)) return direct;
|
|
81596
|
+
const referenceHex = resolveConcreteColorHex(normalized, palette);
|
|
81597
|
+
if (!referenceHex) return null;
|
|
81598
|
+
const equivalent = [
|
|
81599
|
+
...preferredEquivalentTokens,
|
|
81600
|
+
...CANONICAL_EQUIVALENT_TOKEN_ORDER,
|
|
81601
|
+
...Object.keys(palette).sort()
|
|
81602
|
+
].find((token) => {
|
|
81603
|
+
const parsed = parseThemeColorToken(token);
|
|
81604
|
+
return parsed !== null && resolveConcreteColorHex(parsed, palette)?.toLowerCase() === referenceHex.toLowerCase();
|
|
81605
|
+
});
|
|
81606
|
+
return equivalent ? parseThemeColorToken(equivalent) : null;
|
|
81607
|
+
}
|
|
81608
|
+
function paletteToken(reference) {
|
|
81609
|
+
const parts = parseColorTokenParts(reference);
|
|
81610
|
+
return parts.kind === "token" && parts.opacityPercent === null ? parts.token : null;
|
|
81611
|
+
}
|
|
81612
|
+
function normalizedReference(value) {
|
|
81613
|
+
if (typeof value !== "string") return null;
|
|
81614
|
+
const normalized = value.trim();
|
|
81615
|
+
return normalized.length > 0 ? normalized : null;
|
|
81616
|
+
}
|
|
81617
|
+
//#endregion
|
|
81618
|
+
//#region ../theme-core/src/utils/colorStyles.ts
|
|
81619
|
+
const COLOR_VAR_PREFIX = "--tb-";
|
|
81620
|
+
function parseToken(source) {
|
|
81621
|
+
const parts = parseColorTokenParts(source);
|
|
81622
|
+
if (parts.kind === "raw") return {
|
|
81623
|
+
token: source,
|
|
81624
|
+
raw: parts.value
|
|
81625
|
+
};
|
|
81626
|
+
if (parts.kind === "invalid") return { token: source };
|
|
81627
|
+
return {
|
|
81628
|
+
token: parts.token,
|
|
81629
|
+
opacityPercent: parts.opacityPercent === null ? void 0 : parts.opacityPercent
|
|
81630
|
+
};
|
|
81631
|
+
}
|
|
81632
|
+
const SURFACE_TEXT_ROLE_BY_TOKEN = {
|
|
81633
|
+
text: "text",
|
|
81634
|
+
heading: "heading",
|
|
81635
|
+
mutedText: "supporting"
|
|
81636
|
+
};
|
|
81637
|
+
function surfaceRoleForTextToken(token) {
|
|
81638
|
+
return Object.prototype.hasOwnProperty.call(SURFACE_TEXT_ROLE_BY_TOKEN, token) ? SURFACE_TEXT_ROLE_BY_TOKEN[token] : null;
|
|
81639
|
+
}
|
|
81640
|
+
/**
|
|
81641
|
+
* Converts a theme color token to a CSS rgb value.
|
|
81642
|
+
* This is the primary function for applying theme colors to CSS properties.
|
|
81643
|
+
*
|
|
81644
|
+
* @param token - Theme color token (semantic, with opacity, or raw)
|
|
81645
|
+
* @returns CSS color value (rgb with optional alpha, or raw CSS value)
|
|
81646
|
+
*
|
|
81647
|
+
* @example
|
|
81648
|
+
* rgbColorValue('primary') // => 'rgb(var(--tb-primary))'
|
|
81649
|
+
* rgbColorValue('surface/95') // => 'rgb(var(--tb-surface) / 0.95)'
|
|
81650
|
+
* rgbColorValue('raw:transparent') // => 'transparent'
|
|
81651
|
+
*/
|
|
81652
|
+
function rgbColorValue(token) {
|
|
81653
|
+
const { token: baseToken, opacityPercent, raw } = parseToken(token);
|
|
81654
|
+
if (raw) return raw;
|
|
81655
|
+
const cssVar = `${COLOR_VAR_PREFIX}${baseToken}`;
|
|
81656
|
+
if (opacityPercent === void 0) return `rgb(var(${cssVar}))`;
|
|
81657
|
+
return `rgb(var(${cssVar}) / ${opacityPercent / 100})`;
|
|
81658
|
+
}
|
|
81659
|
+
/**
|
|
81660
|
+
* Converts a theme color token to a CSS variable reference.
|
|
81661
|
+
* Note: This returns the base variable without rgb() wrapper, ignoring opacity.
|
|
81662
|
+
*
|
|
81663
|
+
* @param token - Theme color token
|
|
81664
|
+
* @returns CSS variable reference
|
|
81665
|
+
*
|
|
81666
|
+
* @example
|
|
81667
|
+
* cssVarValue('primary') // => 'var(--tb-primary)'
|
|
81668
|
+
* cssVarValue('surface/95') // => 'var(--tb-surface)' (opacity ignored)
|
|
81669
|
+
*/
|
|
81670
|
+
function cssVarValue(token) {
|
|
81671
|
+
const { token: baseToken } = parseToken(token);
|
|
81672
|
+
return `var(${COLOR_VAR_PREFIX}${baseToken})`;
|
|
81673
|
+
}
|
|
81674
|
+
/**
|
|
81675
|
+
* Creates a backgroundColor style object from a theme token.
|
|
81676
|
+
*
|
|
81677
|
+
* @param token - Theme color token
|
|
81678
|
+
* @returns CSSProperties with backgroundColor
|
|
81679
|
+
*/
|
|
81680
|
+
function backgroundColorStyle(token) {
|
|
81681
|
+
return { backgroundColor: rgbColorValue(token) };
|
|
81682
|
+
}
|
|
81683
|
+
/**
|
|
81684
|
+
* Creates a text color style object from a theme token.
|
|
81685
|
+
*
|
|
81686
|
+
* @param token - Theme color token
|
|
81687
|
+
* @returns CSSProperties with color
|
|
81688
|
+
*/
|
|
81689
|
+
function textColorStyle(token) {
|
|
81690
|
+
const parsed = parseToken(token);
|
|
81691
|
+
const surfaceRole = parsed.raw ? null : surfaceRoleForTextToken(parsed.token);
|
|
81692
|
+
if (surfaceRole) return { color: parsed.opacityPercent === void 0 ? surfaceForegroundValue(surfaceRole) : surfaceForegroundValueWithOpacity(surfaceRole, parsed.opacityPercent) };
|
|
81693
|
+
return { color: rgbColorValue(token) };
|
|
81694
|
+
}
|
|
81695
|
+
/**
|
|
81696
|
+
* Creates a border color style object from a theme token.
|
|
81697
|
+
*
|
|
81698
|
+
* @param token - Theme color token
|
|
81699
|
+
* @returns CSSProperties with borderColor
|
|
81700
|
+
*/
|
|
81701
|
+
function borderColorStyle(token) {
|
|
81702
|
+
return { borderColor: rgbColorValue(token) };
|
|
81703
|
+
}
|
|
81704
|
+
/**
|
|
81705
|
+
* Merges multiple CSSProperties objects into a single object.
|
|
81706
|
+
* Later styles override earlier ones. Undefined values are filtered out.
|
|
81707
|
+
* Returns undefined if the merged result is empty.
|
|
81708
|
+
*
|
|
81709
|
+
* @param styles - Variable number of CSSProperties objects (can be undefined)
|
|
81710
|
+
* @returns Merged CSSProperties object, or undefined if empty
|
|
81711
|
+
*
|
|
81712
|
+
* @example
|
|
81713
|
+
* mergeStyles(
|
|
81714
|
+
* backgroundColorStyle('surface'),
|
|
81715
|
+
* textColorStyle('text'),
|
|
81716
|
+
* borderColorStyle('border')
|
|
81717
|
+
* )
|
|
81718
|
+
* // => { backgroundColor: '...', color: '...', borderColor: '...' }
|
|
81719
|
+
*/
|
|
81720
|
+
function mergeStyles(...styles) {
|
|
81721
|
+
const merged = {};
|
|
81722
|
+
for (const style of styles) {
|
|
81723
|
+
if (!style) continue;
|
|
81724
|
+
Object.assign(merged, style);
|
|
81725
|
+
}
|
|
81726
|
+
return Object.keys(merged).length ? merged : void 0;
|
|
81727
|
+
}
|
|
81728
|
+
//#endregion
|
|
81200
81729
|
//#region ../theme-core/src/tokens/resolver.ts
|
|
81201
81730
|
/**
|
|
81202
81731
|
* Resolves theme tokens to CSS variables
|
|
@@ -81223,7 +81752,7 @@ var TokenResolver = class {
|
|
|
81223
81752
|
*/
|
|
81224
81753
|
getColor(token) {
|
|
81225
81754
|
if (!this.tokenExists(token)) console.warn(`[TokenResolver] Color token "${token}" not found in theme palette. Button may render incorrectly.`);
|
|
81226
|
-
return
|
|
81755
|
+
return rgbColorValue(token);
|
|
81227
81756
|
}
|
|
81228
81757
|
/**
|
|
81229
81758
|
* Adjust a color token's shade by a given amount
|
|
@@ -82695,305 +83224,6 @@ function affordanceIconMaskUrl(iconId) {
|
|
|
82695
83224
|
return `data:image/svg+xml,${`<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'>${paths.map((d) => `<path d='${d}'/>`).join("")}</svg>`.replace(/"/g, "'").replace(/#/g, "%23").replace(/</g, "%3C").replace(/>/g, "%3E").replace(/\s+/g, " ")}`;
|
|
82696
83225
|
}
|
|
82697
83226
|
//#endregion
|
|
82698
|
-
//#region ../theme-core/src/palette/utils/opaqueSurfaceColor.ts
|
|
82699
|
-
/** Resolve an opaque colour, compositing alpha against an explicit underlay. */
|
|
82700
|
-
function resolveOpaqueSurfaceHex(reference, palette, underlayReference) {
|
|
82701
|
-
const opaque = resolveConcreteColorHex(reference, palette);
|
|
82702
|
-
if (opaque) return opaque;
|
|
82703
|
-
if (!underlayReference) return null;
|
|
82704
|
-
const underlayHex = resolveConcreteColorHex(underlayReference, palette);
|
|
82705
|
-
if (!underlayHex) return null;
|
|
82706
|
-
const parts = parseColorTokenParts(reference);
|
|
82707
|
-
if (parts.kind === "token" && parts.opacityPercent !== null) {
|
|
82708
|
-
const foregroundHex = normalizePaletteHex(palette[parts.token] ?? "");
|
|
82709
|
-
return foregroundHex ? compositeHex(foregroundHex, underlayHex, parts.opacityPercent / 100) : null;
|
|
82710
|
-
}
|
|
82711
|
-
const rgba = parseRgba(parts.kind === "raw" ? parts.value : reference);
|
|
82712
|
-
return rgba ? compositeHex(rgbToHex$1(rgba.r, rgba.g, rgba.b), underlayHex, rgba.alpha) : null;
|
|
82713
|
-
}
|
|
82714
|
-
/** Resolve a colour reference only when it is already fully opaque. */
|
|
82715
|
-
function resolveConcreteColorHex(reference, palette) {
|
|
82716
|
-
const literalHex = normalizePaletteHex(reference);
|
|
82717
|
-
if (literalHex) return literalHex;
|
|
82718
|
-
const parts = parseColorTokenParts(reference);
|
|
82719
|
-
if (parts.kind === "token") {
|
|
82720
|
-
if (parts.opacityPercent !== null) return null;
|
|
82721
|
-
return normalizePaletteHex(palette[parts.token] ?? "");
|
|
82722
|
-
}
|
|
82723
|
-
const literal = parts.kind === "raw" ? parts.value : reference;
|
|
82724
|
-
if (literal.toLowerCase() === "black") return "#000000";
|
|
82725
|
-
if (literal.toLowerCase() === "white") return "#ffffff";
|
|
82726
|
-
return normalizePaletteHex(literal);
|
|
82727
|
-
}
|
|
82728
|
-
function compositeHex(foregroundHex, underlayHex, alpha) {
|
|
82729
|
-
const foreground = hexToRgb(foregroundHex);
|
|
82730
|
-
const underlay = hexToRgb(underlayHex);
|
|
82731
|
-
const channel = (foregroundValue, underlayValue) => Math.round(foregroundValue * alpha + underlayValue * (1 - alpha));
|
|
82732
|
-
return rgbToHex$1(channel(foreground.r, underlay.r), channel(foreground.g, underlay.g), channel(foreground.b, underlay.b));
|
|
82733
|
-
}
|
|
82734
|
-
function parseRgba(value) {
|
|
82735
|
-
const match = value.trim().match(/^rgba?\(\s*([\d.]+)(?:\s*,\s*|\s+)([\d.]+)(?:\s*,\s*|\s+)([\d.]+)(?:\s*(?:,|\/)\s*([\d.]+%?))?\s*\)$/i);
|
|
82736
|
-
if (!match) return null;
|
|
82737
|
-
const [, rSource, gSource, bSource] = match;
|
|
82738
|
-
if (!rSource || !gSource || !bSource) return null;
|
|
82739
|
-
const r = Number(rSource);
|
|
82740
|
-
const g = Number(gSource);
|
|
82741
|
-
const b = Number(bSource);
|
|
82742
|
-
const alpha = parseAlpha(match[4]);
|
|
82743
|
-
if (alpha === null || !isRgbChannel(r) || !isRgbChannel(g) || !isRgbChannel(b)) return null;
|
|
82744
|
-
return {
|
|
82745
|
-
r,
|
|
82746
|
-
g,
|
|
82747
|
-
b,
|
|
82748
|
-
alpha
|
|
82749
|
-
};
|
|
82750
|
-
}
|
|
82751
|
-
function parseAlpha(source) {
|
|
82752
|
-
if (!source) return 1;
|
|
82753
|
-
const value = source.endsWith("%") ? Number(source.slice(0, -1)) / 100 : Number(source);
|
|
82754
|
-
return Number.isFinite(value) && value >= 0 && value <= 1 ? value : null;
|
|
82755
|
-
}
|
|
82756
|
-
function isRgbChannel(value) {
|
|
82757
|
-
return Number.isFinite(value) && value >= 0 && value <= 255;
|
|
82758
|
-
}
|
|
82759
|
-
//#endregion
|
|
82760
|
-
//#region ../theme-core/src/surfaces/resolveSurfaceForeground.ts
|
|
82761
|
-
const FALLBACK_TEXT_TOKENS = [
|
|
82762
|
-
"text",
|
|
82763
|
-
"primaryForeground",
|
|
82764
|
-
"secondaryForeground",
|
|
82765
|
-
"accentForeground",
|
|
82766
|
-
"neutral-950",
|
|
82767
|
-
"neutral-50"
|
|
82768
|
-
];
|
|
82769
|
-
const CANONICAL_EQUIVALENT_TOKEN_ORDER = [
|
|
82770
|
-
"text",
|
|
82771
|
-
"primaryForeground",
|
|
82772
|
-
"secondaryForeground",
|
|
82773
|
-
"accentForeground",
|
|
82774
|
-
"onPrimary",
|
|
82775
|
-
"onSecondary",
|
|
82776
|
-
"onAccent",
|
|
82777
|
-
"onSurface",
|
|
82778
|
-
"neutral-950",
|
|
82779
|
-
"neutral-50"
|
|
82780
|
-
];
|
|
82781
|
-
/**
|
|
82782
|
-
* Resolve the complete foreground contract for an effective page/section or
|
|
82783
|
-
* site-chrome background.
|
|
82784
|
-
*
|
|
82785
|
-
* Deterministic colour backgrounds are validated at ordinary-text WCAG AA.
|
|
82786
|
-
* Existing image/video/gradient treatments are trusted only when they already
|
|
82787
|
-
* carry a usable foreground token; this function deliberately does not claim
|
|
82788
|
-
* pixel-level contrast proof for media.
|
|
82789
|
-
*/
|
|
82790
|
-
function resolveSurfaceForeground(background, palette, candidates = {}, options = {}) {
|
|
82791
|
-
const authored = foregroundCandidates(background, candidates);
|
|
82792
|
-
if (background === null) return resolveDeterministicForeground("background", {
|
|
82793
|
-
...authored,
|
|
82794
|
-
text: authored.text ?? "text"
|
|
82795
|
-
}, palette);
|
|
82796
|
-
if (background.type === "color") {
|
|
82797
|
-
const backgroundReference = normalizedReference(background.color);
|
|
82798
|
-
if (!backgroundReference || backgroundReference === "transparent") return { kind: "unknown" };
|
|
82799
|
-
return resolveDeterministicForeground(backgroundReference, authored, palette, options.compositeBase);
|
|
82800
|
-
}
|
|
82801
|
-
return resolveTrustedTreatmentForeground(authored, palette);
|
|
82802
|
-
}
|
|
82803
|
-
function foregroundCandidates(background, overrides) {
|
|
82804
|
-
return {
|
|
82805
|
-
text: overrides.text ?? background?.textColor ?? null,
|
|
82806
|
-
heading: overrides.heading ?? background?.headingColor ?? null,
|
|
82807
|
-
link: overrides.link ?? background?.linkColor ?? null,
|
|
82808
|
-
supporting: overrides.supporting ?? background?.supportingColor ?? null
|
|
82809
|
-
};
|
|
82810
|
-
}
|
|
82811
|
-
function resolveDeterministicForeground(backgroundReference, candidates, palette, compositeBase) {
|
|
82812
|
-
const backgroundHex = resolveOpaqueSurfaceHex(backgroundReference, palette, compositeBase);
|
|
82813
|
-
if (!backgroundHex) return resolveTrustedTreatmentForeground(candidates, palette);
|
|
82814
|
-
const backgroundToken = paletteToken(backgroundReference);
|
|
82815
|
-
const derivedOnToken = backgroundToken ? onColorTokenName(backgroundToken) : null;
|
|
82816
|
-
const text = firstSafeToken([
|
|
82817
|
-
candidates.text,
|
|
82818
|
-
derivedOnToken,
|
|
82819
|
-
...FALLBACK_TEXT_TOKENS
|
|
82820
|
-
], backgroundHex, palette, derivedOnToken ? [derivedOnToken] : []);
|
|
82821
|
-
if (!text) return { kind: "unknown" };
|
|
82822
|
-
return {
|
|
82823
|
-
kind: "known",
|
|
82824
|
-
roles: {
|
|
82825
|
-
text,
|
|
82826
|
-
heading: safeTokenOr(candidates.heading, text, backgroundHex, palette),
|
|
82827
|
-
link: safeTokenOr(candidates.link, text, backgroundHex, palette),
|
|
82828
|
-
supporting: safeTokenOr(candidates.supporting, text, backgroundHex, palette)
|
|
82829
|
-
}
|
|
82830
|
-
};
|
|
82831
|
-
}
|
|
82832
|
-
function resolveTrustedTreatmentForeground(candidates, palette) {
|
|
82833
|
-
const text = canonicalToken(candidates.text, palette);
|
|
82834
|
-
if (!text) return { kind: "unknown" };
|
|
82835
|
-
return {
|
|
82836
|
-
kind: "known",
|
|
82837
|
-
roles: {
|
|
82838
|
-
text,
|
|
82839
|
-
heading: canonicalToken(candidates.heading, palette) ?? text,
|
|
82840
|
-
link: canonicalToken(candidates.link, palette) ?? text,
|
|
82841
|
-
supporting: canonicalToken(candidates.supporting, palette) ?? text
|
|
82842
|
-
}
|
|
82843
|
-
};
|
|
82844
|
-
}
|
|
82845
|
-
function safeTokenOr(candidate, fallback, backgroundHex, palette) {
|
|
82846
|
-
return firstSafeToken([candidate], backgroundHex, palette) ?? fallback;
|
|
82847
|
-
}
|
|
82848
|
-
function firstSafeToken(candidates, backgroundHex, palette, preferredEquivalentTokens = []) {
|
|
82849
|
-
const seen = /* @__PURE__ */ new Set();
|
|
82850
|
-
for (const candidate of candidates) {
|
|
82851
|
-
const token = canonicalToken(candidate, palette, preferredEquivalentTokens);
|
|
82852
|
-
if (!token || seen.has(token)) continue;
|
|
82853
|
-
seen.add(token);
|
|
82854
|
-
const foregroundHex = resolveConcreteColorHex(token, palette);
|
|
82855
|
-
if (foregroundHex && contrastRatio$1(backgroundHex, foregroundHex) >= 4.5) return token;
|
|
82856
|
-
}
|
|
82857
|
-
return null;
|
|
82858
|
-
}
|
|
82859
|
-
function canonicalToken(reference, palette, preferredEquivalentTokens = []) {
|
|
82860
|
-
const normalized = normalizedReference(reference);
|
|
82861
|
-
if (!normalized || normalized === "transparent") return null;
|
|
82862
|
-
const direct = parseThemeColorToken(normalized);
|
|
82863
|
-
if (direct && resolveConcreteColorHex(direct, palette)) return direct;
|
|
82864
|
-
const referenceHex = resolveConcreteColorHex(normalized, palette);
|
|
82865
|
-
if (!referenceHex) return null;
|
|
82866
|
-
const equivalent = [
|
|
82867
|
-
...preferredEquivalentTokens,
|
|
82868
|
-
...CANONICAL_EQUIVALENT_TOKEN_ORDER,
|
|
82869
|
-
...Object.keys(palette).sort()
|
|
82870
|
-
].find((token) => {
|
|
82871
|
-
const parsed = parseThemeColorToken(token);
|
|
82872
|
-
return parsed !== null && resolveConcreteColorHex(parsed, palette)?.toLowerCase() === referenceHex.toLowerCase();
|
|
82873
|
-
});
|
|
82874
|
-
return equivalent ? parseThemeColorToken(equivalent) : null;
|
|
82875
|
-
}
|
|
82876
|
-
function paletteToken(reference) {
|
|
82877
|
-
const parts = parseColorTokenParts(reference);
|
|
82878
|
-
return parts.kind === "token" && parts.opacityPercent === null ? parts.token : null;
|
|
82879
|
-
}
|
|
82880
|
-
function normalizedReference(value) {
|
|
82881
|
-
if (typeof value !== "string") return null;
|
|
82882
|
-
const normalized = value.trim();
|
|
82883
|
-
return normalized.length > 0 ? normalized : null;
|
|
82884
|
-
}
|
|
82885
|
-
//#endregion
|
|
82886
|
-
//#region ../theme-core/src/utils/colorStyles.ts
|
|
82887
|
-
const COLOR_VAR_PREFIX = "--tb-";
|
|
82888
|
-
function parseToken(source) {
|
|
82889
|
-
const parts = parseColorTokenParts(source);
|
|
82890
|
-
if (parts.kind === "raw") return {
|
|
82891
|
-
token: source,
|
|
82892
|
-
raw: parts.value
|
|
82893
|
-
};
|
|
82894
|
-
if (parts.kind === "invalid") return { token: source };
|
|
82895
|
-
return {
|
|
82896
|
-
token: parts.token,
|
|
82897
|
-
opacityPercent: parts.opacityPercent === null ? void 0 : parts.opacityPercent
|
|
82898
|
-
};
|
|
82899
|
-
}
|
|
82900
|
-
const SURFACE_TEXT_ROLE_BY_TOKEN = {
|
|
82901
|
-
text: "text",
|
|
82902
|
-
heading: "heading",
|
|
82903
|
-
mutedText: "supporting"
|
|
82904
|
-
};
|
|
82905
|
-
function surfaceRoleForTextToken(token) {
|
|
82906
|
-
return Object.prototype.hasOwnProperty.call(SURFACE_TEXT_ROLE_BY_TOKEN, token) ? SURFACE_TEXT_ROLE_BY_TOKEN[token] : null;
|
|
82907
|
-
}
|
|
82908
|
-
/**
|
|
82909
|
-
* Converts a theme color token to a CSS rgb value.
|
|
82910
|
-
* This is the primary function for applying theme colors to CSS properties.
|
|
82911
|
-
*
|
|
82912
|
-
* @param token - Theme color token (semantic, with opacity, or raw)
|
|
82913
|
-
* @returns CSS color value (rgb with optional alpha, or raw CSS value)
|
|
82914
|
-
*
|
|
82915
|
-
* @example
|
|
82916
|
-
* rgbColorValue('primary') // => 'rgb(var(--tb-primary))'
|
|
82917
|
-
* rgbColorValue('surface/95') // => 'rgb(var(--tb-surface) / 0.95)'
|
|
82918
|
-
* rgbColorValue('raw:transparent') // => 'transparent'
|
|
82919
|
-
*/
|
|
82920
|
-
function rgbColorValue(token) {
|
|
82921
|
-
const { token: baseToken, opacityPercent, raw } = parseToken(token);
|
|
82922
|
-
if (raw) return raw;
|
|
82923
|
-
const cssVar = `${COLOR_VAR_PREFIX}${baseToken}`;
|
|
82924
|
-
if (opacityPercent === void 0) return `rgb(var(${cssVar}))`;
|
|
82925
|
-
return `rgb(var(${cssVar}) / ${opacityPercent / 100})`;
|
|
82926
|
-
}
|
|
82927
|
-
/**
|
|
82928
|
-
* Converts a theme color token to a CSS variable reference.
|
|
82929
|
-
* Note: This returns the base variable without rgb() wrapper, ignoring opacity.
|
|
82930
|
-
*
|
|
82931
|
-
* @param token - Theme color token
|
|
82932
|
-
* @returns CSS variable reference
|
|
82933
|
-
*
|
|
82934
|
-
* @example
|
|
82935
|
-
* cssVarValue('primary') // => 'var(--tb-primary)'
|
|
82936
|
-
* cssVarValue('surface/95') // => 'var(--tb-surface)' (opacity ignored)
|
|
82937
|
-
*/
|
|
82938
|
-
function cssVarValue(token) {
|
|
82939
|
-
const { token: baseToken } = parseToken(token);
|
|
82940
|
-
return `var(${COLOR_VAR_PREFIX}${baseToken})`;
|
|
82941
|
-
}
|
|
82942
|
-
/**
|
|
82943
|
-
* Creates a backgroundColor style object from a theme token.
|
|
82944
|
-
*
|
|
82945
|
-
* @param token - Theme color token
|
|
82946
|
-
* @returns CSSProperties with backgroundColor
|
|
82947
|
-
*/
|
|
82948
|
-
function backgroundColorStyle(token) {
|
|
82949
|
-
return { backgroundColor: rgbColorValue(token) };
|
|
82950
|
-
}
|
|
82951
|
-
/**
|
|
82952
|
-
* Creates a text color style object from a theme token.
|
|
82953
|
-
*
|
|
82954
|
-
* @param token - Theme color token
|
|
82955
|
-
* @returns CSSProperties with color
|
|
82956
|
-
*/
|
|
82957
|
-
function textColorStyle(token) {
|
|
82958
|
-
const parsed = parseToken(token);
|
|
82959
|
-
const surfaceRole = parsed.raw ? null : surfaceRoleForTextToken(parsed.token);
|
|
82960
|
-
if (surfaceRole) return { color: parsed.opacityPercent === void 0 ? surfaceForegroundValue(surfaceRole) : surfaceForegroundValueWithOpacity(surfaceRole, parsed.opacityPercent) };
|
|
82961
|
-
return { color: rgbColorValue(token) };
|
|
82962
|
-
}
|
|
82963
|
-
/**
|
|
82964
|
-
* Creates a border color style object from a theme token.
|
|
82965
|
-
*
|
|
82966
|
-
* @param token - Theme color token
|
|
82967
|
-
* @returns CSSProperties with borderColor
|
|
82968
|
-
*/
|
|
82969
|
-
function borderColorStyle(token) {
|
|
82970
|
-
return { borderColor: rgbColorValue(token) };
|
|
82971
|
-
}
|
|
82972
|
-
/**
|
|
82973
|
-
* Merges multiple CSSProperties objects into a single object.
|
|
82974
|
-
* Later styles override earlier ones. Undefined values are filtered out.
|
|
82975
|
-
* Returns undefined if the merged result is empty.
|
|
82976
|
-
*
|
|
82977
|
-
* @param styles - Variable number of CSSProperties objects (can be undefined)
|
|
82978
|
-
* @returns Merged CSSProperties object, or undefined if empty
|
|
82979
|
-
*
|
|
82980
|
-
* @example
|
|
82981
|
-
* mergeStyles(
|
|
82982
|
-
* backgroundColorStyle('surface'),
|
|
82983
|
-
* textColorStyle('text'),
|
|
82984
|
-
* borderColorStyle('border')
|
|
82985
|
-
* )
|
|
82986
|
-
* // => { backgroundColor: '...', color: '...', borderColor: '...' }
|
|
82987
|
-
*/
|
|
82988
|
-
function mergeStyles(...styles) {
|
|
82989
|
-
const merged = {};
|
|
82990
|
-
for (const style of styles) {
|
|
82991
|
-
if (!style) continue;
|
|
82992
|
-
Object.assign(merged, style);
|
|
82993
|
-
}
|
|
82994
|
-
return Object.keys(merged).length ? merged : void 0;
|
|
82995
|
-
}
|
|
82996
|
-
//#endregion
|
|
82997
83227
|
//#region ../theme-core/src/utils/tokenOrColor.ts
|
|
82998
83228
|
/**
|
|
82999
83229
|
* Runtime color-reference fields intentionally accept any string, including
|
|
@@ -87863,8 +88093,14 @@ const headerInteractionPillPaletteValues = [
|
|
|
87863
88093
|
"accent"
|
|
87864
88094
|
];
|
|
87865
88095
|
/**
|
|
87866
|
-
* "No pill":
|
|
87867
|
-
*
|
|
88096
|
+
* "No pill": a colour change on hover rather than a filled background.
|
|
88097
|
+
*
|
|
88098
|
+
* The palette step writes nothing (#1318 Phase 4c decision 2), but on a
|
|
88099
|
+
* foreground-adaptive style that is not the end of the story: the hover colour
|
|
88100
|
+
* is derived from the resolved opening foreground at render time, paired with
|
|
88101
|
+
* the resting colour, so `quiet` resolves to a definite colour rather than to
|
|
88102
|
+
* whatever brand token the recipe happened to name. See
|
|
88103
|
+
* `applyOpeningForeground`.
|
|
87868
88104
|
*
|
|
87869
88105
|
* It exists because "a colour change on hover, no filled background" was not
|
|
87870
88106
|
* expressible in the vocabulary, and it is what
|
|
@@ -88944,6 +89180,28 @@ const bookingRequirementConsentFieldSchema = z.object({
|
|
|
88944
89180
|
const bookingConsentCarrierSchema = z.union([blockBookingConsentSchema, bookingRequirementConsentFieldSchema]);
|
|
88945
89181
|
//#endregion
|
|
88946
89182
|
//#region ../blocks/src/system/blocks/events/shared/schemas.ts
|
|
89183
|
+
const publicEventLoaderQuerySchemaShape = {
|
|
89184
|
+
limit: z.string().optional(),
|
|
89185
|
+
from: z.string().optional(),
|
|
89186
|
+
to: z.string().optional(),
|
|
89187
|
+
afterStartsAt: z.string().optional(),
|
|
89188
|
+
afterId: z.string().optional(),
|
|
89189
|
+
categoryIds: z.string().optional(),
|
|
89190
|
+
venueId: z.string().optional(),
|
|
89191
|
+
staffMemberId: z.string().optional(),
|
|
89192
|
+
eventSurface: z.string().optional(),
|
|
89193
|
+
eventPresets: z.string().optional(),
|
|
89194
|
+
scheduleScope: z.string().optional(),
|
|
89195
|
+
seriesId: z.string().optional(),
|
|
89196
|
+
seriesIds: z.string().optional(),
|
|
89197
|
+
runSeriesId: z.string().optional(),
|
|
89198
|
+
seriesSlug: z.string().optional(),
|
|
89199
|
+
includeOccurrenceId: z.string().optional(),
|
|
89200
|
+
readIntent: z.string().optional(),
|
|
89201
|
+
detailLevel: z.string().optional(),
|
|
89202
|
+
readProfile: z.string().optional()
|
|
89203
|
+
};
|
|
89204
|
+
z.object(publicEventLoaderQuerySchemaShape);
|
|
88947
89205
|
const eventPresetSchema = z.enum([
|
|
88948
89206
|
"event",
|
|
88949
89207
|
"class",
|
|
@@ -89454,7 +89712,7 @@ function planCalendarMonthRanges(months) {
|
|
|
89454
89712
|
const sorted = [...new Set(months)].sort();
|
|
89455
89713
|
const ranges = [];
|
|
89456
89714
|
for (const month of sorted) {
|
|
89457
|
-
const previous = ranges.
|
|
89715
|
+
const previous = ranges[ranges.length - 1];
|
|
89458
89716
|
const end = calendarMonthKey$1(addMonths(calendarMonthDate(month), 1));
|
|
89459
89717
|
if (previous?.endMonthExclusive === month && monthNumber(end) - monthNumber(previous.startMonth) <= 3) previous.endMonthExclusive = end;
|
|
89460
89718
|
else ranges.push({
|
|
@@ -89973,6 +90231,9 @@ function isApiSuccessResponse(json) {
|
|
|
89973
90231
|
* });
|
|
89974
90232
|
* ```
|
|
89975
90233
|
*/
|
|
90234
|
+
function publicEventsQuery(params) {
|
|
90235
|
+
return { ...params ?? {} };
|
|
90236
|
+
}
|
|
89976
90237
|
function createBlockApi(config) {
|
|
89977
90238
|
const { baseUrl, auth, authOverrides, siteId, isPreview } = config;
|
|
89978
90239
|
const dedup = createDeduplicationCache({ ttl: 100 });
|
|
@@ -90125,23 +90386,7 @@ function createBlockApi(config) {
|
|
|
90125
90386
|
const path = buildPath(EVENTS.list.path, { siteId: sid });
|
|
90126
90387
|
return request(EVENTS.list, {
|
|
90127
90388
|
path,
|
|
90128
|
-
query:
|
|
90129
|
-
from: params?.from,
|
|
90130
|
-
to: params?.to,
|
|
90131
|
-
afterStartsAt: params?.afterStartsAt,
|
|
90132
|
-
afterId: params?.afterId,
|
|
90133
|
-
limit: params?.limit,
|
|
90134
|
-
stage: params?.stage,
|
|
90135
|
-
eventSurface: params?.eventSurface,
|
|
90136
|
-
eventPresets: params?.eventPresets,
|
|
90137
|
-
scheduleScope: params?.scheduleScope,
|
|
90138
|
-
categoryIds: params?.categoryIds,
|
|
90139
|
-
venueId: params?.venueId,
|
|
90140
|
-
staffMemberId: params?.staffMemberId,
|
|
90141
|
-
seriesId: params?.seriesId,
|
|
90142
|
-
includeOccurrenceId: params?.includeOccurrenceId,
|
|
90143
|
-
detailLevel: params?.detailLevel
|
|
90144
|
-
}
|
|
90389
|
+
query: publicEventsQuery(params)
|
|
90145
90390
|
});
|
|
90146
90391
|
},
|
|
90147
90392
|
async getEventFilters(params) {
|
|
@@ -90205,7 +90450,7 @@ function createBlockApi(config) {
|
|
|
90205
90450
|
const path = buildPath(WHOLE_SERIES.waitlistClaimResolve.path, { siteId: sid });
|
|
90206
90451
|
return request(WHOLE_SERIES.waitlistClaimResolve, {
|
|
90207
90452
|
path,
|
|
90208
|
-
body:
|
|
90453
|
+
body: data
|
|
90209
90454
|
});
|
|
90210
90455
|
},
|
|
90211
90456
|
async getDiscountsAvailable(data) {
|
|
@@ -95384,7 +95629,7 @@ const publicPricingSchema = z.object({
|
|
|
95384
95629
|
singlePriceAmount: z.number().nullable(),
|
|
95385
95630
|
slidingMinAmount: z.number().nullable(),
|
|
95386
95631
|
slidingMaxAmount: z.number().nullable(),
|
|
95387
|
-
options: z.array(publicPricingOptionSchema)
|
|
95632
|
+
options: z.array(publicPricingOptionSchema).readonly()
|
|
95388
95633
|
});
|
|
95389
95634
|
const publicAppointmentServiceSchema = z.object({
|
|
95390
95635
|
id: z.string().min(1),
|
|
@@ -103283,143 +103528,6 @@ function assertUniqueLayoutProfileKeys(profiles) {
|
|
|
103283
103528
|
if (duplicates.length > 0) throw new Error(`Duplicate block layout design profiles: ${duplicates.join(", ")}`);
|
|
103284
103529
|
}
|
|
103285
103530
|
//#endregion
|
|
103286
|
-
//#region ../theme-core/src/tokens/tokens.ts
|
|
103287
|
-
const defaultThemeTokens = {
|
|
103288
|
-
color: {
|
|
103289
|
-
"background/base": "#ffffff",
|
|
103290
|
-
"background/elevated": "#f5f5f5",
|
|
103291
|
-
"surface/base": "#ffffff",
|
|
103292
|
-
"surface/subtle": "#f9f9fb",
|
|
103293
|
-
"surface/inverted": "#111111",
|
|
103294
|
-
"content/primary": "#111111",
|
|
103295
|
-
"content/secondary": "#3f3f46",
|
|
103296
|
-
"accent/primary": "#2563eb",
|
|
103297
|
-
"accent/secondary": "#1d4ed8",
|
|
103298
|
-
"border/base": "#e5e7eb"
|
|
103299
|
-
},
|
|
103300
|
-
typography: {
|
|
103301
|
-
"display/hero": {
|
|
103302
|
-
fontSize: "clamp(48px, 8vw, 96px)",
|
|
103303
|
-
lineHeight: "1.05",
|
|
103304
|
-
fontWeight: "700"
|
|
103305
|
-
},
|
|
103306
|
-
"display/section": {
|
|
103307
|
-
fontSize: "clamp(40px, 6vw, 72px)",
|
|
103308
|
-
lineHeight: "1.1",
|
|
103309
|
-
fontWeight: "700"
|
|
103310
|
-
},
|
|
103311
|
-
"heading/large": {
|
|
103312
|
-
fontSize: "clamp(32px, 4vw, 48px)",
|
|
103313
|
-
lineHeight: "1.2",
|
|
103314
|
-
fontWeight: "600"
|
|
103315
|
-
},
|
|
103316
|
-
"heading/medium": {
|
|
103317
|
-
fontSize: "clamp(24px, 3vw, 32px)",
|
|
103318
|
-
lineHeight: "1.25",
|
|
103319
|
-
fontWeight: "600"
|
|
103320
|
-
},
|
|
103321
|
-
"heading/small": {
|
|
103322
|
-
fontSize: "20px",
|
|
103323
|
-
lineHeight: "1.3",
|
|
103324
|
-
fontWeight: "600"
|
|
103325
|
-
},
|
|
103326
|
-
"body/normal": {
|
|
103327
|
-
fontSize: "16px",
|
|
103328
|
-
lineHeight: "1.6",
|
|
103329
|
-
fontWeight: "400"
|
|
103330
|
-
},
|
|
103331
|
-
"body/small": {
|
|
103332
|
-
fontSize: "14px",
|
|
103333
|
-
lineHeight: "1.5",
|
|
103334
|
-
fontWeight: "400"
|
|
103335
|
-
},
|
|
103336
|
-
caption: {
|
|
103337
|
-
fontSize: "12px",
|
|
103338
|
-
lineHeight: "1.4",
|
|
103339
|
-
fontWeight: "500"
|
|
103340
|
-
}
|
|
103341
|
-
},
|
|
103342
|
-
spacing: {
|
|
103343
|
-
none: "0px",
|
|
103344
|
-
"3xs": "4px",
|
|
103345
|
-
"2xs": "8px",
|
|
103346
|
-
xs: "12px",
|
|
103347
|
-
sm: "16px",
|
|
103348
|
-
md: "24px",
|
|
103349
|
-
lg: "32px",
|
|
103350
|
-
xl: "40px",
|
|
103351
|
-
"2xl": "56px",
|
|
103352
|
-
"3xl": "72px"
|
|
103353
|
-
},
|
|
103354
|
-
radius: {
|
|
103355
|
-
none: "0px",
|
|
103356
|
-
xs: "2px",
|
|
103357
|
-
sm: "4px",
|
|
103358
|
-
md: "8px",
|
|
103359
|
-
lg: "12px",
|
|
103360
|
-
pill: "999px",
|
|
103361
|
-
full: "9999px"
|
|
103362
|
-
},
|
|
103363
|
-
shadow: {
|
|
103364
|
-
none: "none",
|
|
103365
|
-
soft: "0px 2px 8px rgba(15, 23, 42, 0.08)",
|
|
103366
|
-
medium: "0px 6px 18px rgba(15, 23, 42, 0.12)",
|
|
103367
|
-
strong: "0px 12px 36px rgba(15, 23, 42, 0.16)"
|
|
103368
|
-
},
|
|
103369
|
-
palette: {
|
|
103370
|
-
surface: "#ffffff",
|
|
103371
|
-
"neutral-50": "#f9fafb",
|
|
103372
|
-
"neutral-900": "#111827",
|
|
103373
|
-
primary: "#2563eb",
|
|
103374
|
-
"primary-50": "#eff6ff",
|
|
103375
|
-
"primary-500": "#2563eb",
|
|
103376
|
-
"primary-900": "#1d4ed8",
|
|
103377
|
-
secondary: "#9333ea",
|
|
103378
|
-
"secondary-50": "#f3e8ff",
|
|
103379
|
-
"secondary-500": "#9333ea",
|
|
103380
|
-
"secondary-900": "#4c1d95",
|
|
103381
|
-
accent: "#f97316",
|
|
103382
|
-
"accent-50": "#fff7ed",
|
|
103383
|
-
"accent-500": "#f97316",
|
|
103384
|
-
"accent-900": "#7c2d12"
|
|
103385
|
-
}
|
|
103386
|
-
};
|
|
103387
|
-
/**
|
|
103388
|
-
* Project the expanded semantic palette into the token buckets consumed by
|
|
103389
|
-
* runtime transforms. Keep this mapping shared by full themes and the
|
|
103390
|
-
* tokens-only hosted-booking runtime so the two paths cannot drift.
|
|
103391
|
-
*/
|
|
103392
|
-
function buildThemeTokens(palette) {
|
|
103393
|
-
const tokens = cloneThemeTokens(defaultThemeTokens);
|
|
103394
|
-
const paletteStrings = {};
|
|
103395
|
-
for (const [key, value] of Object.entries(palette)) if (typeof value === "string" && value.trim().length > 0) paletteStrings[key] = value;
|
|
103396
|
-
tokens.palette = paletteStrings;
|
|
103397
|
-
const resolveColor = (...keys) => {
|
|
103398
|
-
for (const key of keys) {
|
|
103399
|
-
const value = paletteStrings[key];
|
|
103400
|
-
if (value) return value;
|
|
103401
|
-
}
|
|
103402
|
-
};
|
|
103403
|
-
const assignColor = (token, ...keys) => {
|
|
103404
|
-
const value = resolveColor(...keys);
|
|
103405
|
-
if (value) tokens.color[token] = value;
|
|
103406
|
-
};
|
|
103407
|
-
assignColor("background/base", "background", "surface", "primary-50");
|
|
103408
|
-
assignColor("background/elevated", "surface", "background");
|
|
103409
|
-
assignColor("surface/base", "surface", "background");
|
|
103410
|
-
assignColor("surface/subtle", "neutral-100", "surface", "background");
|
|
103411
|
-
assignColor("surface/inverted", "neutral-900", "text", "primary-900");
|
|
103412
|
-
assignColor("content/primary", "text", "body", "neutral-900");
|
|
103413
|
-
assignColor("content/secondary", "mutedText", "secondary", "neutral-600");
|
|
103414
|
-
assignColor("accent/primary", "primary", "accent");
|
|
103415
|
-
assignColor("accent/secondary", "accent", "secondary", "primary-400");
|
|
103416
|
-
assignColor("border/base", "border", "neutral-300");
|
|
103417
|
-
return tokens;
|
|
103418
|
-
}
|
|
103419
|
-
function cloneThemeTokens(source) {
|
|
103420
|
-
return JSON.parse(JSON.stringify(source));
|
|
103421
|
-
}
|
|
103422
|
-
//#endregion
|
|
103423
103531
|
//#region ../theme-core/src/site-styles/backgroundAppearance.ts
|
|
103424
103532
|
const backgroundAppearanceQuickColorTokenNames = [
|
|
103425
103533
|
"background",
|
|
@@ -118805,6 +118913,44 @@ function getRegistrationStartAt(event, occurrenceContext) {
|
|
|
118805
118913
|
return event?.registrationSubject.kind === "wholeSeries" ? event.startsAt : occurrenceContext?.startsAt ?? event?.startsAt;
|
|
118806
118914
|
}
|
|
118807
118915
|
//#endregion
|
|
118916
|
+
//#region ../blocks/src/system/runtime/nodes/event-registration/eventSourceRecovery.ts
|
|
118917
|
+
const { limit: _rawLimit, eventSurface: _rawEventSurface, scheduleScope: _rawScheduleScope, detailLevel: _rawDetailLevel, ...stringEventQueryShape } = publicEventLoaderQuerySchemaShape;
|
|
118918
|
+
const eventRecoveryRequestSchema = z.object({
|
|
118919
|
+
...stringEventQueryShape,
|
|
118920
|
+
limit: z.coerce.number().int().positive().optional(),
|
|
118921
|
+
eventSurface: z.enum(eventSurfaceScopeValues).optional(),
|
|
118922
|
+
scheduleScope: z.enum(eventScheduleScopeValues).optional(),
|
|
118923
|
+
detailLevel: z.enum(["full", "listing"]).optional(),
|
|
118924
|
+
stage: z.enum(["preview", "published"]).optional()
|
|
118925
|
+
});
|
|
118926
|
+
function resolveEventRegistrationEventSource(input) {
|
|
118927
|
+
if (input.wholeSeriesRunEvents != null) return {
|
|
118928
|
+
kind: "loaded",
|
|
118929
|
+
events: input.wholeSeriesRunEvents
|
|
118930
|
+
};
|
|
118931
|
+
if (input.events != null) return {
|
|
118932
|
+
kind: "loaded",
|
|
118933
|
+
events: input.events
|
|
118934
|
+
};
|
|
118935
|
+
return {
|
|
118936
|
+
kind: "unresolved",
|
|
118937
|
+
request: parseEventLoaderRecoveryRequest(input.failures?.wholeSeriesRunEvents ?? input.failures?.events)
|
|
118938
|
+
};
|
|
118939
|
+
}
|
|
118940
|
+
const eventLoaderFailureSchema = z.object({
|
|
118941
|
+
endpoint: z.literal("listPublicEvents"),
|
|
118942
|
+
params: eventRecoveryRequestSchema.extend({ siteId: z.string().optional() })
|
|
118943
|
+
});
|
|
118944
|
+
function parseEventLoaderRecoveryRequest(value) {
|
|
118945
|
+
const parsed = eventLoaderFailureSchema.safeParse(value);
|
|
118946
|
+
if (!parsed.success) return null;
|
|
118947
|
+
const { siteId: _siteId, stage, ...params } = parsed.data.params;
|
|
118948
|
+
return {
|
|
118949
|
+
...params,
|
|
118950
|
+
stage: stage ?? "published"
|
|
118951
|
+
};
|
|
118952
|
+
}
|
|
118953
|
+
//#endregion
|
|
118808
118954
|
//#region ../blocks/src/system/runtime/nodes/event-registration.interactive.ts
|
|
118809
118955
|
const EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS = [
|
|
118810
118956
|
"Date",
|
|
@@ -118822,8 +118968,6 @@ const eventRegistrationPublicEventSchema = z.preprocess(normalizeEventRegistrati
|
|
|
118822
118968
|
const eventRegistrationHydrationSchemaShape = {
|
|
118823
118969
|
occurrenceContext: occurrenceContextSchema.optional(),
|
|
118824
118970
|
subject: eventRegistrationPageSurfaceSubjectSchema.nullable().optional(),
|
|
118825
|
-
events: z.array(eventRegistrationPublicEventSchema).nullable().optional(),
|
|
118826
|
-
wholeSeriesRunEvents: z.array(eventRegistrationPublicEventSchema).nullable().optional(),
|
|
118827
118971
|
maxTickets: z.string().optional(),
|
|
118828
118972
|
showVenue: z.boolean().optional(),
|
|
118829
118973
|
showCapacity: z.boolean().optional(),
|
|
@@ -118835,12 +118979,22 @@ const eventRegistrationHydrationSchemaShape = {
|
|
|
118835
118979
|
sitePasses: publicPassProductCollectionSchema.nullable().optional(),
|
|
118836
118980
|
siteMemberships: publicMembershipProductCollectionSchema.nullable().optional()
|
|
118837
118981
|
};
|
|
118982
|
+
const eventRegistrationEventSourceSchema = z.discriminatedUnion("kind", [z.object({
|
|
118983
|
+
kind: z.literal("loaded"),
|
|
118984
|
+
events: z.array(eventRegistrationPublicEventSchema)
|
|
118985
|
+
}), z.object({
|
|
118986
|
+
kind: z.literal("unresolved"),
|
|
118987
|
+
request: eventRecoveryRequestSchema.nullable()
|
|
118988
|
+
})]);
|
|
118838
118989
|
const eventRegistrationSourceSchema = z.object({
|
|
118839
118990
|
siteId: z.string().optional(),
|
|
118840
118991
|
apiBaseUrl: z.string().optional(),
|
|
118841
118992
|
portalToken: z.string().nullable().optional(),
|
|
118842
118993
|
previewToken: z.string().nullable().optional(),
|
|
118843
118994
|
...eventRegistrationHydrationSchemaShape,
|
|
118995
|
+
events: z.array(eventRegistrationPublicEventSchema).nullable().optional(),
|
|
118996
|
+
wholeSeriesRunEvents: z.array(eventRegistrationPublicEventSchema).nullable().optional(),
|
|
118997
|
+
eventLoaderFailures: z.record(z.string(), z.unknown()).nullable().optional(),
|
|
118844
118998
|
className: z.string().nullable().optional(),
|
|
118845
118999
|
buttonText: z.string().nullable().optional(),
|
|
118846
119000
|
maxTickets: z.string().nullable().optional(),
|
|
@@ -118861,7 +119015,10 @@ const eventRegistrationDisplaySchema = z.discriminatedUnion("state", [z.object({
|
|
|
118861
119015
|
titleText: z.string(),
|
|
118862
119016
|
bodyText: z.string()
|
|
118863
119017
|
})]);
|
|
118864
|
-
const eventRegistrationHydrationSchema = z.object(
|
|
119018
|
+
const eventRegistrationHydrationSchema = z.object({
|
|
119019
|
+
...eventRegistrationHydrationSchemaShape,
|
|
119020
|
+
eventSource: eventRegistrationEventSourceSchema
|
|
119021
|
+
});
|
|
118865
119022
|
const eventRegistrationRenderSchema = z.object({
|
|
118866
119023
|
display: eventRegistrationDisplaySchema,
|
|
118867
119024
|
hydration: eventRegistrationHydrationSchema
|
|
@@ -118920,16 +119077,12 @@ function buildEventRegistrationShellStepLabels(source, scopedSourceEvents) {
|
|
|
118920
119077
|
function toScopedEventRegistrationEvents(scopedSourceEvents) {
|
|
118921
119078
|
return [...toRegistrationEvents(scopedSourceEvents), ...toWholeSeriesRegistrationEvents(scopedSourceEvents)];
|
|
118922
119079
|
}
|
|
118923
|
-
function scopeEventRegistrationSourceEvents(source) {
|
|
118924
|
-
return resolveEventRegistrationScopedEvents(
|
|
119080
|
+
function scopeEventRegistrationSourceEvents(source, eventSource) {
|
|
119081
|
+
return resolveEventRegistrationScopedEvents(eventSource.kind === "loaded" ? eventSource.events : [], {
|
|
118925
119082
|
occurrenceContext: source.occurrenceContext,
|
|
118926
119083
|
subject: source.subject
|
|
118927
119084
|
});
|
|
118928
119085
|
}
|
|
118929
|
-
function resolveLoadedEventRegistrationSourceEvents(source, scopedSourceEvents) {
|
|
118930
|
-
if (source.events == null && source.wholeSeriesRunEvents == null) return null;
|
|
118931
|
-
return [...scopedSourceEvents];
|
|
118932
|
-
}
|
|
118933
119086
|
/**
|
|
118934
119087
|
* The one run this surface is registering for, when the scoped events describe
|
|
118935
119088
|
* exactly one. More than one run means the visitor still has to choose.
|
|
@@ -118969,14 +119122,21 @@ const eventRegistrationBlockRuntime = defineClientOwnedBlockRuntime({
|
|
|
118969
119122
|
render: createZodCodec(eventRegistrationRenderSchema)
|
|
118970
119123
|
},
|
|
118971
119124
|
buildRender: (source) => {
|
|
118972
|
-
const
|
|
118973
|
-
|
|
119125
|
+
const eventSource = resolveEventRegistrationEventSource({
|
|
119126
|
+
events: source.events,
|
|
119127
|
+
wholeSeriesRunEvents: source.wholeSeriesRunEvents,
|
|
119128
|
+
failures: source.eventLoaderFailures
|
|
119129
|
+
});
|
|
119130
|
+
const scopedSourceEvents = scopeEventRegistrationSourceEvents(source, eventSource);
|
|
118974
119131
|
return {
|
|
118975
119132
|
display: buildEventRegistrationDisplayFromScopedEvents(source, scopedSourceEvents),
|
|
118976
119133
|
hydration: {
|
|
118977
119134
|
occurrenceContext: source.occurrenceContext ?? null,
|
|
118978
119135
|
subject: source.subject ?? null,
|
|
118979
|
-
|
|
119136
|
+
eventSource: eventSource.kind === "loaded" ? {
|
|
119137
|
+
...eventSource,
|
|
119138
|
+
events: [...scopedSourceEvents]
|
|
119139
|
+
} : eventSource,
|
|
118980
119140
|
maxTickets: source.maxTickets ?? void 0,
|
|
118981
119141
|
showVenue: source.showVenue,
|
|
118982
119142
|
showCapacity: source.showCapacity,
|
|
@@ -119166,6 +119326,7 @@ const eventRegistrationBlockDefinition = {
|
|
|
119166
119326
|
} },
|
|
119167
119327
|
events: { $bind: { from: "data.events" } },
|
|
119168
119328
|
wholeSeriesRunEvents: { $bind: { from: "data.wholeSeriesRunEvents" } },
|
|
119329
|
+
loaderFailures: { $bind: { from: "$root.loaderFailures" } },
|
|
119169
119330
|
sitePasses: { $bind: { from: "data.sitePasses" } },
|
|
119170
119331
|
siteMemberships: { $bind: { from: "data.siteMemberships" } },
|
|
119171
119332
|
stage: { $bind: {
|
|
@@ -121172,6 +121333,15 @@ const newsletterFieldSchema = z.object({
|
|
|
121172
121333
|
placeholder: z.string().optional()
|
|
121173
121334
|
});
|
|
121174
121335
|
const mailingListSignupBlockIdSchema = z.string().trim().min(1).transform(parseRequiredMailingListSignupBlockId);
|
|
121336
|
+
const mailingListContentVersionIdSchema = z.string().transform((value, ctx) => {
|
|
121337
|
+
const parsed = parseMailingListContentVersionId(value);
|
|
121338
|
+
if (parsed) return parsed;
|
|
121339
|
+
ctx.addIssue({
|
|
121340
|
+
code: z.ZodIssueCode.custom,
|
|
121341
|
+
message: "Invalid mailing-list content version ID"
|
|
121342
|
+
});
|
|
121343
|
+
return z.NEVER;
|
|
121344
|
+
});
|
|
121175
121345
|
const signedMailingListSourceTokenSchema = z.string().trim().min(1).transform(parseRequiredMailingListSignedSourceToken);
|
|
121176
121346
|
const newsletterSourceCommonSchema = z.object({
|
|
121177
121347
|
siteId: z.string().optional(),
|
|
@@ -121185,7 +121355,8 @@ const newsletterSourceCommonSchema = z.object({
|
|
|
121185
121355
|
const newsletterSourceSchema = z.discriminatedUnion("source", [
|
|
121186
121356
|
newsletterSourceCommonSchema.extend({
|
|
121187
121357
|
source: z.literal("block"),
|
|
121188
|
-
blockId: z.string().nullable().optional()
|
|
121358
|
+
blockId: z.string().nullable().optional(),
|
|
121359
|
+
contentVersionId: z.string().nullable().optional()
|
|
121189
121360
|
}),
|
|
121190
121361
|
newsletterSourceCommonSchema.extend({
|
|
121191
121362
|
source: z.literal("signed-footer"),
|
|
@@ -121201,6 +121372,7 @@ const newsletterDisplaySchema = z.object({
|
|
|
121201
121372
|
availability: z.enum(["ready", "unavailable"]),
|
|
121202
121373
|
className: z.string().nullable(),
|
|
121203
121374
|
buttonLabel: z.string(),
|
|
121375
|
+
successMessage: z.string(),
|
|
121204
121376
|
buttonVariant: newsletterButtonVariantSchema,
|
|
121205
121377
|
privacyNote: z.string().nullable(),
|
|
121206
121378
|
fields: z.array(newsletterFieldSchema),
|
|
@@ -121215,7 +121387,8 @@ const newsletterHydrationSchema = z.object({
|
|
|
121215
121387
|
tag: z.literal("block-source"),
|
|
121216
121388
|
sourceRef: z.object({
|
|
121217
121389
|
tag: z.literal("block_ref"),
|
|
121218
|
-
blockId: mailingListSignupBlockIdSchema
|
|
121390
|
+
blockId: mailingListSignupBlockIdSchema,
|
|
121391
|
+
contentVersionId: mailingListContentVersionIdSchema
|
|
121219
121392
|
}).nullable()
|
|
121220
121393
|
}),
|
|
121221
121394
|
z.object({
|
|
@@ -121254,6 +121427,7 @@ function buildNewsletterDisplay(source) {
|
|
|
121254
121427
|
fields: { preset: "emailOnly" },
|
|
121255
121428
|
includeOptionalPhone: false,
|
|
121256
121429
|
buttonLabel: "Subscribe",
|
|
121430
|
+
successMessage: DEFAULT_MAILING_LIST_SUCCESS_MESSAGE,
|
|
121257
121431
|
privacyNote: null
|
|
121258
121432
|
};
|
|
121259
121433
|
const targeting = source.targeting ?? { mode: "default" };
|
|
@@ -121263,6 +121437,7 @@ function buildNewsletterDisplay(source) {
|
|
|
121263
121437
|
availability: runtimeTargetingIsAvailable(context, targeting, choices) ? "ready" : "unavailable",
|
|
121264
121438
|
className: source.className ?? null,
|
|
121265
121439
|
buttonLabel: form.buttonLabel,
|
|
121440
|
+
successMessage: form.successMessage,
|
|
121266
121441
|
buttonVariant: source.buttonVariant ?? "primary",
|
|
121267
121442
|
privacyNote: form.privacyNote,
|
|
121268
121443
|
fields: getGlobalFormFields(form),
|
|
@@ -121293,7 +121468,7 @@ const newsletterFormBlockRuntime = defineProgressiveBlockRuntime({
|
|
|
121293
121468
|
function projectNewsletterFormHydrationTarget(source) {
|
|
121294
121469
|
switch (source.source) {
|
|
121295
121470
|
case "block": {
|
|
121296
|
-
const sourceRef = buildMailingListSignupBlockSourceRef(source.blockId);
|
|
121471
|
+
const sourceRef = buildMailingListSignupBlockSourceRef(source.blockId, source.contentVersionId);
|
|
121297
121472
|
if (sourceRef?.tag === "block_ref") return {
|
|
121298
121473
|
tag: "block-source",
|
|
121299
121474
|
sourceRef
|
|
@@ -123705,9 +123880,10 @@ function cx$1(...classes) {
|
|
|
123705
123880
|
* Server-safe placeholder for event registration.
|
|
123706
123881
|
* Provides a static container for island hydration without importing client hooks.
|
|
123707
123882
|
*/
|
|
123708
|
-
function EventRegistrationSSR({ blockId, subject, children, ...sourceProps }) {
|
|
123883
|
+
function EventRegistrationSSR({ blockId, subject, loaderFailures, children, ...sourceProps }) {
|
|
123709
123884
|
const islandProps = buildEventRegistrationInteractiveIslandProps({
|
|
123710
123885
|
...sourceProps,
|
|
123886
|
+
eventLoaderFailures: blockId ? loaderFailures?.[blockId] : void 0,
|
|
123711
123887
|
subject: normalizeEventRegistrationPageSurfaceSubject(subject)
|
|
123712
123888
|
});
|
|
123713
123889
|
const display = islandProps.render.display;
|
|
@@ -124040,7 +124216,7 @@ function NewsletterFormSSR(props) {
|
|
|
124040
124216
|
className: clsx("newsletter-form-ssr", className),
|
|
124041
124217
|
children: /* @__PURE__ */ jsx("p", {
|
|
124042
124218
|
role: "status",
|
|
124043
|
-
children: "
|
|
124219
|
+
children: "We can’t accept signups right now. Please try again later."
|
|
124044
124220
|
})
|
|
124045
124221
|
});
|
|
124046
124222
|
const renderField = (field) => {
|
|
@@ -124086,14 +124262,18 @@ function NewsletterFormSSR(props) {
|
|
|
124086
124262
|
children: [
|
|
124087
124263
|
fields.map(renderField),
|
|
124088
124264
|
islandProps.render.hydration.choicePresentation === "visitor_choice" ? /* @__PURE__ */ jsxs("fieldset", {
|
|
124089
|
-
className: "newsletter-topics",
|
|
124090
|
-
children: [/* @__PURE__ */ jsx("legend", {
|
|
124091
|
-
className: "
|
|
124265
|
+
className: "fb-fieldset newsletter-topics",
|
|
124266
|
+
children: [/* @__PURE__ */ jsx("legend", {
|
|
124267
|
+
className: "form-label",
|
|
124268
|
+
children: "What would you like to hear about?"
|
|
124269
|
+
}), display.choices.map((choice) => /* @__PURE__ */ jsxs("label", {
|
|
124270
|
+
className: "fb-inline form-label newsletter-topic-choice",
|
|
124092
124271
|
children: [/* @__PURE__ */ jsx("input", {
|
|
124093
124272
|
type: "checkbox",
|
|
124094
124273
|
name: "mailingListChoice",
|
|
124095
|
-
value: choice.id
|
|
124096
|
-
|
|
124274
|
+
value: choice.id,
|
|
124275
|
+
className: "form-checkbox"
|
|
124276
|
+
}), /* @__PURE__ */ jsx("span", { children: choice.label })]
|
|
124097
124277
|
}, choice.id))]
|
|
124098
124278
|
}) : null,
|
|
124099
124279
|
/* @__PURE__ */ jsx("div", {
|
|
@@ -128965,6 +129145,90 @@ function missingPaymentSelection() {
|
|
|
128965
129145
|
};
|
|
128966
129146
|
}
|
|
128967
129147
|
//#endregion
|
|
129148
|
+
//#region ../blocks/src/system/runtime/nodes/event-registration/checkoutRecovery.ts
|
|
129149
|
+
/** Recovery may select held places; checkout still owns admission and payment validation. */
|
|
129150
|
+
function checkoutRecoveryOptionAvailability(availability) {
|
|
129151
|
+
if (availability.kind === "available" || availability.reason === "sold_out" || availability.reason === "overallCapacityUnavailable") return {
|
|
129152
|
+
kind: "available",
|
|
129153
|
+
remainingPlaces: null
|
|
129154
|
+
};
|
|
129155
|
+
return availability;
|
|
129156
|
+
}
|
|
129157
|
+
/**
|
|
129158
|
+
* A form-only projection for the explicit existing-checkout path. It permits
|
|
129159
|
+
* collecting the original selection without claiming a new place is available.
|
|
129160
|
+
* The public checkout service identifies the customer and remains the admission
|
|
129161
|
+
* authority; no reservation/customer data is exposed through this projection.
|
|
129162
|
+
*/
|
|
129163
|
+
function getCheckoutRecoveryFormEligibility(eligibility) {
|
|
129164
|
+
if (!eligibility || eligibility.registration.kind !== "none" && eligibility.registration.kind !== "pending_payment" || eligibility.availability.kind === "unavailable" && eligibility.availability.reason !== "full" && eligibility.availability.reason !== "selectionRequired") return eligibility;
|
|
129165
|
+
const amountCents = eligibility.price ?? 0;
|
|
129166
|
+
if (amountCents <= 0 || !eligibility.currency || eligibility.availability.kind === "unavailable" && eligibility.availability.reason === "selectionRequired") return eligibility.registration.kind === "pending_payment" ? {
|
|
129167
|
+
...eligibility,
|
|
129168
|
+
registration: { kind: "none" },
|
|
129169
|
+
ticketTypes: eligibility.ticketTypes.map((option) => ({
|
|
129170
|
+
...option,
|
|
129171
|
+
availability: checkoutRecoveryOptionAvailability(option.availability)
|
|
129172
|
+
}))
|
|
129173
|
+
} : eligibility;
|
|
129174
|
+
const currency = eligibility.currency;
|
|
129175
|
+
const paymentOptions = eligibility.paymentTerms.allowedOptions.map((option) => {
|
|
129176
|
+
switch (option.kind) {
|
|
129177
|
+
case "upfront": return {
|
|
129178
|
+
kind: "payInFull",
|
|
129179
|
+
amountCents,
|
|
129180
|
+
currency
|
|
129181
|
+
};
|
|
129182
|
+
case "deferred_manual": return {
|
|
129183
|
+
kind: "deferredManual",
|
|
129184
|
+
amountCents,
|
|
129185
|
+
currency
|
|
129186
|
+
};
|
|
129187
|
+
case "instalment_plan": return {
|
|
129188
|
+
kind: "instalmentPlan",
|
|
129189
|
+
amountCents,
|
|
129190
|
+
currency
|
|
129191
|
+
};
|
|
129192
|
+
case "flexible_balance": return {
|
|
129193
|
+
kind: "flexibleBalance",
|
|
129194
|
+
amountCents,
|
|
129195
|
+
currency
|
|
129196
|
+
};
|
|
129197
|
+
}
|
|
129198
|
+
});
|
|
129199
|
+
return {
|
|
129200
|
+
...eligibility,
|
|
129201
|
+
registration: { kind: "none" },
|
|
129202
|
+
availability: {
|
|
129203
|
+
kind: "available",
|
|
129204
|
+
remainingPlaces: null,
|
|
129205
|
+
waitlistEnabled: eligibility.waitlistEnabled
|
|
129206
|
+
},
|
|
129207
|
+
eligible: paymentOptions.length > 0,
|
|
129208
|
+
isFull: false,
|
|
129209
|
+
canJoinWaitlist: false,
|
|
129210
|
+
isFree: false,
|
|
129211
|
+
requiresPayment: true,
|
|
129212
|
+
canPayDirectly: paymentOptions.length > 0,
|
|
129213
|
+
paymentOptions,
|
|
129214
|
+
eligiblePasses: [],
|
|
129215
|
+
eligibleMemberships: [],
|
|
129216
|
+
ticketTypes: eligibility.ticketTypes.map((option) => ({
|
|
129217
|
+
...option,
|
|
129218
|
+
availability: checkoutRecoveryOptionAvailability(option.availability)
|
|
129219
|
+
}))
|
|
129220
|
+
};
|
|
129221
|
+
}
|
|
129222
|
+
function isSoldOutEventSelectable(event, waitlistAvailable) {
|
|
129223
|
+
return waitlistAvailable || canRecoverEventCheckout(event);
|
|
129224
|
+
}
|
|
129225
|
+
function canJoinWaitlistOutsideRecovery(event, attendanceMode, checkoutRecovery) {
|
|
129226
|
+
return !checkoutRecovery && event !== null && canJoinEventWaitlist(event, { attendanceMode });
|
|
129227
|
+
}
|
|
129228
|
+
function canRecoverEventCheckout(event) {
|
|
129229
|
+
return event !== null && (event.registrationSubject.kind === "wholeSeries" || event.pricing.kind !== "free" && event.pricing.kind !== "external");
|
|
129230
|
+
}
|
|
129231
|
+
//#endregion
|
|
128968
129232
|
//#region ../blocks/src/system/runtime/nodes/event-registration/utils.ts
|
|
128969
129233
|
function getPortalSubjectEmail(profile) {
|
|
128970
129234
|
return profile?.email ?? null;
|
|
@@ -129150,7 +129414,7 @@ const EventSelectionStep = ({ events, selectedEvent, onSelect, showVenue, showCa
|
|
|
129150
129414
|
const remaining = getRemainingPlaces(selectMostOpenCapacitySource(event));
|
|
129151
129415
|
const isSoldOut = isEventFull(event);
|
|
129152
129416
|
const canJoinWaitlist = canJoinEventWaitlistOnAnyMode(event);
|
|
129153
|
-
const isUnavailable = isSoldOut && !canJoinWaitlist;
|
|
129417
|
+
const isUnavailable = isSoldOut && !isSoldOutEventSelectable(event, canJoinWaitlist);
|
|
129154
129418
|
const isLowCapacity = remaining.kind === "low";
|
|
129155
129419
|
const capacityLabel = formatEventRemainingPlaces(event, { full: "Sold out" });
|
|
129156
129420
|
const timeZone = event.timeZone ?? null;
|
|
@@ -129195,6 +129459,33 @@ const EventSelectionStep = ({ events, selectedEvent, onSelect, showVenue, showCa
|
|
|
129195
129459
|
});
|
|
129196
129460
|
};
|
|
129197
129461
|
//#endregion
|
|
129462
|
+
//#region ../blocks/src/system/runtime/nodes/event-registration/useCheckoutRecovery.ts
|
|
129463
|
+
/** Recovery belongs to the selected booking subject; changing events resets its scope. */
|
|
129464
|
+
function useCheckoutRecovery(event, setStep) {
|
|
129465
|
+
const [recoveryEventId, setRecoveryEventId] = useState(null);
|
|
129466
|
+
return {
|
|
129467
|
+
checkoutRecovery: event !== null && recoveryEventId === event.selectionId,
|
|
129468
|
+
startCheckoutRecovery: useCallback(() => {
|
|
129469
|
+
if (!event) return;
|
|
129470
|
+
setRecoveryEventId(event.selectionId);
|
|
129471
|
+
setStep("select-tickets");
|
|
129472
|
+
}, [event, setStep])
|
|
129473
|
+
};
|
|
129474
|
+
}
|
|
129475
|
+
/** Authenticated pending bookings enter the same form-only recovery path as guests. */
|
|
129476
|
+
function useCheckoutRecoveryEligibility(eligibility, step, checkoutRecovery, startCheckoutRecovery) {
|
|
129477
|
+
const registrationKind = eligibility?.registration.kind;
|
|
129478
|
+
useEffect(() => {
|
|
129479
|
+
if ((step === "select-event" || step === "select-tickets" || step === "enter-details" || step === "select-payment") && registrationKind === "pending_payment" && !checkoutRecovery) startCheckoutRecovery();
|
|
129480
|
+
}, [
|
|
129481
|
+
registrationKind,
|
|
129482
|
+
step,
|
|
129483
|
+
checkoutRecovery,
|
|
129484
|
+
startCheckoutRecovery
|
|
129485
|
+
]);
|
|
129486
|
+
return useMemo(() => checkoutRecovery ? getCheckoutRecoveryFormEligibility(eligibility) : eligibility, [checkoutRecovery, eligibility]);
|
|
129487
|
+
}
|
|
129488
|
+
//#endregion
|
|
129198
129489
|
//#region ../blocks/src/system/runtime/nodes/event-registration/registrationErrorRecovery.ts
|
|
129199
129490
|
function resolveRegistrationRecoveryAction(step, action) {
|
|
129200
129491
|
if (step === "payment-failed") return "payment-options";
|
|
@@ -129835,6 +130126,10 @@ const eventRegistrationErrors = {
|
|
|
129835
130126
|
message: "We’re checking your booking and payment. Please don’t try to book again yet. If you’ve already paid, you don’t need to pay again.",
|
|
129836
130127
|
action: "payment-status"
|
|
129837
130128
|
},
|
|
130129
|
+
paymentProviderUnavailable: {
|
|
130130
|
+
message: "We couldn’t reach the payment provider. Please try again in a minute.",
|
|
130131
|
+
action: "retry"
|
|
130132
|
+
},
|
|
129838
130133
|
paymentPageUnavailable: {
|
|
129839
130134
|
message: "We couldn’t open the payment page. Please refresh this page and try again. If this keeps happening, contact the organiser for help.",
|
|
129840
130135
|
action: "retry"
|
|
@@ -129957,11 +130252,6 @@ function ensureWaitlistClaimLocationTracking() {
|
|
|
129957
130252
|
} catch {}
|
|
129958
130253
|
window.addEventListener("popstate", emitWaitlistClaimLocationChange);
|
|
129959
130254
|
}
|
|
129960
|
-
function getWaitlistClaimTokenFromUrl() {
|
|
129961
|
-
if (typeof window === "undefined") return null;
|
|
129962
|
-
const token = new URLSearchParams(window.location.search).get("waitlist_claim")?.trim() ?? "";
|
|
129963
|
-
return token.length > 0 ? token : null;
|
|
129964
|
-
}
|
|
129965
130255
|
const useWaitlistClaimDeps = { useBlockApi };
|
|
129966
130256
|
function subscribeToWaitlistClaimToken(callback) {
|
|
129967
130257
|
if (typeof window === "undefined") return () => {};
|
|
@@ -129971,28 +130261,42 @@ function subscribeToWaitlistClaimToken(callback) {
|
|
|
129971
130261
|
window.removeEventListener(WAITLIST_CLAIM_LOCATION_EVENT, callback);
|
|
129972
130262
|
};
|
|
129973
130263
|
}
|
|
129974
|
-
function
|
|
129975
|
-
return
|
|
130264
|
+
function getWaitlistClaimLocationSnapshot() {
|
|
130265
|
+
return typeof window === "undefined" ? "" : window.location.search;
|
|
130266
|
+
}
|
|
130267
|
+
function parseWaitlistClaimCredential(search) {
|
|
130268
|
+
const params = new URLSearchParams(search);
|
|
130269
|
+
const token = params.get("waitlist_claim")?.trim();
|
|
130270
|
+
if (token) return {
|
|
130271
|
+
kind: "emailedToken",
|
|
130272
|
+
token
|
|
130273
|
+
};
|
|
130274
|
+
const entryId = params.get("waitlistEntry")?.trim();
|
|
130275
|
+
return entryId ? {
|
|
130276
|
+
kind: "portalOwnedEntry",
|
|
130277
|
+
entryId
|
|
130278
|
+
} : null;
|
|
129976
130279
|
}
|
|
129977
130280
|
function useWaitlistClaim() {
|
|
129978
130281
|
return useWaitlistClaimWithDeps(useWaitlistClaimDeps);
|
|
129979
130282
|
}
|
|
129980
130283
|
function useWaitlistClaimWithDeps(deps) {
|
|
129981
|
-
|
|
130284
|
+
const locationSearch = useSyncExternalStore(subscribeToWaitlistClaimToken, getWaitlistClaimLocationSnapshot, () => "");
|
|
130285
|
+
return useResolvedWaitlistClaim(deps, useMemo(() => parseWaitlistClaimCredential(locationSearch), [locationSearch]));
|
|
129982
130286
|
}
|
|
129983
|
-
function useResolvedWaitlistClaim(deps,
|
|
130287
|
+
function useResolvedWaitlistClaim(deps, credential) {
|
|
129984
130288
|
const api = deps.useBlockApi();
|
|
129985
|
-
const [state, dispatch] = useReducer(waitlistClaimReducer, Boolean(
|
|
130289
|
+
const [state, dispatch] = useReducer(waitlistClaimReducer, Boolean(credential), createInitialWaitlistClaimState);
|
|
129986
130290
|
useEffect(() => {
|
|
129987
130291
|
let cancelled = false;
|
|
129988
130292
|
async function resolveClaim() {
|
|
129989
|
-
if (!
|
|
130293
|
+
if (!credential) {
|
|
129990
130294
|
dispatch({ type: "cleared" });
|
|
129991
130295
|
return;
|
|
129992
130296
|
}
|
|
129993
130297
|
dispatch({ type: "started" });
|
|
129994
130298
|
try {
|
|
129995
|
-
const result = await api.resolveWaitlistClaim({ claimToken: token });
|
|
130299
|
+
const result = credential.kind === "portalOwnedEntry" ? await api.resolveWaitlistClaim({ waitlistEntryId: credential.entryId }) : await api.resolveWaitlistClaim({ claimToken: credential.token });
|
|
129996
130300
|
if (cancelled) return;
|
|
129997
130301
|
dispatch({
|
|
129998
130302
|
type: "resolved",
|
|
@@ -130010,9 +130314,10 @@ function useResolvedWaitlistClaim(deps, token) {
|
|
|
130010
130314
|
return () => {
|
|
130011
130315
|
cancelled = true;
|
|
130012
130316
|
};
|
|
130013
|
-
}, [api,
|
|
130317
|
+
}, [api, credential]);
|
|
130014
130318
|
return {
|
|
130015
|
-
token,
|
|
130319
|
+
token: credential?.kind === "emailedToken" ? credential.token : null,
|
|
130320
|
+
entryId: credential?.kind === "portalOwnedEntry" ? credential.entryId : null,
|
|
130016
130321
|
claim: getWaitlistClaim(state),
|
|
130017
130322
|
error: getWaitlistClaimError(state),
|
|
130018
130323
|
loginMessage: getWaitlistClaimLoginMessage(state),
|
|
@@ -130490,15 +130795,12 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
|
|
|
130490
130795
|
* landed — a success, or a hand-off to checkout — because until then nobody
|
|
130491
130796
|
* knows whether the first one committed.
|
|
130492
130797
|
*
|
|
130493
|
-
*
|
|
130494
|
-
* details
|
|
130495
|
-
* anything, so a submission that already booked is answered with the booking
|
|
130496
|
-
* that exists — not refused for spending a credit or a claim that this very
|
|
130497
|
-
* command already spent, and not treated as a second booking because a name
|
|
130498
|
-
* or a note changed in between.
|
|
130798
|
+
* Identical retries retain the command after a lost response. Changed form
|
|
130799
|
+
* details get a new command so the server applies the new booking intent.
|
|
130499
130800
|
*/
|
|
130500
|
-
const
|
|
130501
|
-
|
|
130801
|
+
const commandRef = useRef(null);
|
|
130802
|
+
const inFlightRef = useRef(null);
|
|
130803
|
+
const submit = async (method, passId, membershipId, selection, submitOptions) => {
|
|
130502
130804
|
const target = options.registrationTarget;
|
|
130503
130805
|
if (!target) return {
|
|
130504
130806
|
ok: false,
|
|
@@ -130506,44 +130808,34 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
|
|
|
130506
130808
|
message: "Select an event to continue."
|
|
130507
130809
|
};
|
|
130508
130810
|
options.setStep("submitting");
|
|
130509
|
-
const registrationCommandId =
|
|
130510
|
-
commandIdRef.current = registrationCommandId;
|
|
130811
|
+
const registrationCommandId = commandRef.current?.id ?? deps.createClientCommandId();
|
|
130511
130812
|
try {
|
|
130512
|
-
|
|
130813
|
+
let prepared = prepareSubmitContext(options, registrationCommandId, target, method, passId, membershipId, selection);
|
|
130513
130814
|
if (prepared.subject.kind === "wholeSeries" && method === "stripe") {
|
|
130514
|
-
|
|
130815
|
+
commandRef.current = null;
|
|
130515
130816
|
return await submitWholeSeriesCheckout(options, deps, {
|
|
130516
130817
|
...prepared,
|
|
130517
130818
|
subject: prepared.subject
|
|
130518
130819
|
}, submitOptions);
|
|
130519
130820
|
}
|
|
130821
|
+
const request = buildOccurrenceRegistrationRequest(options, prepared, method, passId, membershipId);
|
|
130822
|
+
const intentKey = registrationRequestIntentKey(request);
|
|
130823
|
+
if (commandRef.current !== null && commandRef.current.intentKey !== intentKey) prepared = {
|
|
130824
|
+
...prepared,
|
|
130825
|
+
registrationCommandId: deps.createClientCommandId()
|
|
130826
|
+
};
|
|
130827
|
+
commandRef.current = {
|
|
130828
|
+
id: prepared.registrationCommandId,
|
|
130829
|
+
intentKey
|
|
130830
|
+
};
|
|
130520
130831
|
const result = await options.api.registerForEvent({
|
|
130521
|
-
|
|
130522
|
-
|
|
130523
|
-
ticketSelections: toTicketSelectionRequests(prepared.ticketSelections),
|
|
130524
|
-
selectedSlidingAmount: options.selectedSlidingAmount ?? void 0,
|
|
130525
|
-
email: options.formData.email.trim().toLowerCase(),
|
|
130526
|
-
name: options.formData.name.trim(),
|
|
130527
|
-
phone: options.formData.phone.trim() || void 0,
|
|
130528
|
-
notes: options.formData.notes.trim() || void 0,
|
|
130529
|
-
consentAccepted: options.formData.consentAccepted,
|
|
130530
|
-
altchaSolution: options.altchaSolution,
|
|
130531
|
-
paymentMethod: method,
|
|
130532
|
-
customerPassId: method === "pass" ? passId : void 0,
|
|
130533
|
-
customerMembershipId: method === "membership" ? membershipId : void 0,
|
|
130534
|
-
bundleProductId: prepared.bundleProductId,
|
|
130535
|
-
claimToken: options.claimToken ?? void 0,
|
|
130536
|
-
guests: prepared.guestsPayload
|
|
130832
|
+
...request,
|
|
130833
|
+
registrationCommandId: prepared.registrationCommandId
|
|
130537
130834
|
});
|
|
130538
|
-
|
|
130539
|
-
|
|
130540
|
-
options.setRegistrationResult(toRegistrationResult(result));
|
|
130541
|
-
options.setStep("success");
|
|
130542
|
-
return {
|
|
130543
|
-
ok: true,
|
|
130544
|
-
outcome: { kind: "completed" }
|
|
130545
|
-
};
|
|
130835
|
+
commandRef.current = null;
|
|
130836
|
+
return await completeRegistrationSubmission(options, deps, prepared, result, method, submitOptions);
|
|
130546
130837
|
} catch (error) {
|
|
130838
|
+
if (error instanceof BlockApiError && error.tag === "registrationPreparationChanged") commandRef.current = null;
|
|
130547
130839
|
const { message, action } = registrationErrorPresentation(error);
|
|
130548
130840
|
options.setErrorAction?.(action);
|
|
130549
130841
|
options.setErrorMessage(message);
|
|
@@ -130555,6 +130847,24 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
|
|
|
130555
130847
|
};
|
|
130556
130848
|
}
|
|
130557
130849
|
};
|
|
130850
|
+
return (...args) => {
|
|
130851
|
+
if (inFlightRef.current) return inFlightRef.current;
|
|
130852
|
+
const pending = Promise.resolve().then(() => submit(...args));
|
|
130853
|
+
inFlightRef.current = pending;
|
|
130854
|
+
pending.finally(() => {
|
|
130855
|
+
if (inFlightRef.current === pending) inFlightRef.current = null;
|
|
130856
|
+
});
|
|
130857
|
+
return pending;
|
|
130858
|
+
};
|
|
130859
|
+
}
|
|
130860
|
+
async function completeRegistrationSubmission(options, deps, prepared, result, method, submitOptions) {
|
|
130861
|
+
if (needsOccurrenceCheckout(result, method)) return await submitOccurrenceCheckout(options, deps, prepared, result, method, submitOptions);
|
|
130862
|
+
options.setRegistrationResult(toRegistrationResult(result));
|
|
130863
|
+
options.setStep("success");
|
|
130864
|
+
return {
|
|
130865
|
+
ok: true,
|
|
130866
|
+
outcome: { kind: "completed" }
|
|
130867
|
+
};
|
|
130558
130868
|
}
|
|
130559
130869
|
function toTicketSelectionRequests(lines) {
|
|
130560
130870
|
return lines.map((line) => ({
|
|
@@ -130629,6 +130939,7 @@ async function submitWholeSeriesCheckout(options, deps, prepared, submitOptions)
|
|
|
130629
130939
|
altchaSolution: options.altchaSolution,
|
|
130630
130940
|
guests: prepared.guestsPayload,
|
|
130631
130941
|
claimToken: options.claimToken ?? void 0,
|
|
130942
|
+
waitlistEntryId: options.waitlistEntryId ?? void 0,
|
|
130632
130943
|
discountCode: options.discountCode.trim() || void 0,
|
|
130633
130944
|
collectionOptionKind: prepared.selectionSnapshot.collectionOptionKind,
|
|
130634
130945
|
checkoutAttemptId,
|
|
@@ -130650,14 +130961,14 @@ async function submitWholeSeriesCheckout(options, deps, prepared, submitOptions)
|
|
|
130650
130961
|
}
|
|
130651
130962
|
if (result.bypassed) return completeBypassedCheckout(options);
|
|
130652
130963
|
if (!result.checkoutUrl) throw new Error("Checkout URL missing");
|
|
130653
|
-
savePendingCheckout(options, deps, prepared, checkoutAttemptId, {
|
|
130964
|
+
savePendingCheckout(options, deps, prepared, result.checkoutAttemptId, {
|
|
130654
130965
|
scope: "wholeSeries",
|
|
130655
130966
|
registrationId: result.registrationId
|
|
130656
130967
|
});
|
|
130657
130968
|
return redirectToCheckout(result.checkoutUrl, submitOptions);
|
|
130658
130969
|
}
|
|
130659
130970
|
function needsOccurrenceCheckout(result, method) {
|
|
130660
|
-
return result.scope === "occurrence" &&
|
|
130971
|
+
return result.scope === "occurrence" && result.status === "confirmed" && result.pendingPayment && [
|
|
130661
130972
|
"stripe",
|
|
130662
130973
|
"pass_bundle",
|
|
130663
130974
|
"membership_bundle"
|
|
@@ -130677,6 +130988,7 @@ async function submitOccurrenceCheckout(options, deps, prepared, registration, m
|
|
|
130677
130988
|
kind: "occurrence",
|
|
130678
130989
|
attendeeId: registration.attendeeId
|
|
130679
130990
|
},
|
|
130991
|
+
registrationCommandId: prepared.registrationCommandId,
|
|
130680
130992
|
checkoutType: method === "pass_bundle" ? "pass_bundle" : method === "membership_bundle" ? "membership_bundle" : "event",
|
|
130681
130993
|
productId: prepared.bundleProductId,
|
|
130682
130994
|
discountCode: options.discountCode.trim() || void 0,
|
|
@@ -130719,6 +131031,31 @@ function redirectToCheckout(checkoutUrl, submitOptions) {
|
|
|
130719
131031
|
}
|
|
130720
131032
|
};
|
|
130721
131033
|
}
|
|
131034
|
+
function registrationRequestIntentKey(request) {
|
|
131035
|
+
const { registrationCommandId: _command, altchaSolution: _proof, ...intent } = request;
|
|
131036
|
+
return JSON.stringify(intent);
|
|
131037
|
+
}
|
|
131038
|
+
function buildOccurrenceRegistrationRequest(options, prepared, method, passId, membershipId) {
|
|
131039
|
+
return {
|
|
131040
|
+
registrationCommandId: prepared.registrationCommandId,
|
|
131041
|
+
subject: prepared.subject,
|
|
131042
|
+
ticketSelections: toTicketSelectionRequests(prepared.ticketSelections),
|
|
131043
|
+
selectedSlidingAmount: options.selectedSlidingAmount ?? void 0,
|
|
131044
|
+
email: options.formData.email.trim().toLowerCase(),
|
|
131045
|
+
name: options.formData.name.trim(),
|
|
131046
|
+
phone: options.formData.phone.trim() || void 0,
|
|
131047
|
+
notes: options.formData.notes.trim() || void 0,
|
|
131048
|
+
consentAccepted: options.formData.consentAccepted,
|
|
131049
|
+
altchaSolution: options.altchaSolution,
|
|
131050
|
+
paymentMethod: method,
|
|
131051
|
+
customerPassId: method === "pass" ? passId : void 0,
|
|
131052
|
+
customerMembershipId: method === "membership" ? membershipId : void 0,
|
|
131053
|
+
bundleProductId: prepared.bundleProductId,
|
|
131054
|
+
claimToken: options.claimToken ?? void 0,
|
|
131055
|
+
waitlistEntryId: options.waitlistEntryId ?? void 0,
|
|
131056
|
+
guests: prepared.guestsPayload
|
|
131057
|
+
};
|
|
131058
|
+
}
|
|
130722
131059
|
//#endregion
|
|
130723
131060
|
//#region ../blocks/src/system/runtime/nodes/event-registration/registrationWizardContext.ts
|
|
130724
131061
|
function getEventSelectionDefaults(event) {
|
|
@@ -130957,14 +131294,28 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
130957
131294
|
}), [options.occurrenceContext, selectedEvent]);
|
|
130958
131295
|
const registrationOccurrenceId = getRegistrationOccurrenceId(registrationTarget);
|
|
130959
131296
|
const currentEvent = selectedEvent ?? preSelectedEvent;
|
|
131297
|
+
const setStep = useCallback((nextStep) => {
|
|
131298
|
+
dispatchFlow({
|
|
131299
|
+
type: "set-step",
|
|
131300
|
+
step: nextStep
|
|
131301
|
+
});
|
|
131302
|
+
}, []);
|
|
131303
|
+
const { checkoutRecovery, startCheckoutRecovery } = useCheckoutRecovery(currentEvent, setStep);
|
|
130960
131304
|
const currentEventUsesTicketTypes = usesTieredPricing(currentEvent);
|
|
130961
|
-
const currentCanJoinWaitlist =
|
|
131305
|
+
const currentCanJoinWaitlist = canJoinWaitlistOutsideRecovery(currentEvent, selectedAttendanceMode, checkoutRecovery);
|
|
130962
131306
|
const usesTicketTypeSelections = currentEventUsesTicketTypes && !currentCanJoinWaitlist;
|
|
130963
131307
|
const eventTicketTypesForSelection = useMemo(() => getVisibleTicketTypes({
|
|
130964
131308
|
event: currentEvent,
|
|
130965
131309
|
eligibility: null,
|
|
130966
131310
|
selectedAttendanceMode
|
|
130967
|
-
})
|
|
131311
|
+
}).map((option) => checkoutRecovery ? {
|
|
131312
|
+
...option,
|
|
131313
|
+
availability: checkoutRecoveryOptionAvailability(option.availability)
|
|
131314
|
+
} : option), [
|
|
131315
|
+
currentEvent,
|
|
131316
|
+
selectedAttendanceMode,
|
|
131317
|
+
checkoutRecovery
|
|
131318
|
+
]);
|
|
130968
131319
|
const normalizedSelectedTicketLines = useMemo(() => normalizeTicketSelectionLines(selectedTicketLines), [selectedTicketLines]);
|
|
130969
131320
|
const ticketTypeSelectionTotal = useMemo(() => getTicketSelectionTotal(normalizedSelectedTicketLines), [normalizedSelectedTicketLines]);
|
|
130970
131321
|
const ticketsCount = usesTicketTypeSelections ? ticketTypeSelectionTotal : flowState.ticketsCount;
|
|
@@ -131002,17 +131353,11 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
131002
131353
|
isAuthenticated: portalAuthState === "authenticated",
|
|
131003
131354
|
occurrenceId: registrationOccurrenceId
|
|
131004
131355
|
});
|
|
131005
|
-
const eligibility = eligibilityResult.eligibility;
|
|
131356
|
+
const eligibility = useCheckoutRecoveryEligibility(eligibilityResult.eligibility, step, checkoutRecovery, startCheckoutRecovery);
|
|
131006
131357
|
const eligibilityLoading = eligibilityResult.isLoading;
|
|
131007
131358
|
const eligibilityError = eligibilityResult.error;
|
|
131008
131359
|
const portalCreditState = eligibilityResult.creditState;
|
|
131009
131360
|
const registrationState = eligibility?.registration ?? { kind: "none" };
|
|
131010
|
-
const setStep = useCallback((nextStep) => {
|
|
131011
|
-
dispatchFlow({
|
|
131012
|
-
type: "set-step",
|
|
131013
|
-
step: nextStep
|
|
131014
|
-
});
|
|
131015
|
-
}, []);
|
|
131016
131361
|
const setTicketsCount = useCallback((nextTicketsCount) => {
|
|
131017
131362
|
dispatchFlow({
|
|
131018
131363
|
type: "set-tickets-count",
|
|
@@ -131120,10 +131465,14 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
131120
131465
|
event: currentEvent,
|
|
131121
131466
|
eligibility,
|
|
131122
131467
|
selectedAttendanceMode
|
|
131123
|
-
})
|
|
131468
|
+
}).map((option) => checkoutRecovery ? {
|
|
131469
|
+
...option,
|
|
131470
|
+
availability: checkoutRecoveryOptionAvailability(option.availability)
|
|
131471
|
+
} : option), [
|
|
131124
131472
|
currentEvent,
|
|
131125
131473
|
selectedAttendanceMode,
|
|
131126
|
-
eligibility
|
|
131474
|
+
eligibility,
|
|
131475
|
+
checkoutRecovery
|
|
131127
131476
|
]);
|
|
131128
131477
|
const singleSelectedPricingOptionId = getSingleSelectedPricingOptionId(normalizedSelectedTicketLines);
|
|
131129
131478
|
const selectedTicketType = useMemo(() => findSelectedTicketType({
|
|
@@ -131147,8 +131496,12 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
131147
131496
|
const event = currentEvent;
|
|
131148
131497
|
if (!usesTieredPricing(event)) return false;
|
|
131149
131498
|
if ((event.deliveryMode ?? "in_person") === "hybrid" && !selectedAttendanceMode) return false;
|
|
131150
|
-
return !canJoinEventWaitlist(event, { attendanceMode: selectedAttendanceMode });
|
|
131151
|
-
}, [
|
|
131499
|
+
return checkoutRecovery || !canJoinEventWaitlist(event, { attendanceMode: selectedAttendanceMode });
|
|
131500
|
+
}, [
|
|
131501
|
+
currentEvent,
|
|
131502
|
+
selectedAttendanceMode,
|
|
131503
|
+
checkoutRecovery
|
|
131504
|
+
]);
|
|
131152
131505
|
const hasValidTicketSelection = hasValidPricingOptionSelection({
|
|
131153
131506
|
selectionRequired: ticketTypeSelectionRequired,
|
|
131154
131507
|
lines: normalizedSelectedTicketLines,
|
|
@@ -131352,6 +131705,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
131352
131705
|
guests,
|
|
131353
131706
|
discountCode: discountUi.discountCode,
|
|
131354
131707
|
claimToken: waitlistClaim.token,
|
|
131708
|
+
waitlistEntryId: waitlistClaim.entryId,
|
|
131355
131709
|
setPendingRegistrationReference,
|
|
131356
131710
|
setStep,
|
|
131357
131711
|
setRegistrationResult: (result) => setRegistrationResult(result),
|
|
@@ -131414,6 +131768,8 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
131414
131768
|
scopedEvents,
|
|
131415
131769
|
preSelectedEvent,
|
|
131416
131770
|
hasPreSelectedContext,
|
|
131771
|
+
checkoutRecovery,
|
|
131772
|
+
startCheckoutRecovery,
|
|
131417
131773
|
step,
|
|
131418
131774
|
setStep,
|
|
131419
131775
|
selectedEvent,
|
|
@@ -131617,6 +131973,51 @@ function getMagicLinkErrorMessage(error) {
|
|
|
131617
131973
|
return error instanceof Error ? error.message : "Failed to send. Please try again.";
|
|
131618
131974
|
}
|
|
131619
131975
|
//#endregion
|
|
131976
|
+
//#region ../blocks/src/system/runtime/nodes/event-registration/ErrorStep.tsx
|
|
131977
|
+
/**
|
|
131978
|
+
* Error Step
|
|
131979
|
+
*
|
|
131980
|
+
* Displays an error message with a retry button when registration fails.
|
|
131981
|
+
*/
|
|
131982
|
+
const labels = {
|
|
131983
|
+
none: "",
|
|
131984
|
+
retry: "Try again",
|
|
131985
|
+
places: "Choose places",
|
|
131986
|
+
start: "Start again",
|
|
131987
|
+
details: "Check my details",
|
|
131988
|
+
"payment-options": "View payment options",
|
|
131989
|
+
"payment-status": "Check payment status",
|
|
131990
|
+
portal: "View my bookings",
|
|
131991
|
+
event: "View event"
|
|
131992
|
+
};
|
|
131993
|
+
const ErrorStep = ({ message, onRetry, action = "retry", canJoinWaitlist = false }) => {
|
|
131994
|
+
const offerWaitlist = action === "places" && canJoinWaitlist;
|
|
131995
|
+
return /* @__PURE__ */ jsx(TerminalPanel, {
|
|
131996
|
+
tone: "error",
|
|
131997
|
+
className: "er-center",
|
|
131998
|
+
titleClassName: "er-title--lg er-message",
|
|
131999
|
+
icon: /* @__PURE__ */ jsx(StateIcon, {
|
|
132000
|
+
variant: "error",
|
|
132001
|
+
children: /* @__PURE__ */ jsx(CrossIcon, {})
|
|
132002
|
+
}),
|
|
132003
|
+
title: "We couldn’t complete your booking",
|
|
132004
|
+
body: /* @__PURE__ */ jsx("p", {
|
|
132005
|
+
className: "er-text--muted er-message",
|
|
132006
|
+
children: offerWaitlist ? "Sorry, this event is now full. You can join the waiting list, and we’ll email you if a place becomes available." : message
|
|
132007
|
+
}),
|
|
132008
|
+
actions: action === "none" ? void 0 : action === "portal" || action === "payment-status" ? /* @__PURE__ */ jsx("a", {
|
|
132009
|
+
href: "/portal",
|
|
132010
|
+
className: "er-retry-btn",
|
|
132011
|
+
children: labels[action]
|
|
132012
|
+
}) : /* @__PURE__ */ jsx("button", {
|
|
132013
|
+
type: "button",
|
|
132014
|
+
onClick: onRetry,
|
|
132015
|
+
className: "er-retry-btn",
|
|
132016
|
+
children: offerWaitlist ? "Join the waiting list" : labels[action]
|
|
132017
|
+
})
|
|
132018
|
+
});
|
|
132019
|
+
};
|
|
132020
|
+
//#endregion
|
|
131620
132021
|
//#region ../blocks/src/system/runtime/nodes/event-registration/EventRegistrationSummaryBar.tsx
|
|
131621
132022
|
function getScheduleSummary(wizard, summaryEvent) {
|
|
131622
132023
|
if (summaryEvent.registrationSubject.kind !== "wholeSeries") {
|
|
@@ -131900,7 +132301,7 @@ function SelectTicketsActions(props) {
|
|
|
131900
132301
|
const currentEvent = wizard.selectedEvent ?? wizard.preSelectedEvent;
|
|
131901
132302
|
const registrationOptionsPending = wizard.registrationOptionsState.tag === "idle" || wizard.registrationOptionsState.tag === "loading";
|
|
131902
132303
|
const registrationOptionsFailed = wizard.registrationOptionsState.tag === "failed";
|
|
131903
|
-
const isSoldOutWithoutWaitlist = !hasWaitlistClaim && isFullWithNoWaitlist(currentEvent, wizard.selectedAttendanceMode);
|
|
132304
|
+
const isSoldOutWithoutWaitlist = !wizard.checkoutRecovery && !hasWaitlistClaim && isFullWithNoWaitlist(currentEvent, wizard.selectedAttendanceMode);
|
|
131904
132305
|
const isCheckingExistingRegistration = wizard.portalAuthState === "authenticated" && wizard.existingRegistrationLoading;
|
|
131905
132306
|
const hasExistingRegistration = isExistingRegistrationBlocking$1(wizard);
|
|
131906
132307
|
const ticketTypeSelectionBlocked = wizard.ticketTypeSelectionRequired && !wizard.hasValidTicketSelection;
|
|
@@ -132490,6 +132891,31 @@ function resolveTicketSelectionPricing(event) {
|
|
|
132490
132891
|
currency: event ? publicEventPricingCurrency(event.pricing) : null
|
|
132491
132892
|
};
|
|
132492
132893
|
}
|
|
132894
|
+
function CheckoutRecoveryEntry(props) {
|
|
132895
|
+
return props.onContinue ? /* @__PURE__ */ jsx("button", {
|
|
132896
|
+
type: "button",
|
|
132897
|
+
className: "er-back-btn",
|
|
132898
|
+
onClick: props.onContinue,
|
|
132899
|
+
children: "Continue an existing booking"
|
|
132900
|
+
}) : null;
|
|
132901
|
+
}
|
|
132902
|
+
function getTicketSelectionCapacity(event, attendanceMode, checkoutRecovery) {
|
|
132903
|
+
if (checkoutRecovery) return {
|
|
132904
|
+
availableSpots: null,
|
|
132905
|
+
isSoldOut: false,
|
|
132906
|
+
canJoinWaitlist: false,
|
|
132907
|
+
eventAvailabilityLabel: null
|
|
132908
|
+
};
|
|
132909
|
+
const source = event ? selectEventCapacitySource(event, attendanceMode) : null;
|
|
132910
|
+
const availability = source ? getEventAvailability(source) : null;
|
|
132911
|
+
const canJoinWaitlist = source ? canJoinEventWaitlist(source) : false;
|
|
132912
|
+
return {
|
|
132913
|
+
availableSpots: availability?.available,
|
|
132914
|
+
isSoldOut: availability?.isFull ?? false,
|
|
132915
|
+
canJoinWaitlist,
|
|
132916
|
+
eventAvailabilityLabel: !canJoinWaitlist && source ? formatRemainingPlaces(source) : null
|
|
132917
|
+
};
|
|
132918
|
+
}
|
|
132493
132919
|
/**
|
|
132494
132920
|
* Ticket Selection Step
|
|
132495
132921
|
*
|
|
@@ -132498,15 +132924,11 @@ function resolveTicketSelectionPricing(event) {
|
|
|
132498
132924
|
*
|
|
132499
132925
|
* Can use either a full PublicEvent or just occurrence context (when on event page).
|
|
132500
132926
|
*/
|
|
132501
|
-
const TicketSelectionStep = ({ event, occurrenceContext: _occurrenceContext, selectedAttendanceMode = null, onAttendanceModeChange, ticketsCount, maxTickets, visibleTicketTypes: visibleTicketTypesOverride, ticketSelections = [], onTicketSelectionsChange, slidingScale = null, selectedSlidingAmountInput = "", slidingScaleSelectionMessage = null, onSlidingAmountChange, onTicketsChange, bookingUnit = { kind: "ticket" } }) => {
|
|
132927
|
+
const TicketSelectionStep = ({ event, occurrenceContext: _occurrenceContext, selectedAttendanceMode = null, onAttendanceModeChange, ticketsCount, maxTickets, visibleTicketTypes: visibleTicketTypesOverride, ticketSelections = [], onTicketSelectionsChange, slidingScale = null, selectedSlidingAmountInput = "", slidingScaleSelectionMessage = null, onSlidingAmountChange, onTicketsChange, bookingUnit = { kind: "ticket" }, checkoutRecovery = false, onCheckoutRecovery }) => {
|
|
132502
132928
|
const unit = bookingUnit.kind;
|
|
132503
132929
|
const deliveryMode = event?.deliveryMode ?? "in_person";
|
|
132504
132930
|
const attendanceModes = event?.attendanceModes ?? [];
|
|
132505
|
-
const
|
|
132506
|
-
const availability = capacitySource ? getEventAvailability(capacitySource) : null;
|
|
132507
|
-
const availableSpots = availability?.available;
|
|
132508
|
-
const isSoldOut = availability?.isFull ?? false;
|
|
132509
|
-
const canJoinWaitlist = capacitySource ? canJoinEventWaitlist(capacitySource) : false;
|
|
132931
|
+
const { availableSpots, isSoldOut, canJoinWaitlist, eventAvailabilityLabel } = getTicketSelectionCapacity(event, selectedAttendanceMode, checkoutRecovery);
|
|
132510
132932
|
const { mode: eventPricingMode, currency: eventPricingCurrency } = resolveTicketSelectionPricing(event);
|
|
132511
132933
|
const usesTicketTypes = eventPricingMode === "tiered" && !canJoinWaitlist;
|
|
132512
132934
|
const visibleTicketTypes = usesTicketTypes ? visibleTicketTypesOverride ?? getVisibleTicketTypes({
|
|
@@ -132525,7 +132947,6 @@ const TicketSelectionStep = ({ event, occurrenceContext: _occurrenceContext, sel
|
|
|
132525
132947
|
selectedTicketTypeRemainingCapacity: implicitTicketType?.availability.remainingPlaces ?? null,
|
|
132526
132948
|
hasSelectedTicketType: implicitTicketType !== null
|
|
132527
132949
|
});
|
|
132528
|
-
const eventAvailabilityLabel = !canJoinWaitlist && capacitySource ? formatRemainingPlaces(capacitySource) : null;
|
|
132529
132950
|
if (deliveryMode === "hybrid" && !selectedAttendanceMode) return /* @__PURE__ */ jsxs("div", {
|
|
132530
132951
|
className: "rb-reg-stack er-stack",
|
|
132531
132952
|
children: [
|
|
@@ -132546,13 +132967,17 @@ const TicketSelectionStep = ({ event, occurrenceContext: _occurrenceContext, sel
|
|
|
132546
132967
|
});
|
|
132547
132968
|
if (isSoldOut && !canJoinWaitlist) return /* @__PURE__ */ jsxs("div", {
|
|
132548
132969
|
className: "rb-reg-stack er-stack",
|
|
132549
|
-
children: [
|
|
132550
|
-
|
|
132551
|
-
|
|
132552
|
-
|
|
132553
|
-
|
|
132554
|
-
|
|
132555
|
-
|
|
132970
|
+
children: [
|
|
132971
|
+
/* @__PURE__ */ jsx("h3", {
|
|
132972
|
+
className: "er-title",
|
|
132973
|
+
children: "Sold out"
|
|
132974
|
+
}),
|
|
132975
|
+
/* @__PURE__ */ jsx("p", {
|
|
132976
|
+
className: "er-text er-text--muted",
|
|
132977
|
+
children: "Sorry you missed out! This event is fully booked."
|
|
132978
|
+
}),
|
|
132979
|
+
/* @__PURE__ */ jsx(CheckoutRecoveryEntry, { onContinue: onCheckoutRecovery })
|
|
132980
|
+
]
|
|
132556
132981
|
});
|
|
132557
132982
|
if (!eventPricingCurrency) return /* @__PURE__ */ jsx("div", {
|
|
132558
132983
|
className: "rb-reg-stack er-stack",
|
|
@@ -132620,9 +133045,13 @@ const TicketSelectionStep = ({ event, occurrenceContext: _occurrenceContext, sel
|
|
|
132620
133045
|
})]
|
|
132621
133046
|
})
|
|
132622
133047
|
] }),
|
|
132623
|
-
canJoinWaitlist && /* @__PURE__ */ jsx("p", {
|
|
133048
|
+
canJoinWaitlist && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("p", {
|
|
132624
133049
|
className: "er-text er-text--muted",
|
|
132625
133050
|
children: "This event is currently full. Continue to join the waitlist if a place opens up."
|
|
133051
|
+
}), /* @__PURE__ */ jsx(CheckoutRecoveryEntry, { onContinue: onCheckoutRecovery })] }),
|
|
133052
|
+
checkoutRecovery && /* @__PURE__ */ jsx("p", {
|
|
133053
|
+
className: "er-text er-text--muted",
|
|
133054
|
+
children: "Enter the details from your earlier booking. We’ll check your checkout before continuing to payment."
|
|
132626
133055
|
})
|
|
132627
133056
|
]
|
|
132628
133057
|
});
|
|
@@ -133530,12 +133959,14 @@ function EventRegistrationWizardContent(props) {
|
|
|
133530
133959
|
onBookForSomeoneElse: wizard.handleBookForSomeoneElse
|
|
133531
133960
|
}), /* @__PURE__ */ jsx(TicketSelectionStep, {
|
|
133532
133961
|
event: wizard.selectedEvent,
|
|
133962
|
+
checkoutRecovery: wizard.checkoutRecovery,
|
|
133963
|
+
onCheckoutRecovery: canRecoverEventCheckout(wizard.selectedEvent) ? wizard.startCheckoutRecovery : void 0,
|
|
133533
133964
|
occurrenceContext: wizard.occurrenceContext,
|
|
133534
133965
|
selectedAttendanceMode: wizard.selectedAttendanceMode,
|
|
133535
133966
|
onAttendanceModeChange: wizard.setSelectedAttendanceMode,
|
|
133536
133967
|
ticketsCount: wizard.ticketsCount,
|
|
133537
133968
|
maxTickets: wizard.maxTicketsNum,
|
|
133538
|
-
visibleTicketTypes: wizard.
|
|
133969
|
+
visibleTicketTypes: wizard.visibleTicketTypes,
|
|
133539
133970
|
ticketSelections: wizard.selectedTicketLines,
|
|
133540
133971
|
onTicketSelectionsChange: wizard.setSelectedTicketLines,
|
|
133541
133972
|
slidingScale: wizard.selectedEventSlidingScale,
|
|
@@ -133554,66 +133985,6 @@ function EventRegistrationWizardContent(props) {
|
|
|
133554
133985
|
}
|
|
133555
133986
|
}
|
|
133556
133987
|
//#endregion
|
|
133557
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/StepIndicator.tsx
|
|
133558
|
-
/**
|
|
133559
|
-
* Step indicator component for the event registration wizard.
|
|
133560
|
-
* Thin wrapper around the shared StepIndicator: styled by the shared
|
|
133561
|
-
* registration-surface classes, with 'er'-prefixed classes kept in the
|
|
133562
|
-
* markup as the stable hook surface for per-site theme CSS.
|
|
133563
|
-
*/
|
|
133564
|
-
function StepIndicator(props) {
|
|
133565
|
-
return /* @__PURE__ */ jsx(StepIndicator$1, {
|
|
133566
|
-
...props,
|
|
133567
|
-
classPrefix: "er",
|
|
133568
|
-
emitSharedClasses: true
|
|
133569
|
-
});
|
|
133570
|
-
}
|
|
133571
|
-
//#endregion
|
|
133572
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/ErrorStep.tsx
|
|
133573
|
-
/**
|
|
133574
|
-
* Error Step
|
|
133575
|
-
*
|
|
133576
|
-
* Displays an error message with a retry button when registration fails.
|
|
133577
|
-
*/
|
|
133578
|
-
const labels = {
|
|
133579
|
-
none: "",
|
|
133580
|
-
retry: "Try again",
|
|
133581
|
-
places: "Choose places",
|
|
133582
|
-
start: "Start again",
|
|
133583
|
-
details: "Check my details",
|
|
133584
|
-
"payment-options": "View payment options",
|
|
133585
|
-
"payment-status": "Check payment status",
|
|
133586
|
-
portal: "View my bookings",
|
|
133587
|
-
event: "View event"
|
|
133588
|
-
};
|
|
133589
|
-
const ErrorStep = ({ message, onRetry, action = "retry", canJoinWaitlist = false }) => {
|
|
133590
|
-
const offerWaitlist = action === "places" && canJoinWaitlist;
|
|
133591
|
-
return /* @__PURE__ */ jsx(TerminalPanel, {
|
|
133592
|
-
tone: "error",
|
|
133593
|
-
className: "er-center",
|
|
133594
|
-
titleClassName: "er-title--lg er-message",
|
|
133595
|
-
icon: /* @__PURE__ */ jsx(StateIcon, {
|
|
133596
|
-
variant: "error",
|
|
133597
|
-
children: /* @__PURE__ */ jsx(CrossIcon, {})
|
|
133598
|
-
}),
|
|
133599
|
-
title: "We couldn’t complete your booking",
|
|
133600
|
-
body: /* @__PURE__ */ jsx("p", {
|
|
133601
|
-
className: "er-text--muted er-message",
|
|
133602
|
-
children: offerWaitlist ? "Sorry, this event is now full. You can join the waiting list, and we’ll email you if a place becomes available." : message
|
|
133603
|
-
}),
|
|
133604
|
-
actions: action === "none" ? void 0 : action === "portal" || action === "payment-status" ? /* @__PURE__ */ jsx("a", {
|
|
133605
|
-
href: "/portal",
|
|
133606
|
-
className: "er-retry-btn",
|
|
133607
|
-
children: labels[action]
|
|
133608
|
-
}) : /* @__PURE__ */ jsx("button", {
|
|
133609
|
-
type: "button",
|
|
133610
|
-
onClick: onRetry,
|
|
133611
|
-
className: "er-retry-btn",
|
|
133612
|
-
children: offerWaitlist ? "Join the waiting list" : labels[action]
|
|
133613
|
-
})
|
|
133614
|
-
});
|
|
133615
|
-
};
|
|
133616
|
-
//#endregion
|
|
133617
133988
|
//#region ../blocks/src/system/runtime/nodes/event-registration/PaymentFailedStep.tsx
|
|
133618
133989
|
/**
|
|
133619
133990
|
* Payment Failed Step
|
|
@@ -133644,6 +134015,21 @@ const PaymentFailedStep = ({ onRetry }) => {
|
|
|
133644
134015
|
});
|
|
133645
134016
|
};
|
|
133646
134017
|
//#endregion
|
|
134018
|
+
//#region ../blocks/src/system/runtime/nodes/event-registration/StepIndicator.tsx
|
|
134019
|
+
/**
|
|
134020
|
+
* Step indicator component for the event registration wizard.
|
|
134021
|
+
* Thin wrapper around the shared StepIndicator: styled by the shared
|
|
134022
|
+
* registration-surface classes, with 'er'-prefixed classes kept in the
|
|
134023
|
+
* markup as the stable hook surface for per-site theme CSS.
|
|
134024
|
+
*/
|
|
134025
|
+
function StepIndicator(props) {
|
|
134026
|
+
return /* @__PURE__ */ jsx(StepIndicator$1, {
|
|
134027
|
+
...props,
|
|
134028
|
+
classPrefix: "er",
|
|
134029
|
+
emitSharedClasses: true
|
|
134030
|
+
});
|
|
134031
|
+
}
|
|
134032
|
+
//#endregion
|
|
133647
134033
|
//#region ../blocks/src/system/runtime/nodes/event-registration/SuccessStep.tsx
|
|
133648
134034
|
/**
|
|
133649
134035
|
* Success Step
|
|
@@ -133916,7 +134302,8 @@ function EventRegistrationSurface(props) {
|
|
|
133916
134302
|
}), /* @__PURE__ */ jsx(EventRegistrationTerminalState, {
|
|
133917
134303
|
wizard,
|
|
133918
134304
|
supportEmail: props.supportEmail,
|
|
133919
|
-
successMessage: props.successMessage
|
|
134305
|
+
successMessage: props.successMessage,
|
|
134306
|
+
buttonClass: props.buttonClass
|
|
133920
134307
|
})]
|
|
133921
134308
|
});
|
|
133922
134309
|
}
|
|
@@ -134389,6 +134776,84 @@ function PastOccurrenceNotice(props) {
|
|
|
134389
134776
|
});
|
|
134390
134777
|
}
|
|
134391
134778
|
//#endregion
|
|
134779
|
+
//#region ../blocks/src/system/runtime/nodes/event-registration/useEventSourceRecovery.ts
|
|
134780
|
+
const RECOVERY_DELAYS_MS = [
|
|
134781
|
+
0,
|
|
134782
|
+
250,
|
|
134783
|
+
750
|
|
134784
|
+
];
|
|
134785
|
+
const defaultRecoveryDeps = {
|
|
134786
|
+
useApi: useBlockApi,
|
|
134787
|
+
wait: waitForRetry
|
|
134788
|
+
};
|
|
134789
|
+
function useEventSourceRecovery(source, deps = defaultRecoveryDeps) {
|
|
134790
|
+
const api = deps.useApi();
|
|
134791
|
+
const wait = deps.wait;
|
|
134792
|
+
const [cycle, setCycle] = useState(0);
|
|
134793
|
+
const [state, setState] = useState(() => source.kind === "loaded" ? {
|
|
134794
|
+
kind: "ready",
|
|
134795
|
+
events: source.events
|
|
134796
|
+
} : { kind: "loading" });
|
|
134797
|
+
const retry = useCallback(() => {
|
|
134798
|
+
setState({ kind: "loading" });
|
|
134799
|
+
setCycle((value) => value + 1);
|
|
134800
|
+
}, []);
|
|
134801
|
+
useEffect(() => {
|
|
134802
|
+
if (source.kind === "loaded") {
|
|
134803
|
+
setState({
|
|
134804
|
+
kind: "ready",
|
|
134805
|
+
events: source.events
|
|
134806
|
+
});
|
|
134807
|
+
return;
|
|
134808
|
+
}
|
|
134809
|
+
if (!source.request) {
|
|
134810
|
+
setState({
|
|
134811
|
+
kind: "exhausted",
|
|
134812
|
+
retry
|
|
134813
|
+
});
|
|
134814
|
+
return;
|
|
134815
|
+
}
|
|
134816
|
+
const controller = new AbortController();
|
|
134817
|
+
const isCurrent = () => !controller.signal.aborted;
|
|
134818
|
+
(async () => {
|
|
134819
|
+
for (const delayMs of RECOVERY_DELAYS_MS) try {
|
|
134820
|
+
await wait(delayMs, controller.signal);
|
|
134821
|
+
const events = await api.getPublicEvents(source.request ?? void 0);
|
|
134822
|
+
if (isCurrent()) setState({
|
|
134823
|
+
kind: "ready",
|
|
134824
|
+
events
|
|
134825
|
+
});
|
|
134826
|
+
return;
|
|
134827
|
+
} catch {
|
|
134828
|
+
if (!isCurrent()) return;
|
|
134829
|
+
}
|
|
134830
|
+
if (isCurrent()) setState({
|
|
134831
|
+
kind: "exhausted",
|
|
134832
|
+
retry
|
|
134833
|
+
});
|
|
134834
|
+
})();
|
|
134835
|
+
return () => controller.abort();
|
|
134836
|
+
}, [
|
|
134837
|
+
api,
|
|
134838
|
+
cycle,
|
|
134839
|
+
retry,
|
|
134840
|
+
source,
|
|
134841
|
+
wait
|
|
134842
|
+
]);
|
|
134843
|
+
return state;
|
|
134844
|
+
}
|
|
134845
|
+
function waitForRetry(milliseconds, signal) {
|
|
134846
|
+
if (signal.aborted) return Promise.reject(/* @__PURE__ */ new Error("Recovery aborted"));
|
|
134847
|
+
if (milliseconds === 0) return Promise.resolve();
|
|
134848
|
+
return new Promise((resolve, reject) => {
|
|
134849
|
+
const timeout = setTimeout(resolve, milliseconds);
|
|
134850
|
+
signal.addEventListener("abort", () => {
|
|
134851
|
+
clearTimeout(timeout);
|
|
134852
|
+
reject(/* @__PURE__ */ new Error("Recovery aborted"));
|
|
134853
|
+
}, { once: true });
|
|
134854
|
+
});
|
|
134855
|
+
}
|
|
134856
|
+
//#endregion
|
|
134392
134857
|
//#region ../blocks/src/system/runtime/nodes/event-registration.client.tsx
|
|
134393
134858
|
function toEventRegistrationClientProps(props, display) {
|
|
134394
134859
|
return {
|
|
@@ -134422,8 +134887,71 @@ const EventRegistrationIslandClient = (props) => {
|
|
|
134422
134887
|
title: props.render.display.titleText,
|
|
134423
134888
|
body: props.render.display.bodyText
|
|
134424
134889
|
});
|
|
134425
|
-
return /* @__PURE__ */ jsx(
|
|
134890
|
+
return /* @__PURE__ */ jsx(RecoverableEventRegistrationClient, {
|
|
134891
|
+
props,
|
|
134892
|
+
display: props.render.display
|
|
134893
|
+
});
|
|
134426
134894
|
};
|
|
134895
|
+
function RecoverableEventRegistrationClient({ props, display }) {
|
|
134896
|
+
const recovery = useEventSourceRecovery(props.render.hydration.eventSource);
|
|
134897
|
+
if (recovery.kind === "loading") return /* @__PURE__ */ jsxs("div", {
|
|
134898
|
+
id: EVENT_REGISTRATION_ANCHOR_ID,
|
|
134899
|
+
className: "rb-reg-surface er-container er-registration-shell",
|
|
134900
|
+
"aria-busy": "true",
|
|
134901
|
+
role: "status",
|
|
134902
|
+
children: [
|
|
134903
|
+
/* @__PURE__ */ jsx("p", {
|
|
134904
|
+
className: "er-registration-shell__eyebrow",
|
|
134905
|
+
children: "Registration"
|
|
134906
|
+
}),
|
|
134907
|
+
/* @__PURE__ */ jsx("h3", {
|
|
134908
|
+
className: "er-title er-registration-shell__title",
|
|
134909
|
+
children: display.titleText
|
|
134910
|
+
}),
|
|
134911
|
+
/* @__PURE__ */ jsx("p", {
|
|
134912
|
+
className: "er-text er-text--muted",
|
|
134913
|
+
children: "Loading event dates…"
|
|
134914
|
+
}),
|
|
134915
|
+
/* @__PURE__ */ jsxs("div", {
|
|
134916
|
+
className: "er-event-grid er-registration-shell__cards",
|
|
134917
|
+
"aria-hidden": "true",
|
|
134918
|
+
children: [/* @__PURE__ */ jsx("div", { className: "er-event-card er-registration-shell__card" }), /* @__PURE__ */ jsx("div", { className: "er-event-card er-registration-shell__card" })]
|
|
134919
|
+
})
|
|
134920
|
+
]
|
|
134921
|
+
});
|
|
134922
|
+
if (recovery.kind === "exhausted") return /* @__PURE__ */ jsxs("div", {
|
|
134923
|
+
id: EVENT_REGISTRATION_ANCHOR_ID,
|
|
134924
|
+
className: "rb-reg-surface er-container er-registration-shell",
|
|
134925
|
+
role: "alert",
|
|
134926
|
+
children: [/* @__PURE__ */ jsx("p", { children: "We couldn’t load the event dates. Please try again." }), /* @__PURE__ */ jsx("button", {
|
|
134927
|
+
type: "button",
|
|
134928
|
+
className: themeButtonClassName({
|
|
134929
|
+
variant: props.render.hydration.buttonVariant ?? "primary",
|
|
134930
|
+
size: "md"
|
|
134931
|
+
}),
|
|
134932
|
+
onClick: recovery.retry,
|
|
134933
|
+
children: "Try again"
|
|
134934
|
+
})]
|
|
134935
|
+
});
|
|
134936
|
+
const events = resolveEventRegistrationScopedEvents(recovery.events, {
|
|
134937
|
+
occurrenceContext: props.render.hydration.occurrenceContext,
|
|
134938
|
+
subject: props.render.hydration.subject
|
|
134939
|
+
});
|
|
134940
|
+
const recoveredDisplay = buildEventRegistrationDisplayFromScopedEvents({
|
|
134941
|
+
...props.render.hydration,
|
|
134942
|
+
events,
|
|
134943
|
+
className: display.className,
|
|
134944
|
+
buttonText: display.summaryButtonText
|
|
134945
|
+
}, events);
|
|
134946
|
+
if (recoveredDisplay.state === "registration-closed") return /* @__PURE__ */ jsx(RegistrationClosedState, {
|
|
134947
|
+
title: recoveredDisplay.titleText,
|
|
134948
|
+
body: recoveredDisplay.bodyText
|
|
134949
|
+
});
|
|
134950
|
+
return /* @__PURE__ */ jsx(EventRegistrationClient, {
|
|
134951
|
+
...toEventRegistrationClientProps(props, display),
|
|
134952
|
+
events
|
|
134953
|
+
});
|
|
134954
|
+
}
|
|
134427
134955
|
//#endregion
|
|
134428
134956
|
//#region ../blocks/src/system/runtime/nodes/shared/LeafletStaticMap.tsx
|
|
134429
134957
|
/**
|
|
@@ -142273,6 +142801,11 @@ function NewsletterFormClient({ render }) {
|
|
|
142273
142801
|
const api = useBlockApi();
|
|
142274
142802
|
const [submissionState, dispatchSubmission] = useReducer(newsletterFormSubmissionReducer, initialNewsletterFormSubmissionState);
|
|
142275
142803
|
const [altchaSolution, setAltchaSolution] = useState(null);
|
|
142804
|
+
const successRef = useRef(null);
|
|
142805
|
+
const succeeded = isNewsletterFormSuccess(submissionState);
|
|
142806
|
+
useEffect(() => {
|
|
142807
|
+
if (succeeded) successRef.current?.focus();
|
|
142808
|
+
}, [succeeded]);
|
|
142276
142809
|
const showSpamProtection = render.hydration.spamProtectionEnabled ?? isSpamProtectionEnabled();
|
|
142277
142810
|
const fields = render.display.fields;
|
|
142278
142811
|
const handleSubmit = async (e) => {
|
|
@@ -142312,7 +142845,7 @@ function NewsletterFormClient({ render }) {
|
|
|
142312
142845
|
if (render.hydration.setupRevision === null || render.display.availability === "unavailable") {
|
|
142313
142846
|
dispatchSubmission({
|
|
142314
142847
|
type: "failed",
|
|
142315
|
-
error: newsletterFormError(
|
|
142848
|
+
error: newsletterFormError(SIGNUPS_PAUSED_MESSAGE)
|
|
142316
142849
|
});
|
|
142317
142850
|
return;
|
|
142318
142851
|
}
|
|
@@ -142320,7 +142853,7 @@ function NewsletterFormClient({ render }) {
|
|
|
142320
142853
|
if (visitorSelection === null) {
|
|
142321
142854
|
dispatchSubmission({
|
|
142322
142855
|
type: "failed",
|
|
142323
|
-
error:
|
|
142856
|
+
error: newsletterFieldError(TOPIC_CHOICE_FIELD_ID, "Choose at least one email topic.")
|
|
142324
142857
|
});
|
|
142325
142858
|
return;
|
|
142326
142859
|
}
|
|
@@ -142352,71 +142885,27 @@ function NewsletterFormClient({ render }) {
|
|
|
142352
142885
|
} catch (err) {
|
|
142353
142886
|
dispatchSubmission({
|
|
142354
142887
|
type: "failed",
|
|
142355
|
-
error: newsletterFormError(err
|
|
142888
|
+
error: newsletterFormError(transportFailureMessage(err))
|
|
142356
142889
|
});
|
|
142357
142890
|
}
|
|
142358
142891
|
};
|
|
142359
|
-
const
|
|
142360
|
-
const inputId = `newsletter_${field.id}`;
|
|
142361
|
-
const fieldError = getNewsletterSubmissionFieldError(submissionState, field.id);
|
|
142362
|
-
const fieldErrorId = `${inputId}-error`;
|
|
142363
|
-
const validationProps = getFieldValidationControlProps({
|
|
142364
|
-
message: fieldError,
|
|
142365
|
-
messageId: fieldErrorId
|
|
142366
|
-
});
|
|
142367
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
142368
|
-
className: "fb-field newsletter-field",
|
|
142369
|
-
children: [
|
|
142370
|
-
/* @__PURE__ */ jsxs("label", {
|
|
142371
|
-
htmlFor: inputId,
|
|
142372
|
-
className: "form-label",
|
|
142373
|
-
children: [field.label, field.required && /* @__PURE__ */ jsx("span", {
|
|
142374
|
-
className: "newsletter-required",
|
|
142375
|
-
"aria-hidden": "true",
|
|
142376
|
-
children: "*"
|
|
142377
|
-
})]
|
|
142378
|
-
}),
|
|
142379
|
-
/* @__PURE__ */ jsx("input", {
|
|
142380
|
-
id: inputId,
|
|
142381
|
-
name: field.id,
|
|
142382
|
-
type: field.type,
|
|
142383
|
-
required: field.required,
|
|
142384
|
-
placeholder: field.placeholder,
|
|
142385
|
-
className: "form-input",
|
|
142386
|
-
autoComplete: field.type === "email" ? "email" : void 0,
|
|
142387
|
-
disabled: isNewsletterFormSubmitting(submissionState),
|
|
142388
|
-
...validationProps
|
|
142389
|
-
}),
|
|
142390
|
-
fieldError && /* @__PURE__ */ jsx(FieldValidationMessage, {
|
|
142391
|
-
id: fieldErrorId,
|
|
142392
|
-
className: "fb-error",
|
|
142393
|
-
children: fieldError
|
|
142394
|
-
})
|
|
142395
|
-
]
|
|
142396
|
-
}, field.id);
|
|
142397
|
-
};
|
|
142892
|
+
const submitting = isNewsletterFormSubmitting(submissionState);
|
|
142398
142893
|
const formError = getNewsletterSubmissionFormError(submissionState);
|
|
142399
|
-
if (
|
|
142400
|
-
|
|
142401
|
-
|
|
142402
|
-
|
|
142403
|
-
|
|
142404
|
-
|
|
142405
|
-
|
|
142406
|
-
|
|
142407
|
-
|
|
142408
|
-
|
|
142409
|
-
|
|
142410
|
-
}
|
|
142894
|
+
if (succeeded) return /* @__PURE__ */ jsx("div", {
|
|
142895
|
+
ref: successRef,
|
|
142896
|
+
tabIndex: -1,
|
|
142897
|
+
className: clsx("newsletter-form", "newsletter-success", render.display.className ?? void 0),
|
|
142898
|
+
children: /* @__PURE__ */ jsx(FeedbackMessage, {
|
|
142899
|
+
tone: "success",
|
|
142900
|
+
className: "fb-success",
|
|
142901
|
+
role: "status",
|
|
142902
|
+
children: getNewsletterSuccessOutcome(submissionState) === "confirmation_required" ? "Please check your inbox to confirm your signup." : render.display.successMessage
|
|
142903
|
+
})
|
|
142904
|
+
});
|
|
142411
142905
|
if (render.display.availability === "unavailable") return /* @__PURE__ */ jsx(UnavailableNewsletterForm, { className: render.display.className });
|
|
142412
|
-
return /* @__PURE__ */
|
|
142906
|
+
return /* @__PURE__ */ jsx("div", {
|
|
142413
142907
|
className: clsx("newsletter-form", render.display.className ?? void 0),
|
|
142414
|
-
children:
|
|
142415
|
-
tone: "error",
|
|
142416
|
-
className: "fb-error",
|
|
142417
|
-
role: "alert",
|
|
142418
|
-
children: formError
|
|
142419
|
-
}), /* @__PURE__ */ jsxs("form", {
|
|
142908
|
+
children: /* @__PURE__ */ jsxs("form", {
|
|
142420
142909
|
onSubmit: handleSubmit,
|
|
142421
142910
|
className: "fb-form",
|
|
142422
142911
|
children: [
|
|
@@ -142431,18 +142920,15 @@ function NewsletterFormClient({ render }) {
|
|
|
142431
142920
|
/* @__PURE__ */ jsxs("div", {
|
|
142432
142921
|
className: "newsletter-form-fields",
|
|
142433
142922
|
children: [
|
|
142434
|
-
fields.map(
|
|
142435
|
-
|
|
142436
|
-
|
|
142437
|
-
|
|
142438
|
-
|
|
142439
|
-
|
|
142440
|
-
|
|
142441
|
-
|
|
142442
|
-
|
|
142443
|
-
disabled: isNewsletterFormSubmitting(submissionState)
|
|
142444
|
-
}), choice.label]
|
|
142445
|
-
}, choice.id))]
|
|
142923
|
+
fields.map((field) => /* @__PURE__ */ jsx(NewsletterField, {
|
|
142924
|
+
field,
|
|
142925
|
+
submitting,
|
|
142926
|
+
error: getNewsletterSubmissionFieldError(submissionState, field.id)
|
|
142927
|
+
}, field.id)),
|
|
142928
|
+
render.hydration.choicePresentation === "visitor_choice" ? /* @__PURE__ */ jsx(NewsletterTopicChoices, {
|
|
142929
|
+
choices: render.display.choices,
|
|
142930
|
+
submitting,
|
|
142931
|
+
error: getNewsletterSubmissionFieldError(submissionState, TOPIC_CHOICE_FIELD_ID)
|
|
142446
142932
|
}) : null,
|
|
142447
142933
|
showSpamProtection && /* @__PURE__ */ jsx("div", {
|
|
142448
142934
|
className: "newsletter-altcha",
|
|
@@ -142451,6 +142937,12 @@ function NewsletterFormClient({ render }) {
|
|
|
142451
142937
|
onSolutionChange: setAltchaSolution
|
|
142452
142938
|
})
|
|
142453
142939
|
}),
|
|
142940
|
+
formError && /* @__PURE__ */ jsx(FeedbackMessage, {
|
|
142941
|
+
tone: "error",
|
|
142942
|
+
className: "fb-error",
|
|
142943
|
+
role: "alert",
|
|
142944
|
+
children: formError
|
|
142945
|
+
}),
|
|
142454
142946
|
/* @__PURE__ */ jsx("div", {
|
|
142455
142947
|
className: "newsletter-submit",
|
|
142456
142948
|
children: /* @__PURE__ */ jsx("button", {
|
|
@@ -142459,8 +142951,8 @@ function NewsletterFormClient({ render }) {
|
|
|
142459
142951
|
variant: render.display.buttonVariant,
|
|
142460
142952
|
size: "md"
|
|
142461
142953
|
}),
|
|
142462
|
-
disabled:
|
|
142463
|
-
children:
|
|
142954
|
+
disabled: submitting,
|
|
142955
|
+
children: submitting ? "Subscribing..." : render.display.buttonLabel
|
|
142464
142956
|
})
|
|
142465
142957
|
})
|
|
142466
142958
|
]
|
|
@@ -142470,9 +142962,70 @@ function NewsletterFormClient({ render }) {
|
|
|
142470
142962
|
children: render.display.privacyNote
|
|
142471
142963
|
})
|
|
142472
142964
|
]
|
|
142473
|
-
})
|
|
142965
|
+
})
|
|
142474
142966
|
});
|
|
142475
142967
|
}
|
|
142968
|
+
function NewsletterField({ field, submitting, error }) {
|
|
142969
|
+
const inputId = `newsletter_${field.id}`;
|
|
142970
|
+
const errorId = `${inputId}-error`;
|
|
142971
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
142972
|
+
className: "fb-field newsletter-field",
|
|
142973
|
+
children: [
|
|
142974
|
+
/* @__PURE__ */ jsxs("label", {
|
|
142975
|
+
htmlFor: inputId,
|
|
142976
|
+
className: "form-label",
|
|
142977
|
+
children: [field.label, field.required && /* @__PURE__ */ jsx("span", {
|
|
142978
|
+
className: "newsletter-required",
|
|
142979
|
+
"aria-hidden": "true",
|
|
142980
|
+
children: "*"
|
|
142981
|
+
})]
|
|
142982
|
+
}),
|
|
142983
|
+
/* @__PURE__ */ jsx("input", {
|
|
142984
|
+
id: inputId,
|
|
142985
|
+
name: field.id,
|
|
142986
|
+
type: field.type,
|
|
142987
|
+
required: field.required,
|
|
142988
|
+
placeholder: field.placeholder,
|
|
142989
|
+
className: "form-input",
|
|
142990
|
+
autoComplete: field.type === "email" ? "email" : void 0,
|
|
142991
|
+
disabled: submitting,
|
|
142992
|
+
...getFieldValidationControlProps({
|
|
142993
|
+
message: error,
|
|
142994
|
+
messageId: errorId
|
|
142995
|
+
})
|
|
142996
|
+
}),
|
|
142997
|
+
error && /* @__PURE__ */ jsx(FieldValidationMessage, {
|
|
142998
|
+
id: errorId,
|
|
142999
|
+
className: "fb-error",
|
|
143000
|
+
children: error
|
|
143001
|
+
})
|
|
143002
|
+
]
|
|
143003
|
+
});
|
|
143004
|
+
}
|
|
143005
|
+
function NewsletterTopicChoices({ choices, submitting, error }) {
|
|
143006
|
+
const errorId = `newsletter_${TOPIC_CHOICE_FIELD_ID}-error`;
|
|
143007
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("fieldset", {
|
|
143008
|
+
className: "fb-fieldset newsletter-topics",
|
|
143009
|
+
"aria-describedby": error ? errorId : void 0,
|
|
143010
|
+
children: [/* @__PURE__ */ jsx("legend", {
|
|
143011
|
+
className: "form-label",
|
|
143012
|
+
children: "What would you like to hear about?"
|
|
143013
|
+
}), choices.map((choice) => /* @__PURE__ */ jsxs("label", {
|
|
143014
|
+
className: "fb-inline form-label newsletter-topic-choice",
|
|
143015
|
+
children: [/* @__PURE__ */ jsx("input", {
|
|
143016
|
+
type: "checkbox",
|
|
143017
|
+
name: TOPIC_CHOICE_FIELD_ID,
|
|
143018
|
+
value: choice.id,
|
|
143019
|
+
className: "form-checkbox",
|
|
143020
|
+
disabled: submitting
|
|
143021
|
+
}), /* @__PURE__ */ jsx("span", { children: choice.label })]
|
|
143022
|
+
}, choice.id))]
|
|
143023
|
+
}), error && /* @__PURE__ */ jsx(FieldValidationMessage, {
|
|
143024
|
+
id: errorId,
|
|
143025
|
+
className: "fb-error",
|
|
143026
|
+
children: error
|
|
143027
|
+
})] });
|
|
143028
|
+
}
|
|
142476
143029
|
function UnavailableNewsletterForm({ className }) {
|
|
142477
143030
|
return /* @__PURE__ */ jsx("div", {
|
|
142478
143031
|
className: clsx("newsletter-form", className ?? void 0),
|
|
@@ -142480,13 +143033,32 @@ function UnavailableNewsletterForm({ className }) {
|
|
|
142480
143033
|
tone: "error",
|
|
142481
143034
|
className: "fb-error",
|
|
142482
143035
|
role: "status",
|
|
142483
|
-
children:
|
|
143036
|
+
children: SIGNUPS_PAUSED_MESSAGE
|
|
142484
143037
|
})
|
|
142485
143038
|
});
|
|
142486
143039
|
}
|
|
143040
|
+
const TOPIC_CHOICE_FIELD_ID = "mailingListChoice";
|
|
143041
|
+
/** The site's setup is broken or missing: nothing the visitor does will help. */
|
|
143042
|
+
const SIGNUPS_PAUSED_MESSAGE = "We can’t accept signups right now. Please try again later.";
|
|
143043
|
+
/** The provider did not answer in time or at all: worth another go shortly. */
|
|
143044
|
+
const RETRY_SHORTLY_MESSAGE = "We couldn’t confirm your signup. Please try again in a little while.";
|
|
143045
|
+
const TOO_MANY_ATTEMPTS_MESSAGE = "There have been too many signup attempts. Please wait a moment and try again.";
|
|
143046
|
+
/**
|
|
143047
|
+
* Vetted copy for a request that never produced a signup response. The raw
|
|
143048
|
+
* error text ("Failed to fetch", "received invalid JSON") is for logs, not
|
|
143049
|
+
* visitors.
|
|
143050
|
+
*/
|
|
143051
|
+
function transportFailureMessage(err) {
|
|
143052
|
+
if (err instanceof BlockApiError) {
|
|
143053
|
+
if (err.status === 429) return TOO_MANY_ATTEMPTS_MESSAGE;
|
|
143054
|
+
if (err.status === 403) return "We couldn’t verify this submission. Please try again.";
|
|
143055
|
+
if (err.status === 400 || err.status === 422) return "Please check your details and try again.";
|
|
143056
|
+
}
|
|
143057
|
+
return RETRY_SHORTLY_MESSAGE;
|
|
143058
|
+
}
|
|
142487
143059
|
function readVisitorSelection(formData, hydration) {
|
|
142488
143060
|
if (hydration.choicePresentation !== "visitor_choice") return void 0;
|
|
142489
|
-
const ids = formData.getAll(
|
|
143061
|
+
const ids = formData.getAll(TOPIC_CHOICE_FIELD_ID).flatMap((value) => typeof value === "string" ? [value] : []);
|
|
142490
143062
|
if (ids.length === 0) return null;
|
|
142491
143063
|
const raw = hydration.choiceProvider === "native" ? {
|
|
142492
143064
|
provider: "native",
|
|
@@ -142508,11 +143080,10 @@ function publicSignupError(outcome) {
|
|
|
142508
143080
|
case "unavailable": switch (outcome.reason) {
|
|
142509
143081
|
case "configuration_unavailable":
|
|
142510
143082
|
case "authentication_failed":
|
|
142511
|
-
case "target_unavailable": return
|
|
143083
|
+
case "target_unavailable": return SIGNUPS_PAUSED_MESSAGE;
|
|
142512
143084
|
case "stale_configuration": return "This signup form has changed. Refresh the page, then try again.";
|
|
142513
|
-
case "
|
|
142514
|
-
case "
|
|
142515
|
-
case "temporarily_unavailable": return "We could not sign you up just now. Please try again shortly.";
|
|
143085
|
+
case "rate_limited": return TOO_MANY_ATTEMPTS_MESSAGE;
|
|
143086
|
+
case "temporarily_unavailable": return RETRY_SHORTLY_MESSAGE;
|
|
142516
143087
|
}
|
|
142517
143088
|
case "uncertain": return "We could not confirm whether your signup completed. Please wait a moment, then try again.";
|
|
142518
143089
|
}
|
|
@@ -146749,6 +147320,18 @@ function resolveChildren(nodes, context) {
|
|
|
146749
147320
|
function isReactNode(value) {
|
|
146750
147321
|
return value !== null && value !== void 0;
|
|
146751
147322
|
}
|
|
147323
|
+
function resolveNodeMetadata(nodeType, context) {
|
|
147324
|
+
return {
|
|
147325
|
+
pathBase: context.pathBase,
|
|
147326
|
+
blockId: context.blockId,
|
|
147327
|
+
blockKind: context.blockKind,
|
|
147328
|
+
blockContent: context.blockContent,
|
|
147329
|
+
fragmentRegistry: context.fragmentRegistry,
|
|
147330
|
+
previewAuthoring: context.previewAuthoring,
|
|
147331
|
+
...nodeType.toLowerCase() === "newsletter-form" ? { contentVersionId: context.contentVersionId } : {},
|
|
147332
|
+
...nodeType === "media" && context.imageResolveContext ? { imageResolveContext: context.imageResolveContext } : {}
|
|
147333
|
+
};
|
|
147334
|
+
}
|
|
146752
147335
|
/**
|
|
146753
147336
|
* Resolves a node definition into a React element.
|
|
146754
147337
|
* Handles conditionals ($when), scopes ($scopes), repeaters ($repeat), bindings ($bind), and children.
|
|
@@ -146784,13 +147367,7 @@ function resolveNode(node, context, indexFallback) {
|
|
|
146784
147367
|
const elementProps = {
|
|
146785
147368
|
...props,
|
|
146786
147369
|
key: node.key ?? indexFallback,
|
|
146787
|
-
|
|
146788
|
-
blockId: context.blockId,
|
|
146789
|
-
blockKind: context.blockKind,
|
|
146790
|
-
blockContent: context.blockContent,
|
|
146791
|
-
...node.type === "media" && context.imageResolveContext ? { imageResolveContext: context.imageResolveContext } : {},
|
|
146792
|
-
fragmentRegistry: context.fragmentRegistry,
|
|
146793
|
-
previewAuthoring: context.previewAuthoring
|
|
147370
|
+
...resolveNodeMetadata(node.type, context)
|
|
146794
147371
|
};
|
|
146795
147372
|
const element = React.createElement(component, elementProps, ...children);
|
|
146796
147373
|
if (headingDecorationPlan.kind === "skip") return element;
|
|
@@ -158952,7 +159529,7 @@ function collectNestedPreviewFieldConstraintEntries(field, path) {
|
|
|
158952
159529
|
}
|
|
158953
159530
|
function makeDefaultBlockComponent(args) {
|
|
158954
159531
|
const { manifest } = args;
|
|
158955
|
-
return function DefaultBlockComponent({ content, data, registry, theme, themeConfig, transforms, viewModelOverrides, pathBase, blockId, blockKind, blockBindings, editableRouteMetadataFieldIds, fragmentRegistry, imageResolveContext, previewAuthoring }) {
|
|
159532
|
+
return function DefaultBlockComponent({ content, data, registry, theme, themeConfig, transforms, viewModelOverrides, pathBase, blockId, contentVersionId, blockKind, blockBindings, editableRouteMetadataFieldIds, fragmentRegistry, imageResolveContext, previewAuthoring }) {
|
|
158956
159533
|
const perf = beginBlockRenderMeasurement();
|
|
158957
159534
|
if (!theme) throw new Error("Block rendering requires theme tokens; none were provided to makeDefaultBlockComponent");
|
|
158958
159535
|
if (!registry) throw new Error("Block rendering requires a component registry; none was provided");
|
|
@@ -158972,6 +159549,7 @@ function makeDefaultBlockComponent(args) {
|
|
|
158972
159549
|
theme: withButtonSystem(theme, themeConfig),
|
|
158973
159550
|
pathBase,
|
|
158974
159551
|
blockId,
|
|
159552
|
+
contentVersionId,
|
|
158975
159553
|
blockKind,
|
|
158976
159554
|
blockContent: mergedContent,
|
|
158977
159555
|
blockBindings,
|
|
@@ -170076,7 +170654,9 @@ const containerResponsiveThemeCss = `/*
|
|
|
170076
170654
|
text-align: left;
|
|
170077
170655
|
}
|
|
170078
170656
|
|
|
170079
|
-
:where(.theme-scope)
|
|
170657
|
+
:where(.theme-scope)
|
|
170658
|
+
:where([data-block="customer-portal"])
|
|
170659
|
+
.cp-login__subtitle {
|
|
170080
170660
|
color: var(--cp-muted);
|
|
170081
170661
|
font-size: 0.9375rem;
|
|
170082
170662
|
text-align: left;
|
|
@@ -170103,7 +170683,9 @@ const containerResponsiveThemeCss = `/*
|
|
|
170103
170683
|
text-align: left;
|
|
170104
170684
|
}
|
|
170105
170685
|
|
|
170106
|
-
:where(.theme-scope)
|
|
170686
|
+
:where(.theme-scope)
|
|
170687
|
+
:where([data-block="customer-portal"])
|
|
170688
|
+
.cp-login__reset-link {
|
|
170107
170689
|
appearance: none;
|
|
170108
170690
|
background: none;
|
|
170109
170691
|
border: 0;
|
|
@@ -170117,11 +170699,15 @@ const containerResponsiveThemeCss = `/*
|
|
|
170117
170699
|
text-underline-offset: 0.15em;
|
|
170118
170700
|
}
|
|
170119
170701
|
|
|
170120
|
-
:where(.theme-scope)
|
|
170702
|
+
:where(.theme-scope)
|
|
170703
|
+
:where([data-block="customer-portal"])
|
|
170704
|
+
.cp-login__reset-link:hover {
|
|
170121
170705
|
color: var(--cp-text);
|
|
170122
170706
|
}
|
|
170123
170707
|
|
|
170124
|
-
:where(.theme-scope)
|
|
170708
|
+
:where(.theme-scope)
|
|
170709
|
+
:where([data-block="customer-portal"])
|
|
170710
|
+
.cp-login__reset-link:focus-visible {
|
|
170125
170711
|
outline: 2px solid currentColor;
|
|
170126
170712
|
outline-offset: 3px;
|
|
170127
170713
|
}
|
|
@@ -170166,7 +170752,9 @@ const containerResponsiveThemeCss = `/*
|
|
|
170166
170752
|
border-bottom: none;
|
|
170167
170753
|
}
|
|
170168
170754
|
|
|
170169
|
-
:where(.theme-scope)
|
|
170755
|
+
:where(.theme-scope)
|
|
170756
|
+
:where([data-block="customer-portal"])
|
|
170757
|
+
.cp-header__welcome {
|
|
170170
170758
|
font-size: 1.125rem;
|
|
170171
170759
|
font-weight: 500;
|
|
170172
170760
|
}
|
|
@@ -170182,8 +170770,14 @@ const containerResponsiveThemeCss = `/*
|
|
|
170182
170770
|
}
|
|
170183
170771
|
|
|
170184
170772
|
@keyframes cp-fade-in {
|
|
170185
|
-
from {
|
|
170186
|
-
|
|
170773
|
+
from {
|
|
170774
|
+
opacity: 0;
|
|
170775
|
+
transform: translateY(4px);
|
|
170776
|
+
}
|
|
170777
|
+
to {
|
|
170778
|
+
opacity: 1;
|
|
170779
|
+
transform: translateY(0);
|
|
170780
|
+
}
|
|
170187
170781
|
}
|
|
170188
170782
|
|
|
170189
170783
|
/* Empty state */
|
|
@@ -170272,6 +170866,77 @@ const containerResponsiveThemeCss = `/*
|
|
|
170272
170866
|
margin-top: 1rem;
|
|
170273
170867
|
}
|
|
170274
170868
|
|
|
170869
|
+
/* Event waitlists */
|
|
170870
|
+
:where(.theme-scope) :where([data-block="customer-portal"]) .cp-waitlist-list {
|
|
170871
|
+
display: grid;
|
|
170872
|
+
gap: 1rem;
|
|
170873
|
+
}
|
|
170874
|
+
|
|
170875
|
+
:where(.theme-scope)
|
|
170876
|
+
:where([data-block="customer-portal"])
|
|
170877
|
+
.cp-waitlists
|
|
170878
|
+
> .cp-alert {
|
|
170879
|
+
margin-bottom: 1rem;
|
|
170880
|
+
}
|
|
170881
|
+
|
|
170882
|
+
:where(.theme-scope) :where([data-block="customer-portal"]) .cp-waitlist-card {
|
|
170883
|
+
transition:
|
|
170884
|
+
border-color 180ms ease,
|
|
170885
|
+
box-shadow 180ms ease;
|
|
170886
|
+
}
|
|
170887
|
+
|
|
170888
|
+
:where(.theme-scope)
|
|
170889
|
+
:where([data-block="customer-portal"])
|
|
170890
|
+
.cp-waitlist-card--focused {
|
|
170891
|
+
border-color: var(--cp-primary);
|
|
170892
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--cp-primary) 22%, transparent);
|
|
170893
|
+
}
|
|
170894
|
+
|
|
170895
|
+
:where(.theme-scope)
|
|
170896
|
+
:where([data-block="customer-portal"])
|
|
170897
|
+
.cp-waitlist-card__summary,
|
|
170898
|
+
:where(.theme-scope)
|
|
170899
|
+
:where([data-block="customer-portal"])
|
|
170900
|
+
.cp-waitlist-card__position {
|
|
170901
|
+
font-weight: 600;
|
|
170902
|
+
}
|
|
170903
|
+
|
|
170904
|
+
:where(.theme-scope)
|
|
170905
|
+
:where([data-block="customer-portal"])
|
|
170906
|
+
.cp-waitlist-card
|
|
170907
|
+
.cp-card-body
|
|
170908
|
+
p {
|
|
170909
|
+
margin: 0.4rem 0;
|
|
170910
|
+
}
|
|
170911
|
+
|
|
170912
|
+
@container rb-site (max-width: 640px) {
|
|
170913
|
+
@scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
|
|
170914
|
+
:where(.theme-scope)
|
|
170915
|
+
:where([data-block="customer-portal"])
|
|
170916
|
+
.cp-waitlist-card
|
|
170917
|
+
.cp-card-header {
|
|
170918
|
+
flex-direction: column-reverse;
|
|
170919
|
+
}
|
|
170920
|
+
|
|
170921
|
+
:where(.theme-scope)
|
|
170922
|
+
:where([data-block="customer-portal"])
|
|
170923
|
+
.cp-waitlist-card
|
|
170924
|
+
.cp-card-actions {
|
|
170925
|
+
align-items: stretch;
|
|
170926
|
+
flex-direction: column;
|
|
170927
|
+
}
|
|
170928
|
+
|
|
170929
|
+
:where(.theme-scope)
|
|
170930
|
+
:where([data-block="customer-portal"])
|
|
170931
|
+
.cp-waitlist-card
|
|
170932
|
+
.cp-card-actions
|
|
170933
|
+
> * {
|
|
170934
|
+
justify-content: center;
|
|
170935
|
+
text-align: center;
|
|
170936
|
+
}
|
|
170937
|
+
}
|
|
170938
|
+
}
|
|
170939
|
+
|
|
170275
170940
|
/* Badge */
|
|
170276
170941
|
:where(.theme-scope) :where([data-block="customer-portal"]) .cp-badge {
|
|
170277
170942
|
display: inline-flex;
|
|
@@ -170408,11 +171073,18 @@ const containerResponsiveThemeCss = `/*
|
|
|
170408
171073
|
background: rgba(var(--tb-border), 0.2);
|
|
170409
171074
|
}
|
|
170410
171075
|
|
|
170411
|
-
:where(.theme-scope)
|
|
171076
|
+
:where(.theme-scope)
|
|
171077
|
+
:where([data-block="customer-portal"])
|
|
171078
|
+
.cp-table
|
|
171079
|
+
tbody
|
|
171080
|
+
tr:last-child
|
|
171081
|
+
td {
|
|
170412
171082
|
border-bottom: none;
|
|
170413
171083
|
}
|
|
170414
171084
|
|
|
170415
|
-
:where(.theme-scope)
|
|
171085
|
+
:where(.theme-scope)
|
|
171086
|
+
:where([data-block="customer-portal"])
|
|
171087
|
+
:is(.cp-row--past, .cp-row--muted) {
|
|
170416
171088
|
opacity: 0.65;
|
|
170417
171089
|
}
|
|
170418
171090
|
|
|
@@ -170425,7 +171097,9 @@ const containerResponsiveThemeCss = `/*
|
|
|
170425
171097
|
line-height: 1.2;
|
|
170426
171098
|
}
|
|
170427
171099
|
|
|
170428
|
-
:where(.theme-scope)
|
|
171100
|
+
:where(.theme-scope)
|
|
171101
|
+
:where([data-block="customer-portal"])
|
|
171102
|
+
.cp-row-title__badges {
|
|
170429
171103
|
margin-left: auto;
|
|
170430
171104
|
display: flex;
|
|
170431
171105
|
flex-wrap: wrap;
|
|
@@ -170433,7 +171107,9 @@ const containerResponsiveThemeCss = `/*
|
|
|
170433
171107
|
gap: 0.375rem;
|
|
170434
171108
|
}
|
|
170435
171109
|
|
|
170436
|
-
:where(.theme-scope)
|
|
171110
|
+
:where(.theme-scope)
|
|
171111
|
+
:where([data-block="customer-portal"])
|
|
171112
|
+
.cp-row-title__text {
|
|
170437
171113
|
min-width: 0;
|
|
170438
171114
|
}
|
|
170439
171115
|
|
|
@@ -170453,12 +171129,16 @@ const containerResponsiveThemeCss = `/*
|
|
|
170453
171129
|
line-height: 1.35;
|
|
170454
171130
|
}
|
|
170455
171131
|
|
|
170456
|
-
:where(.theme-scope)
|
|
171132
|
+
:where(.theme-scope)
|
|
171133
|
+
:where([data-block="customer-portal"])
|
|
171134
|
+
.cp-row-note--success {
|
|
170457
171135
|
border-left-color: rgb(var(--tb-success));
|
|
170458
171136
|
color: rgb(var(--tb-success));
|
|
170459
171137
|
}
|
|
170460
171138
|
|
|
170461
|
-
:where(.theme-scope)
|
|
171139
|
+
:where(.theme-scope)
|
|
171140
|
+
:where([data-block="customer-portal"])
|
|
171141
|
+
.cp-row-note--error {
|
|
170462
171142
|
border-left-color: rgb(var(--tb-destructive));
|
|
170463
171143
|
color: rgb(var(--tb-destructive));
|
|
170464
171144
|
}
|
|
@@ -170477,16 +171157,23 @@ const containerResponsiveThemeCss = `/*
|
|
|
170477
171157
|
white-space: nowrap;
|
|
170478
171158
|
}
|
|
170479
171159
|
|
|
170480
|
-
:where(.theme-scope)
|
|
171160
|
+
:where(.theme-scope)
|
|
171161
|
+
:where([data-block="customer-portal"])
|
|
171162
|
+
.cp-col-actions
|
|
171163
|
+
.btn-sm {
|
|
170481
171164
|
white-space: nowrap;
|
|
170482
171165
|
}
|
|
170483
171166
|
|
|
170484
|
-
:where(.theme-scope)
|
|
171167
|
+
:where(.theme-scope)
|
|
171168
|
+
:where([data-block="customer-portal"])
|
|
171169
|
+
.cp-row-title__link {
|
|
170485
171170
|
color: inherit;
|
|
170486
171171
|
text-decoration: none;
|
|
170487
171172
|
}
|
|
170488
171173
|
|
|
170489
|
-
:where(.theme-scope)
|
|
171174
|
+
:where(.theme-scope)
|
|
171175
|
+
:where([data-block="customer-portal"])
|
|
171176
|
+
.cp-row-title__link:hover {
|
|
170490
171177
|
text-decoration: underline;
|
|
170491
171178
|
text-decoration-thickness: 2px;
|
|
170492
171179
|
text-underline-offset: 2px;
|
|
@@ -170508,7 +171195,9 @@ const containerResponsiveThemeCss = `/*
|
|
|
170508
171195
|
}
|
|
170509
171196
|
|
|
170510
171197
|
/* Profile actions */
|
|
170511
|
-
:where(.theme-scope)
|
|
171198
|
+
:where(.theme-scope)
|
|
171199
|
+
:where([data-block="customer-portal"])
|
|
171200
|
+
.cp-profile__actions {
|
|
170512
171201
|
display: flex;
|
|
170513
171202
|
gap: 0.75rem;
|
|
170514
171203
|
margin-top: 1rem;
|
|
@@ -170575,28 +171264,39 @@ const containerResponsiveThemeCss = `/*
|
|
|
170575
171264
|
gap: 0.375rem;
|
|
170576
171265
|
}
|
|
170577
171266
|
|
|
170578
|
-
:where(.theme-scope)
|
|
171267
|
+
:where(.theme-scope)
|
|
171268
|
+
:where([data-block="customer-portal"])
|
|
171269
|
+
.cp-guest-edit-row__index {
|
|
170579
171270
|
font-size: 0.75rem;
|
|
170580
171271
|
font-weight: 500;
|
|
170581
171272
|
color: var(--cp-muted);
|
|
170582
171273
|
}
|
|
170583
171274
|
|
|
170584
|
-
:where(.theme-scope)
|
|
171275
|
+
:where(.theme-scope)
|
|
171276
|
+
:where([data-block="customer-portal"])
|
|
171277
|
+
.cp-guest-edit-row__fields {
|
|
170585
171278
|
display: flex;
|
|
170586
171279
|
gap: 0.5rem;
|
|
170587
171280
|
}
|
|
170588
171281
|
|
|
170589
|
-
:where(.theme-scope)
|
|
171282
|
+
:where(.theme-scope)
|
|
171283
|
+
:where([data-block="customer-portal"])
|
|
171284
|
+
.cp-guest-edit-row__fields
|
|
171285
|
+
input {
|
|
170590
171286
|
flex: 1;
|
|
170591
171287
|
min-width: 0;
|
|
170592
171288
|
}
|
|
170593
171289
|
|
|
170594
|
-
:where(.theme-scope)
|
|
171290
|
+
:where(.theme-scope)
|
|
171291
|
+
:where([data-block="customer-portal"])
|
|
171292
|
+
.cp-guest-edit-row__error {
|
|
170595
171293
|
font-size: 0.75rem;
|
|
170596
171294
|
color: var(--cp-error);
|
|
170597
171295
|
}
|
|
170598
171296
|
|
|
170599
|
-
:where(.theme-scope)
|
|
171297
|
+
:where(.theme-scope)
|
|
171298
|
+
:where([data-block="customer-portal"])
|
|
171299
|
+
.cp-guests__actions {
|
|
170600
171300
|
display: flex;
|
|
170601
171301
|
gap: 0.5rem;
|
|
170602
171302
|
margin-top: 0.5rem;
|
|
@@ -170610,13 +171310,18 @@ const containerResponsiveThemeCss = `/*
|
|
|
170610
171310
|
}
|
|
170611
171311
|
|
|
170612
171312
|
/* In the actions modal, tiles sit on a surface modal, so use "background" for contrast. */
|
|
170613
|
-
:where(.theme-scope)
|
|
171313
|
+
:where(.theme-scope)
|
|
171314
|
+
:where([data-block="customer-portal"])
|
|
171315
|
+
.cp-actions-list
|
|
171316
|
+
:where(.rb-tile) {
|
|
170614
171317
|
--rb-event-tile-bg: rgb(var(--tb-background));
|
|
170615
171318
|
--rb-event-tile-border: rgb(var(--tb-border));
|
|
170616
171319
|
}
|
|
170617
171320
|
|
|
170618
171321
|
/* Actions trigger: icon-only kebab button */
|
|
170619
|
-
:where(.theme-scope)
|
|
171322
|
+
:where(.theme-scope)
|
|
171323
|
+
:where([data-block="customer-portal"])
|
|
171324
|
+
.cp-actions-trigger.btn-sm {
|
|
170620
171325
|
padding: 0.35rem !important;
|
|
170621
171326
|
line-height: 1 !important;
|
|
170622
171327
|
min-width: 32px;
|
|
@@ -170640,17 +171345,24 @@ const containerResponsiveThemeCss = `/*
|
|
|
170640
171345
|
gap: 0.25rem;
|
|
170641
171346
|
}
|
|
170642
171347
|
|
|
170643
|
-
:where(.theme-scope)
|
|
171348
|
+
:where(.theme-scope)
|
|
171349
|
+
:where([data-block="customer-portal"])
|
|
171350
|
+
.cp-action-tile__title {
|
|
170644
171351
|
font-weight: 600;
|
|
170645
171352
|
font-size: 0.9375rem;
|
|
170646
171353
|
}
|
|
170647
171354
|
|
|
170648
|
-
:where(.theme-scope)
|
|
171355
|
+
:where(.theme-scope)
|
|
171356
|
+
:where([data-block="customer-portal"])
|
|
171357
|
+
.cp-action-tile__desc {
|
|
170649
171358
|
font-size: 0.875rem;
|
|
170650
171359
|
line-height: 1.35;
|
|
170651
171360
|
}
|
|
170652
171361
|
|
|
170653
|
-
:where(.theme-scope)
|
|
171362
|
+
:where(.theme-scope)
|
|
171363
|
+
:where([data-block="customer-portal"])
|
|
171364
|
+
.cp-action-tile--danger
|
|
171365
|
+
.cp-action-tile__title {
|
|
170654
171366
|
color: rgb(var(--tb-destructive));
|
|
170655
171367
|
}
|
|
170656
171368
|
|
|
@@ -170672,7 +171384,9 @@ const containerResponsiveThemeCss = `/*
|
|
|
170672
171384
|
text-decoration: underline;
|
|
170673
171385
|
}
|
|
170674
171386
|
|
|
170675
|
-
:where(.theme-scope)
|
|
171387
|
+
:where(.theme-scope)
|
|
171388
|
+
:where([data-block="customer-portal"])
|
|
171389
|
+
.cp-btn--link:hover {
|
|
170676
171390
|
color: var(--cp-primary-hover);
|
|
170677
171391
|
}
|
|
170678
171392
|
|
|
@@ -170711,34 +171425,48 @@ const containerResponsiveThemeCss = `/*
|
|
|
170711
171425
|
margin-top: 0.75rem;
|
|
170712
171426
|
}
|
|
170713
171427
|
|
|
170714
|
-
:where(.theme-scope)
|
|
171428
|
+
:where(.theme-scope)
|
|
171429
|
+
:where([data-block="customer-portal"])
|
|
171430
|
+
.cp-cancel-confirm__title {
|
|
170715
171431
|
font-weight: 600;
|
|
170716
171432
|
margin-bottom: 0.5rem;
|
|
170717
171433
|
}
|
|
170718
171434
|
|
|
170719
|
-
:where(.theme-scope)
|
|
171435
|
+
:where(.theme-scope)
|
|
171436
|
+
:where([data-block="customer-portal"])
|
|
171437
|
+
.cp-cancel-confirm__message {
|
|
170720
171438
|
margin-bottom: 0.25rem;
|
|
170721
171439
|
}
|
|
170722
171440
|
|
|
170723
|
-
:where(.theme-scope)
|
|
171441
|
+
:where(.theme-scope)
|
|
171442
|
+
:where([data-block="customer-portal"])
|
|
171443
|
+
.cp-cancel-confirm__warning {
|
|
170724
171444
|
margin-bottom: 0.75rem;
|
|
170725
171445
|
}
|
|
170726
171446
|
|
|
170727
|
-
:where(.theme-scope)
|
|
171447
|
+
:where(.theme-scope)
|
|
171448
|
+
:where([data-block="customer-portal"])
|
|
171449
|
+
.cp-cancel-confirm__actions {
|
|
170728
171450
|
display: flex;
|
|
170729
171451
|
gap: 0.75rem;
|
|
170730
171452
|
}
|
|
170731
171453
|
|
|
170732
171454
|
/* Membership actions */
|
|
170733
|
-
:where(.theme-scope)
|
|
171455
|
+
:where(.theme-scope)
|
|
171456
|
+
:where([data-block="customer-portal"])
|
|
171457
|
+
.cp-membership-actions {
|
|
170734
171458
|
margin-top: 0.75rem;
|
|
170735
171459
|
}
|
|
170736
171460
|
|
|
170737
|
-
:where(.theme-scope)
|
|
171461
|
+
:where(.theme-scope)
|
|
171462
|
+
:where([data-block="customer-portal"])
|
|
171463
|
+
.cp-section-actions {
|
|
170738
171464
|
margin-top: 1rem;
|
|
170739
171465
|
}
|
|
170740
171466
|
|
|
170741
|
-
:where(.theme-scope)
|
|
171467
|
+
:where(.theme-scope)
|
|
171468
|
+
:where([data-block="customer-portal"])
|
|
171469
|
+
.cp-card-subtitle--spaced {
|
|
170742
171470
|
margin-top: 0.75rem;
|
|
170743
171471
|
}
|
|
170744
171472
|
|
|
@@ -170762,9 +171490,18 @@ const containerResponsiveThemeCss = `/*
|
|
|
170762
171490
|
display: none;
|
|
170763
171491
|
}
|
|
170764
171492
|
|
|
170765
|
-
:where(.theme-scope)
|
|
170766
|
-
|
|
170767
|
-
|
|
171493
|
+
:where(.theme-scope)
|
|
171494
|
+
:where([data-block="customer-portal"])
|
|
171495
|
+
.cp-table
|
|
171496
|
+
:is(th, td).cp-col-guests,
|
|
171497
|
+
:where(.theme-scope)
|
|
171498
|
+
:where([data-block="customer-portal"])
|
|
171499
|
+
.cp-table
|
|
171500
|
+
:is(th, td).cp-col-tickets,
|
|
171501
|
+
:where(.theme-scope)
|
|
171502
|
+
:where([data-block="customer-portal"])
|
|
171503
|
+
.cp-table
|
|
171504
|
+
:is(th, td).cp-col-actions {
|
|
170768
171505
|
display: none;
|
|
170769
171506
|
}
|
|
170770
171507
|
|
|
@@ -170773,24 +171510,34 @@ const containerResponsiveThemeCss = `/*
|
|
|
170773
171510
|
}
|
|
170774
171511
|
|
|
170775
171512
|
/* Make the cell a positioning context for the kebab */
|
|
170776
|
-
:where(.theme-scope)
|
|
171513
|
+
:where(.theme-scope)
|
|
171514
|
+
:where([data-block="customer-portal"])
|
|
171515
|
+
.cp-row
|
|
171516
|
+
> td:first-child {
|
|
170777
171517
|
position: relative;
|
|
170778
171518
|
padding-right: 2.5rem;
|
|
170779
171519
|
}
|
|
170780
171520
|
|
|
170781
171521
|
/* Position kebab in top-right of the cell */
|
|
170782
|
-
:where(.theme-scope)
|
|
171522
|
+
:where(.theme-scope)
|
|
171523
|
+
:where([data-block="customer-portal"])
|
|
171524
|
+
.cp-row-mobile-actions {
|
|
170783
171525
|
position: absolute;
|
|
170784
171526
|
top: 0.5rem;
|
|
170785
171527
|
right: 0.5rem;
|
|
170786
171528
|
margin-top: 0;
|
|
170787
171529
|
}
|
|
170788
171530
|
|
|
170789
|
-
:where(.theme-scope)
|
|
171531
|
+
:where(.theme-scope)
|
|
171532
|
+
:where([data-block="customer-portal"])
|
|
171533
|
+
.cp-row-mobile-actions
|
|
171534
|
+
.btn-sm {
|
|
170790
171535
|
width: auto;
|
|
170791
171536
|
}
|
|
170792
171537
|
|
|
170793
|
-
:where(.theme-scope)
|
|
171538
|
+
:where(.theme-scope)
|
|
171539
|
+
:where([data-block="customer-portal"])
|
|
171540
|
+
.cp-profile__edit {
|
|
170794
171541
|
align-self: stretch;
|
|
170795
171542
|
}
|
|
170796
171543
|
}
|
|
@@ -171238,6 +171985,30 @@ const containerResponsiveThemeCss = `/*
|
|
|
171238
171985
|
gap: 0.25rem;
|
|
171239
171986
|
}
|
|
171240
171987
|
|
|
171988
|
+
/* Topic choices (visitor picks what to hear about). Same treatment as the
|
|
171989
|
+
form block's .fb-fieldset / .fb-inline, defined here because the newsletter
|
|
171990
|
+
form also renders inside contact-newsletter and the site footer. */
|
|
171991
|
+
:where(.theme-scope) .newsletter-topics {
|
|
171992
|
+
display: flex;
|
|
171993
|
+
flex-direction: column;
|
|
171994
|
+
gap: 0.5rem;
|
|
171995
|
+
border: none;
|
|
171996
|
+
padding: 0;
|
|
171997
|
+
margin: 0;
|
|
171998
|
+
min-width: 0;
|
|
171999
|
+
}
|
|
172000
|
+
|
|
172001
|
+
:where(.theme-scope) .newsletter-topics > legend {
|
|
172002
|
+
padding: 0;
|
|
172003
|
+
margin-bottom: 0.25rem;
|
|
172004
|
+
}
|
|
172005
|
+
|
|
172006
|
+
:where(.theme-scope) .newsletter-topic-choice {
|
|
172007
|
+
display: flex;
|
|
172008
|
+
align-items: center;
|
|
172009
|
+
gap: 0.5rem;
|
|
172010
|
+
}
|
|
172011
|
+
|
|
171241
172012
|
/* Required indicator */
|
|
171242
172013
|
:where(.theme-scope) .newsletter-required {
|
|
171243
172014
|
color: rgb(var(--tb-primary));
|
|
@@ -171287,6 +172058,10 @@ const containerResponsiveThemeCss = `/*
|
|
|
171287
172058
|
flex-shrink: 0;
|
|
171288
172059
|
}
|
|
171289
172060
|
|
|
172061
|
+
:where(.theme-scope) .newsletter-inline .newsletter-topics {
|
|
172062
|
+
flex-basis: 100%;
|
|
172063
|
+
}
|
|
172064
|
+
|
|
171290
172065
|
/* Mobile fallback for inline variant */
|
|
171291
172066
|
@container rb-site (max-width: 640px) {
|
|
171292
172067
|
@scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
|
|
@@ -184879,13 +185654,16 @@ async function listFooterForms(apiClient, siteId) {
|
|
|
184879
185654
|
}));
|
|
184880
185655
|
}
|
|
184881
185656
|
async function getFooterEngagementAuthoringOptions(apiClient, siteId) {
|
|
184882
|
-
const [forms,
|
|
185657
|
+
const [forms, authoringContext] = await Promise.all([listFooterForms(apiClient, siteId), apiClient({
|
|
184883
185658
|
endpoint: "getMailingListAuthoringContext",
|
|
184884
185659
|
params: { siteId }
|
|
184885
185660
|
}).then(unwrapResponse)]);
|
|
184886
185661
|
return {
|
|
184887
185662
|
forms,
|
|
184888
|
-
mailingList
|
|
185663
|
+
mailingList: authoringContext.runtime,
|
|
185664
|
+
expectedMailingListProviderScope: authoringContext.expectedProviderScope,
|
|
185665
|
+
confirmation: authoringContext.confirmation,
|
|
185666
|
+
canManageMailingListSetup: authoringContext.canManageSetup
|
|
184889
185667
|
};
|
|
184890
185668
|
}
|
|
184891
185669
|
async function updateFooterComposition(apiClient, siteId, body) {
|
|
@@ -185341,7 +186119,17 @@ const riverbankSiteConfigInputSchema = z.object({
|
|
|
185341
186119
|
z.object({
|
|
185342
186120
|
config: riverbankSiteConfigInputSchema,
|
|
185343
186121
|
forceContentTypes: z.boolean().optional(),
|
|
185344
|
-
mode: z.enum(["apply", "preview"]).optional()
|
|
186122
|
+
mode: z.enum(["apply", "preview"]).optional(),
|
|
186123
|
+
expectedMailingListProviderScope: z.unknown().transform((value, ctx) => {
|
|
186124
|
+
if (value === void 0) return void 0;
|
|
186125
|
+
const parsed = parseMailingListProviderScope(value);
|
|
186126
|
+
if (parsed.ok) return parsed.value;
|
|
186127
|
+
ctx.addIssue({
|
|
186128
|
+
code: "custom",
|
|
186129
|
+
message: "Invalid mailing-list provider scope"
|
|
186130
|
+
});
|
|
186131
|
+
return z.NEVER;
|
|
186132
|
+
}).optional()
|
|
185345
186133
|
}).strict();
|
|
185346
186134
|
//#endregion
|
|
185347
186135
|
//#region ../api/src/sdkThemeWire.ts
|
|
@@ -186504,7 +187292,8 @@ async function mutateBlockContent(apiClient, args) {
|
|
|
186504
187292
|
if ("data" in args) {
|
|
186505
187293
|
const payload = {
|
|
186506
187294
|
data: args.data,
|
|
186507
|
-
optimistic_hash: args.optimisticHash ?? void 0
|
|
187295
|
+
optimistic_hash: args.optimisticHash ?? void 0,
|
|
187296
|
+
expected_mailing_list_provider_scope: args.expectedMailingListProviderScope
|
|
186508
187297
|
};
|
|
186509
187298
|
return unwrapResponse(await apiClient({
|
|
186510
187299
|
endpoint: "saveBlockContent",
|
|
@@ -186516,7 +187305,8 @@ async function mutateBlockContent(apiClient, args) {
|
|
|
186516
187305
|
const payload = {
|
|
186517
187306
|
path: args.path,
|
|
186518
187307
|
value: args.value,
|
|
186519
|
-
optimistic_hash: args.optimisticHash ?? void 0
|
|
187308
|
+
optimistic_hash: args.optimisticHash ?? void 0,
|
|
187309
|
+
expected_mailing_list_provider_scope: args.expectedMailingListProviderScope
|
|
186520
187310
|
};
|
|
186521
187311
|
return unwrapResponse(await apiClient({
|
|
186522
187312
|
endpoint: "saveBlockContent",
|
|
@@ -192124,6 +192914,9 @@ function planBlockSaveRevisionForOwner(owner, optimisticHash) {
|
|
|
192124
192914
|
default: return assertNever$10(owner);
|
|
192125
192915
|
}
|
|
192126
192916
|
}
|
|
192917
|
+
function isPendingWithCurrent(snapshot) {
|
|
192918
|
+
return snapshot.syncState.kind === "pending" && Boolean(snapshot.current);
|
|
192919
|
+
}
|
|
192127
192920
|
function optimisticHashForSave(revision) {
|
|
192128
192921
|
switch (revision.kind) {
|
|
192129
192922
|
case "bestEffort":
|
|
@@ -192138,9 +192931,8 @@ const MISSING_REQUIRED_BLOCK_REVISION = "This Page Content block is missing its
|
|
|
192138
192931
|
*
|
|
192139
192932
|
* Only enabled for pages (hasRoute=true), as content entries don't have blocks.
|
|
192140
192933
|
*/
|
|
192141
|
-
function useBlockAutosave({ uiStore, apiClient, siteId, hasRoute, owner }) {
|
|
192934
|
+
function useBlockAutosave({ uiStore, apiClient, siteId, hasRoute, owner, getExpectedMailingListProviderScope }) {
|
|
192142
192935
|
const ownerKind = owner.kind;
|
|
192143
|
-
const isPendingWithCurrent = (snapshot) => snapshot.syncState.kind === "pending" && Boolean(snapshot.current);
|
|
192144
192936
|
return useSimpleAutosave({
|
|
192145
192937
|
saveFn: useCallback(async (pendingBlocks) => {
|
|
192146
192938
|
const results = await Promise.allSettled(pendingBlocks.map(async ({ blockId, data, revision }) => {
|
|
@@ -192149,7 +192941,8 @@ function useBlockAutosave({ uiStore, apiClient, siteId, hasRoute, owner }) {
|
|
|
192149
192941
|
siteId,
|
|
192150
192942
|
blockId,
|
|
192151
192943
|
data,
|
|
192152
|
-
optimisticHash: optimisticHashForSave(revision) ?? void 0
|
|
192944
|
+
optimisticHash: optimisticHashForSave(revision) ?? void 0,
|
|
192945
|
+
expectedMailingListProviderScope: getExpectedMailingListProviderScope?.() ?? void 0
|
|
192153
192946
|
});
|
|
192154
192947
|
}));
|
|
192155
192948
|
const drafts = uiStore.getState().drafts;
|
|
@@ -192171,6 +192964,7 @@ function useBlockAutosave({ uiStore, apiClient, siteId, hasRoute, owner }) {
|
|
|
192171
192964
|
return results;
|
|
192172
192965
|
}, [
|
|
192173
192966
|
apiClient,
|
|
192967
|
+
getExpectedMailingListProviderScope,
|
|
192174
192968
|
siteId,
|
|
192175
192969
|
uiStore
|
|
192176
192970
|
]),
|
|
@@ -222980,314 +223774,34 @@ async function loadMailingListAuthoringContext(input) {
|
|
|
222980
223774
|
}));
|
|
222981
223775
|
}
|
|
222982
223776
|
//#endregion
|
|
222983
|
-
//#region ../editor-blocks/src/widgets/mailing-list-targeting/
|
|
222984
|
-
|
|
222985
|
-
function
|
|
222986
|
-
const { value, error, setValue } = useField(path, backend);
|
|
222987
|
-
const { siteId, load, manageHref } = useMailingListTargetingContext();
|
|
222988
|
-
const [loadState, setLoadState] = useState({ tag: "loading" });
|
|
222989
|
-
const [loadError, setLoadError] = useState(null);
|
|
222990
|
-
const requestVersion = useRef(0);
|
|
222991
|
-
const refresh = useCallback(async () => {
|
|
222992
|
-
const version = requestVersion.current + 1;
|
|
222993
|
-
requestVersion.current = version;
|
|
222994
|
-
setLoadState({ tag: "loading" });
|
|
222995
|
-
setLoadError(null);
|
|
222996
|
-
try {
|
|
222997
|
-
const context = await load(siteId);
|
|
222998
|
-
if (requestVersion.current === version) setLoadState({
|
|
222999
|
-
tag: "loaded",
|
|
223000
|
-
context
|
|
223001
|
-
});
|
|
223002
|
-
} catch {
|
|
223003
|
-
if (requestVersion.current === version) {
|
|
223004
|
-
setLoadState({ tag: "failed" });
|
|
223005
|
-
setLoadError("We could not load the mailing-list choices. Try again.");
|
|
223006
|
-
}
|
|
223007
|
-
}
|
|
223008
|
-
}, [load, siteId]);
|
|
223009
|
-
useEffect(() => {
|
|
223010
|
-
refresh();
|
|
223011
|
-
}, [refresh]);
|
|
223012
|
-
const targeting = value ?? { mode: "default" };
|
|
223013
|
-
return /* @__PURE__ */ jsx(FieldFrame, {
|
|
223014
|
-
fieldPath: path,
|
|
223015
|
-
label: config.label,
|
|
223016
|
-
description: config.description,
|
|
223017
|
-
error: error?.message ?? loadError,
|
|
223018
|
-
children: () => loadState.tag === "loaded" && loadState.context.tag === "configured" && providerDefaultIsAvailable(loadState.context) ? /* @__PURE__ */ jsxs("div", {
|
|
223019
|
-
className: "space-y-3",
|
|
223020
|
-
children: [/* @__PURE__ */ jsx(MailingListTargetingControl, {
|
|
223021
|
-
context: loadState.context,
|
|
223022
|
-
targeting,
|
|
223023
|
-
onChange: setValue,
|
|
223024
|
-
name: path
|
|
223025
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
223026
|
-
className: "flex gap-3 text-xs font-medium",
|
|
223027
|
-
children: [manageHref ? /* @__PURE__ */ jsx("a", {
|
|
223028
|
-
className: "text-primary hover:underline",
|
|
223029
|
-
href: manageHref,
|
|
223030
|
-
children: "Manage mailing list"
|
|
223031
|
-
}) : null, /* @__PURE__ */ jsx("button", {
|
|
223032
|
-
type: "button",
|
|
223033
|
-
className: "text-primary hover:underline",
|
|
223034
|
-
onClick: () => void refresh(),
|
|
223035
|
-
children: "Refresh choices"
|
|
223036
|
-
})]
|
|
223037
|
-
})]
|
|
223038
|
-
}) : /* @__PURE__ */ jsxs("div", {
|
|
223039
|
-
className: "rounded-md border border-dashed p-3 text-sm text-muted-foreground",
|
|
223040
|
-
children: [loadState.tag === "loading" ? "Loading mailing-list setup…" : loadState.tag === "failed" ? "We could not load the mailing-list setup." : loadState.context.tag === "configured" ? "The provider connection or default choice needs attention. Check Mailing list setup, then refresh choices." : "Set up a mailing list before configuring this form.", loadState.tag === "failed" ? /* @__PURE__ */ jsx("button", {
|
|
223041
|
-
type: "button",
|
|
223042
|
-
className: "ml-2 underline",
|
|
223043
|
-
onClick: () => void refresh(),
|
|
223044
|
-
children: "Try again"
|
|
223045
|
-
}) : null]
|
|
223046
|
-
})
|
|
223047
|
-
});
|
|
223048
|
-
}
|
|
223049
|
-
function MailingListTargetingControl({ context, targeting, onChange, name }) {
|
|
223050
|
-
if (!hasConfigurableTargetingChoices(context)) return /* @__PURE__ */ jsxs("div", {
|
|
223051
|
-
className: "space-y-1 text-sm",
|
|
223052
|
-
children: [
|
|
223053
|
-
/* @__PURE__ */ jsx("p", {
|
|
223054
|
-
className: "font-medium",
|
|
223055
|
-
children: "Subscribers join"
|
|
223056
|
-
}),
|
|
223057
|
-
/* @__PURE__ */ jsx("p", { children: defaultLabel(context).replace("Use the site default: ", "") }),
|
|
223058
|
-
/* @__PURE__ */ jsx("p", {
|
|
223059
|
-
className: "text-xs text-muted-foreground",
|
|
223060
|
-
children: "This is the only available choice, so it is used automatically."
|
|
223061
|
-
})
|
|
223062
|
-
]
|
|
223063
|
-
});
|
|
223064
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
223065
|
-
className: "space-y-3",
|
|
223066
|
-
children: [
|
|
223067
|
-
/* @__PURE__ */ jsx(Choice, {
|
|
223068
|
-
checked: targeting.mode === "default",
|
|
223069
|
-
label: defaultLabel(context),
|
|
223070
|
-
name: `${name}-mode`,
|
|
223071
|
-
onChange: () => onChange({ mode: "default" })
|
|
223072
|
-
}),
|
|
223073
|
-
/* @__PURE__ */ jsx(Choice, {
|
|
223074
|
-
checked: targeting.mode === "custom",
|
|
223075
|
-
label: "Choose what this form signs people up to",
|
|
223076
|
-
name: `${name}-mode`,
|
|
223077
|
-
onChange: () => onChange(createInitialCustom(context))
|
|
223078
|
-
}),
|
|
223079
|
-
targeting.mode === "custom" ? /* @__PURE__ */ jsx(CustomTargeting, {
|
|
223080
|
-
context,
|
|
223081
|
-
targeting,
|
|
223082
|
-
setValue: onChange,
|
|
223083
|
-
name
|
|
223084
|
-
}) : null
|
|
223085
|
-
]
|
|
223086
|
-
});
|
|
223087
|
-
}
|
|
223088
|
-
function hasConfigurableTargetingChoices(context) {
|
|
223777
|
+
//#region ../editor-blocks/src/widgets/mailing-list-targeting/targetingState.ts
|
|
223778
|
+
/** The name of the site's default topic/list/audience, or null when it no longer exists. */
|
|
223779
|
+
function defaultItemName(context) {
|
|
223089
223780
|
const provider = context.provider;
|
|
223090
|
-
|
|
223091
|
-
case "native": return provider.topics.length > 1;
|
|
223092
|
-
case "brevo": return provider.lists.length > 1;
|
|
223093
|
-
case "mailchimp": return provider.audiences.length > 1 || provider.audiences.some((audience) => audience.interests.length > 0);
|
|
223094
|
-
}
|
|
223781
|
+
return (provider.provider === "native" ? provider.topics.find((value) => value.id === provider.defaultTopicId) : provider.provider === "brevo" ? provider.lists.find((value) => value.id === provider.defaultListId) : provider.audiences.find((value) => value.id === provider.defaultAudienceId))?.name ?? null;
|
|
223095
223782
|
}
|
|
223096
|
-
|
|
223097
|
-
|
|
223098
|
-
|
|
223099
|
-
|
|
223100
|
-
|
|
223101
|
-
|
|
223102
|
-
|
|
223103
|
-
children: "Use the site default"
|
|
223104
|
-
})]
|
|
223105
|
-
});
|
|
223106
|
-
const selectionMode = targeting.selection.tag;
|
|
223107
|
-
const setSelectionMode = (mode) => setValue(changeSelectionMode(context, targeting, mode));
|
|
223108
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
223109
|
-
className: "ml-6 space-y-3 border-l pl-4",
|
|
223110
|
-
children: [
|
|
223111
|
-
/* @__PURE__ */ jsx(Choice, {
|
|
223112
|
-
checked: selectionMode === "fixed",
|
|
223113
|
-
label: "Automatically add people to",
|
|
223114
|
-
name: `${name}-selection-mode`,
|
|
223115
|
-
onChange: () => setSelectionMode("fixed")
|
|
223116
|
-
}),
|
|
223117
|
-
/* @__PURE__ */ jsx(Choice, {
|
|
223118
|
-
checked: selectionMode === "visitor_choice",
|
|
223119
|
-
disabled: !canOfferVisitorChoice(context, targeting),
|
|
223120
|
-
label: "Let people choose",
|
|
223121
|
-
name: `${name}-selection-mode`,
|
|
223122
|
-
onChange: () => setSelectionMode("visitor_choice")
|
|
223123
|
-
}),
|
|
223124
|
-
targeting.provider === "mailchimp" ? /* @__PURE__ */ jsx(MailchimpChoices, {
|
|
223125
|
-
context,
|
|
223126
|
-
targeting,
|
|
223127
|
-
setValue,
|
|
223128
|
-
name
|
|
223129
|
-
}) : /* @__PURE__ */ jsx(ListChoices, {
|
|
223130
|
-
context,
|
|
223131
|
-
targeting,
|
|
223132
|
-
setValue,
|
|
223133
|
-
name
|
|
223134
|
-
})
|
|
223135
|
-
]
|
|
223136
|
-
});
|
|
223137
|
-
}
|
|
223138
|
-
function ListChoices({ context, targeting, setValue }) {
|
|
223139
|
-
const options = context.provider.provider === "native" ? context.provider.topics : context.provider.provider === "brevo" ? context.provider.lists : [];
|
|
223140
|
-
const selected = targeting.provider === "native" ? targeting.selection.tag === "fixed" ? targeting.selection.topicIds : targeting.selection.offeredTopicIds : targeting.provider === "brevo" ? targeting.selection.tag === "fixed" ? targeting.selection.listIds : targeting.selection.offeredListIds : [];
|
|
223141
|
-
if (options.length === 0) return /* @__PURE__ */ jsx("p", {
|
|
223142
|
-
className: "text-sm text-muted-foreground",
|
|
223143
|
-
children: "No choices are available yet. Add one in Mailing list, then refresh choices."
|
|
223144
|
-
});
|
|
223145
|
-
return /* @__PURE__ */ jsx(Checkboxes, {
|
|
223146
|
-
options,
|
|
223147
|
-
selected: selected.map(String),
|
|
223148
|
-
requireOne: true,
|
|
223149
|
-
onToggle: (id) => {
|
|
223150
|
-
const ids = toggleRequired(selected.map(String), id);
|
|
223151
|
-
if (targeting.provider === "native") {
|
|
223152
|
-
const parsed = ids.flatMap((item) => {
|
|
223153
|
-
const value = parseNewsletterListId(item);
|
|
223154
|
-
return value ? [value] : [];
|
|
223155
|
-
});
|
|
223156
|
-
if (!parsed[0]) return;
|
|
223157
|
-
setValue({
|
|
223158
|
-
mode: "custom",
|
|
223159
|
-
provider: "native",
|
|
223160
|
-
selection: targeting.selection.tag === "fixed" ? {
|
|
223161
|
-
tag: "fixed",
|
|
223162
|
-
topicIds: [parsed[0], ...parsed.slice(1)]
|
|
223163
|
-
} : {
|
|
223164
|
-
tag: "visitor_choice",
|
|
223165
|
-
offeredTopicIds: [parsed[0], ...parsed.slice(1)]
|
|
223166
|
-
}
|
|
223167
|
-
});
|
|
223168
|
-
} else if (targeting.provider === "brevo") {
|
|
223169
|
-
const parsed = ids.flatMap((item) => {
|
|
223170
|
-
const value = parseBrevoListId(Number(item));
|
|
223171
|
-
return value ? [value] : [];
|
|
223172
|
-
});
|
|
223173
|
-
if (!parsed[0]) return;
|
|
223174
|
-
setValue({
|
|
223175
|
-
mode: "custom",
|
|
223176
|
-
provider: "brevo",
|
|
223177
|
-
selection: targeting.selection.tag === "fixed" ? {
|
|
223178
|
-
tag: "fixed",
|
|
223179
|
-
listIds: [parsed[0], ...parsed.slice(1)]
|
|
223180
|
-
} : {
|
|
223181
|
-
tag: "visitor_choice",
|
|
223182
|
-
offeredListIds: [parsed[0], ...parsed.slice(1)]
|
|
223183
|
-
}
|
|
223184
|
-
});
|
|
223185
|
-
}
|
|
223186
|
-
}
|
|
223187
|
-
});
|
|
223188
|
-
}
|
|
223189
|
-
function MailchimpChoices({ context, targeting, setValue }) {
|
|
223190
|
-
if (context.provider.provider !== "mailchimp" || targeting.provider !== "mailchimp") return null;
|
|
223191
|
-
const audience = context.provider.audiences.find((item) => item.id === targeting.audienceId);
|
|
223192
|
-
const selected = targeting.selection.tag === "fixed" ? targeting.selection.interestIds : targeting.selection.offeredInterestIds;
|
|
223193
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
223194
|
-
className: "space-y-3",
|
|
223195
|
-
children: [
|
|
223196
|
-
/* @__PURE__ */ jsx("select", {
|
|
223197
|
-
className: inputClass$2,
|
|
223198
|
-
"aria-label": "Mailchimp audience",
|
|
223199
|
-
value: targeting.audienceId,
|
|
223200
|
-
onChange: (event) => {
|
|
223201
|
-
const audienceId = parseMailchimpAudienceId(event.target.value);
|
|
223202
|
-
if (!audienceId) return;
|
|
223203
|
-
setValue({
|
|
223204
|
-
mode: "custom",
|
|
223205
|
-
provider: "mailchimp",
|
|
223206
|
-
audienceId,
|
|
223207
|
-
selection: {
|
|
223208
|
-
tag: "fixed",
|
|
223209
|
-
interestIds: []
|
|
223210
|
-
}
|
|
223211
|
-
});
|
|
223212
|
-
},
|
|
223213
|
-
children: context.provider.audiences.map((item) => /* @__PURE__ */ jsx("option", {
|
|
223214
|
-
value: item.id,
|
|
223215
|
-
children: item.name
|
|
223216
|
-
}, item.id))
|
|
223217
|
-
}),
|
|
223218
|
-
/* @__PURE__ */ jsx(Checkboxes, {
|
|
223219
|
-
options: audience?.interests ?? [],
|
|
223220
|
-
selected: selected.map(String),
|
|
223221
|
-
requireOne: targeting.selection.tag === "visitor_choice",
|
|
223222
|
-
onToggle: (id) => {
|
|
223223
|
-
const parsed = toggle(selected.map(String), id).flatMap((item) => {
|
|
223224
|
-
const value = parseMailchimpInterestId(item);
|
|
223225
|
-
return value ? [value] : [];
|
|
223226
|
-
});
|
|
223227
|
-
setValue({
|
|
223228
|
-
...targeting,
|
|
223229
|
-
selection: targeting.selection.tag === "fixed" ? {
|
|
223230
|
-
tag: "fixed",
|
|
223231
|
-
interestIds: parsed
|
|
223232
|
-
} : parsed[0] ? {
|
|
223233
|
-
tag: "visitor_choice",
|
|
223234
|
-
offeredInterestIds: [parsed[0], ...parsed.slice(1)]
|
|
223235
|
-
} : targeting.selection
|
|
223236
|
-
});
|
|
223237
|
-
}
|
|
223238
|
-
}),
|
|
223239
|
-
targeting.selection.tag === "fixed" && selected.length === 0 ? /* @__PURE__ */ jsx("p", {
|
|
223240
|
-
className: "text-xs text-muted-foreground",
|
|
223241
|
-
children: "No interests selected: people join the audience without an interest."
|
|
223242
|
-
}) : null
|
|
223243
|
-
]
|
|
223244
|
-
});
|
|
223245
|
-
}
|
|
223246
|
-
function Checkboxes({ options, selected, onToggle, requireOne = false }) {
|
|
223247
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
223248
|
-
className: "space-y-2",
|
|
223249
|
-
children: [options.map((item) => {
|
|
223250
|
-
const id = String(item.id);
|
|
223251
|
-
return /* @__PURE__ */ jsxs("label", {
|
|
223252
|
-
className: "flex items-center gap-2 text-sm",
|
|
223253
|
-
children: [/* @__PURE__ */ jsx("input", {
|
|
223254
|
-
type: "checkbox",
|
|
223255
|
-
checked: selected.includes(id),
|
|
223256
|
-
disabled: requireOne && selected.length === 1 && selected.includes(id),
|
|
223257
|
-
onChange: () => onToggle(id)
|
|
223258
|
-
}), item.name]
|
|
223259
|
-
}, id);
|
|
223260
|
-
}), requireOne && selected.length === 1 ? /* @__PURE__ */ jsx("p", {
|
|
223261
|
-
className: "text-xs text-muted-foreground",
|
|
223262
|
-
children: "At least one choice is required."
|
|
223263
|
-
}) : null]
|
|
223264
|
-
});
|
|
223265
|
-
}
|
|
223266
|
-
function Choice({ checked, disabled, label, name, onChange }) {
|
|
223267
|
-
return /* @__PURE__ */ jsxs("label", {
|
|
223268
|
-
className: "flex items-center gap-2 text-sm",
|
|
223269
|
-
children: [/* @__PURE__ */ jsx("input", {
|
|
223270
|
-
type: "radio",
|
|
223271
|
-
checked,
|
|
223272
|
-
disabled,
|
|
223273
|
-
name,
|
|
223274
|
-
onChange
|
|
223275
|
-
}), label]
|
|
223276
|
-
});
|
|
223783
|
+
/** What the editor is choosing between, in the provider's own words. */
|
|
223784
|
+
function choiceNoun(context, form = "plural") {
|
|
223785
|
+
switch (context.provider.provider) {
|
|
223786
|
+
case "native": return form === "plural" ? "topics" : "topic";
|
|
223787
|
+
case "brevo": return form === "plural" ? "lists" : "list";
|
|
223788
|
+
case "mailchimp": return form === "plural" ? "interests" : "audience";
|
|
223789
|
+
}
|
|
223277
223790
|
}
|
|
223278
|
-
function
|
|
223279
|
-
|
|
223280
|
-
const item = provider.provider === "native" ? provider.topics.find((value) => value.id === provider.defaultTopicId) : provider.provider === "brevo" ? provider.lists.find((value) => value.id === provider.defaultListId) : provider.audiences.find((value) => value.id === provider.defaultAudienceId);
|
|
223281
|
-
return `Use the site default${item ? `: ${item.name}` : ""}`;
|
|
223791
|
+
function providerDisplayName(context) {
|
|
223792
|
+
return mailingListProviderName(context.provider.provider);
|
|
223282
223793
|
}
|
|
223283
223794
|
function providerDefaultIsAvailable(context) {
|
|
223284
223795
|
const provider = context.provider;
|
|
223285
223796
|
switch (provider.provider) {
|
|
223286
|
-
case "native": return provider.topics
|
|
223287
|
-
case "brevo": return provider.lists
|
|
223288
|
-
case "mailchimp": return provider.audiences
|
|
223797
|
+
case "native": return includesId(provider.topics, provider.defaultTopicId);
|
|
223798
|
+
case "brevo": return includesId(provider.lists, provider.defaultListId);
|
|
223799
|
+
case "mailchimp": return includesId(provider.audiences, provider.defaultAudienceId);
|
|
223289
223800
|
}
|
|
223290
223801
|
}
|
|
223802
|
+
function includesId(items, id) {
|
|
223803
|
+
return items.some((item) => item.id === id);
|
|
223804
|
+
}
|
|
223291
223805
|
function createInitialCustom(context) {
|
|
223292
223806
|
switch (context.provider.provider) {
|
|
223293
223807
|
case "native": return {
|
|
@@ -223374,6 +223888,425 @@ function toggleRequired(values, id) {
|
|
|
223374
223888
|
return next.length > 0 ? next : [...values];
|
|
223375
223889
|
}
|
|
223376
223890
|
//#endregion
|
|
223891
|
+
//#region ../editor-blocks/src/widgets/mailing-list-targeting/MailingListGlobalSettingsSummary.tsx
|
|
223892
|
+
/**
|
|
223893
|
+
* The read-only "what every signup on this site shares" card. Editors only
|
|
223894
|
+
* choose targeting; fields, confirmation and copy are set once by an
|
|
223895
|
+
* administrator, so this tells them what they are working inside of.
|
|
223896
|
+
*/
|
|
223897
|
+
function MailingListGlobalSettingsSummary({ context }) {
|
|
223898
|
+
if (context.runtime.tag !== "configured") return null;
|
|
223899
|
+
const confirmation = context.confirmation?.tag === "on" ? "Email confirmation is on" : "Email confirmation is off";
|
|
223900
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
223901
|
+
className: "rounded-md bg-muted/50 p-3 text-xs text-muted-foreground",
|
|
223902
|
+
children: [/* @__PURE__ */ jsxs("p", {
|
|
223903
|
+
className: "font-medium text-foreground",
|
|
223904
|
+
children: [providerDisplayName(context.runtime), /* @__PURE__ */ jsx("span", {
|
|
223905
|
+
className: "ml-2 font-normal text-muted-foreground",
|
|
223906
|
+
children: "Shared form settings"
|
|
223907
|
+
})]
|
|
223908
|
+
}), /* @__PURE__ */ jsxs("p", { children: [
|
|
223909
|
+
"Shared across your site: ",
|
|
223910
|
+
globalFieldsSummary(context.runtime.form),
|
|
223911
|
+
". ",
|
|
223912
|
+
confirmation,
|
|
223913
|
+
"."
|
|
223914
|
+
] })]
|
|
223915
|
+
});
|
|
223916
|
+
}
|
|
223917
|
+
/** Mid-sentence phrasing, so it reads on from "Shared across your site:". */
|
|
223918
|
+
function globalFieldsSummary(form) {
|
|
223919
|
+
const phone = form.includeOptionalPhone ? ", plus optional phone" : "";
|
|
223920
|
+
switch (form.fields.preset) {
|
|
223921
|
+
case "emailOnly": return `email only${phone}`;
|
|
223922
|
+
case "emailName": return `email and ${form.fields.name} name${phone}`;
|
|
223923
|
+
case "emailFirstLast": return `email, ${form.fields.firstName} first name and ${form.fields.lastName} last name${phone}`;
|
|
223924
|
+
case "emailNameCompany": return `email, ${form.fields.name} name and ${form.fields.company} company${phone}`;
|
|
223925
|
+
}
|
|
223926
|
+
}
|
|
223927
|
+
//#endregion
|
|
223928
|
+
//#region ../editor-blocks/src/widgets/mailing-list-targeting/MailingListTargetingField.tsx
|
|
223929
|
+
const inputClass$2 = "w-full rounded-md border bg-background px-3 py-2 text-sm";
|
|
223930
|
+
function MailingListTargetingField({ path, backend, config }) {
|
|
223931
|
+
const { value, error, setValue } = useField(path, backend);
|
|
223932
|
+
const { siteId, load, manageHref } = useMailingListTargetingContext();
|
|
223933
|
+
const [loadState, setLoadState] = useState({ tag: "loading" });
|
|
223934
|
+
const [loadError, setLoadError] = useState(null);
|
|
223935
|
+
const requestVersion = useRef(0);
|
|
223936
|
+
const refresh = useCallback(async () => {
|
|
223937
|
+
const version = requestVersion.current + 1;
|
|
223938
|
+
requestVersion.current = version;
|
|
223939
|
+
setLoadState({ tag: "loading" });
|
|
223940
|
+
setLoadError(null);
|
|
223941
|
+
try {
|
|
223942
|
+
const context = await load(siteId);
|
|
223943
|
+
if (requestVersion.current === version) setLoadState({
|
|
223944
|
+
tag: "loaded",
|
|
223945
|
+
context
|
|
223946
|
+
});
|
|
223947
|
+
} catch {
|
|
223948
|
+
if (requestVersion.current === version) {
|
|
223949
|
+
setLoadState({ tag: "failed" });
|
|
223950
|
+
setLoadError("We could not load the mailing-list choices. Try again.");
|
|
223951
|
+
}
|
|
223952
|
+
}
|
|
223953
|
+
}, [load, siteId]);
|
|
223954
|
+
useEffect(() => {
|
|
223955
|
+
refresh();
|
|
223956
|
+
}, [refresh]);
|
|
223957
|
+
const targeting = value ?? { mode: "default" };
|
|
223958
|
+
return /* @__PURE__ */ jsx(FieldFrame, {
|
|
223959
|
+
fieldPath: path,
|
|
223960
|
+
label: config.label,
|
|
223961
|
+
description: config.description,
|
|
223962
|
+
error: error?.message ?? loadError,
|
|
223963
|
+
children: () => loadState.tag === "loaded" && loadState.context.runtime.tag === "configured" && providerDefaultIsAvailable(loadState.context.runtime) ? /* @__PURE__ */ jsxs("div", {
|
|
223964
|
+
className: "space-y-3",
|
|
223965
|
+
children: [
|
|
223966
|
+
/* @__PURE__ */ jsx(MailingListGlobalSettingsSummary, { context: loadState.context }),
|
|
223967
|
+
/* @__PURE__ */ jsx(MailingListTargetingControl, {
|
|
223968
|
+
context: loadState.context.runtime,
|
|
223969
|
+
targeting,
|
|
223970
|
+
onChange: setValue,
|
|
223971
|
+
name: path
|
|
223972
|
+
}),
|
|
223973
|
+
/* @__PURE__ */ jsxs("div", {
|
|
223974
|
+
className: "flex gap-3 text-xs font-medium",
|
|
223975
|
+
children: [manageHref && loadState.context.canManageSetup ? /* @__PURE__ */ jsx("a", {
|
|
223976
|
+
className: "text-primary hover:underline",
|
|
223977
|
+
href: manageHref,
|
|
223978
|
+
children: "Manage mailing list"
|
|
223979
|
+
}) : /* @__PURE__ */ jsx("span", {
|
|
223980
|
+
className: "text-muted-foreground",
|
|
223981
|
+
children: "Ask an administrator to change these settings."
|
|
223982
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
223983
|
+
type: "button",
|
|
223984
|
+
className: "text-primary hover:underline",
|
|
223985
|
+
onClick: () => void refresh(),
|
|
223986
|
+
children: "Refresh choices"
|
|
223987
|
+
})]
|
|
223988
|
+
})
|
|
223989
|
+
]
|
|
223990
|
+
}) : /* @__PURE__ */ jsxs("div", {
|
|
223991
|
+
className: "rounded-md border border-dashed p-3 text-sm text-muted-foreground",
|
|
223992
|
+
children: [loadState.tag === "loading" ? "Loading mailing-list setup…" : loadState.tag === "failed" ? "We could not load the mailing-list setup." : loadState.context.runtime.tag === "configured" ? "The provider connection or default choice needs attention. Check Mailing list setup, then refresh choices." : "Set up a mailing list before configuring this form.", loadState.tag === "failed" ? /* @__PURE__ */ jsx("button", {
|
|
223993
|
+
type: "button",
|
|
223994
|
+
className: "ml-2 underline",
|
|
223995
|
+
onClick: () => void refresh(),
|
|
223996
|
+
children: "Try again"
|
|
223997
|
+
}) : null]
|
|
223998
|
+
})
|
|
223999
|
+
});
|
|
224000
|
+
}
|
|
224001
|
+
function MailingListTargetingControl({ context, targeting, onChange, name }) {
|
|
224002
|
+
if (!hasConfigurableTargetingChoices(context)) return /* @__PURE__ */ jsxs("div", {
|
|
224003
|
+
className: "space-y-1 text-sm",
|
|
224004
|
+
children: [
|
|
224005
|
+
/* @__PURE__ */ jsx("p", {
|
|
224006
|
+
className: "font-medium",
|
|
224007
|
+
children: "Subscribers join"
|
|
224008
|
+
}),
|
|
224009
|
+
/* @__PURE__ */ jsx("p", { children: defaultItemName(context) ?? "the site default" }),
|
|
224010
|
+
/* @__PURE__ */ jsxs("p", {
|
|
224011
|
+
className: "text-xs text-muted-foreground",
|
|
224012
|
+
children: [
|
|
224013
|
+
"This is your only ",
|
|
224014
|
+
choiceNoun(context, "singular"),
|
|
224015
|
+
", so it is used automatically."
|
|
224016
|
+
]
|
|
224017
|
+
})
|
|
224018
|
+
]
|
|
224019
|
+
});
|
|
224020
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
224021
|
+
className: "space-y-3",
|
|
224022
|
+
children: [
|
|
224023
|
+
/* @__PURE__ */ jsxs("fieldset", {
|
|
224024
|
+
className: "space-y-2",
|
|
224025
|
+
children: [
|
|
224026
|
+
/* @__PURE__ */ jsx("legend", {
|
|
224027
|
+
className: legendClass,
|
|
224028
|
+
children: "Signup destination"
|
|
224029
|
+
}),
|
|
224030
|
+
/* @__PURE__ */ jsx(Choice, {
|
|
224031
|
+
checked: targeting.mode === "default",
|
|
224032
|
+
label: "Use site default",
|
|
224033
|
+
description: defaultItemName(context) ?? void 0,
|
|
224034
|
+
name: `${name}-mode`,
|
|
224035
|
+
onChange: () => onChange({ mode: "default" })
|
|
224036
|
+
}),
|
|
224037
|
+
/* @__PURE__ */ jsx(Choice, {
|
|
224038
|
+
checked: targeting.mode === "custom",
|
|
224039
|
+
label: "Customise this signup",
|
|
224040
|
+
name: `${name}-mode`,
|
|
224041
|
+
onChange: () => onChange(createInitialCustom(context))
|
|
224042
|
+
})
|
|
224043
|
+
]
|
|
224044
|
+
}),
|
|
224045
|
+
targeting.mode === "custom" ? /* @__PURE__ */ jsx(CustomTargeting, {
|
|
224046
|
+
context,
|
|
224047
|
+
targeting,
|
|
224048
|
+
setValue: onChange,
|
|
224049
|
+
name
|
|
224050
|
+
}) : null,
|
|
224051
|
+
/* @__PURE__ */ jsx("p", {
|
|
224052
|
+
className: "text-xs text-muted-foreground",
|
|
224053
|
+
children: "Subscription choices should match what your form promises."
|
|
224054
|
+
})
|
|
224055
|
+
]
|
|
224056
|
+
});
|
|
224057
|
+
}
|
|
224058
|
+
const legendClass = "mb-1 text-sm font-medium";
|
|
224059
|
+
function hasConfigurableTargetingChoices(context) {
|
|
224060
|
+
const provider = context.provider;
|
|
224061
|
+
switch (provider.provider) {
|
|
224062
|
+
case "native": return provider.topics.length > 1;
|
|
224063
|
+
case "brevo": return provider.lists.length > 1;
|
|
224064
|
+
case "mailchimp": return provider.audiences.length > 1 || provider.audiences.some((audience) => audience.interests.length > 0);
|
|
224065
|
+
}
|
|
224066
|
+
}
|
|
224067
|
+
function CustomTargeting({ context, targeting, setValue, name }) {
|
|
224068
|
+
if (context.provider.provider !== targeting.provider) return /* @__PURE__ */ jsxs("div", {
|
|
224069
|
+
className: "space-y-2 rounded-md border border-dashed p-3 text-sm text-muted-foreground",
|
|
224070
|
+
children: [/* @__PURE__ */ jsx("p", { children: "The mailing-list setup changed, so this form's previous choices no longer apply. Reset it to the site default to keep editing." }), /* @__PURE__ */ jsx("button", {
|
|
224071
|
+
type: "button",
|
|
224072
|
+
className: "font-medium text-primary underline",
|
|
224073
|
+
onClick: () => setValue({ mode: "default" }),
|
|
224074
|
+
children: "Use the site default"
|
|
224075
|
+
})]
|
|
224076
|
+
});
|
|
224077
|
+
const selectionMode = targeting.selection.tag;
|
|
224078
|
+
const setSelectionMode = (mode) => setValue(changeSelectionMode(context, targeting, mode));
|
|
224079
|
+
const noun = choiceNoun(context);
|
|
224080
|
+
const visitorChoiceAllowed = canOfferVisitorChoice(context, targeting);
|
|
224081
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
224082
|
+
className: "ml-6 space-y-3 border-l pl-4",
|
|
224083
|
+
children: [
|
|
224084
|
+
targeting.provider === "mailchimp" ? /* @__PURE__ */ jsx(MailchimpAudience, {
|
|
224085
|
+
context,
|
|
224086
|
+
targeting,
|
|
224087
|
+
setValue,
|
|
224088
|
+
name
|
|
224089
|
+
}) : null,
|
|
224090
|
+
/* @__PURE__ */ jsxs("fieldset", {
|
|
224091
|
+
className: "space-y-2",
|
|
224092
|
+
children: [
|
|
224093
|
+
/* @__PURE__ */ jsxs("legend", {
|
|
224094
|
+
className: legendClass,
|
|
224095
|
+
children: [
|
|
224096
|
+
"How are ",
|
|
224097
|
+
noun,
|
|
224098
|
+
" chosen?"
|
|
224099
|
+
]
|
|
224100
|
+
}),
|
|
224101
|
+
/* @__PURE__ */ jsx(Choice, {
|
|
224102
|
+
checked: selectionMode === "fixed",
|
|
224103
|
+
label: "I choose",
|
|
224104
|
+
description: `Automatically subscribe to selected ${noun}.`,
|
|
224105
|
+
name: `${name}-selection-mode`,
|
|
224106
|
+
onChange: () => setSelectionMode("fixed")
|
|
224107
|
+
}),
|
|
224108
|
+
/* @__PURE__ */ jsx(Choice, {
|
|
224109
|
+
checked: selectionMode === "visitor_choice",
|
|
224110
|
+
disabled: !visitorChoiceAllowed,
|
|
224111
|
+
label: "Let visitors choose",
|
|
224112
|
+
description: visitorChoiceAllowed ? "Show these options on the form." : "Pick an audience with interests to offer visitors a choice.",
|
|
224113
|
+
name: `${name}-selection-mode`,
|
|
224114
|
+
onChange: () => setSelectionMode("visitor_choice")
|
|
224115
|
+
})
|
|
224116
|
+
]
|
|
224117
|
+
}),
|
|
224118
|
+
targeting.provider === "mailchimp" ? /* @__PURE__ */ jsx(MailchimpChoices, {
|
|
224119
|
+
context,
|
|
224120
|
+
targeting,
|
|
224121
|
+
setValue,
|
|
224122
|
+
name
|
|
224123
|
+
}) : /* @__PURE__ */ jsx(ListChoices, {
|
|
224124
|
+
context,
|
|
224125
|
+
targeting,
|
|
224126
|
+
setValue,
|
|
224127
|
+
name
|
|
224128
|
+
}),
|
|
224129
|
+
/* @__PURE__ */ jsx("p", {
|
|
224130
|
+
className: "text-xs text-muted-foreground",
|
|
224131
|
+
children: selectionMode === "visitor_choice" ? "Offer at least one choice; visitors choose what they want to hear about." : targeting.provider === "mailchimp" ? "People join the audience, with any interests you tick applied to them." : `Visitors join the selected ${noun} without a picker.`
|
|
224132
|
+
})
|
|
224133
|
+
]
|
|
224134
|
+
});
|
|
224135
|
+
}
|
|
224136
|
+
function ListChoices({ context, targeting, setValue }) {
|
|
224137
|
+
const options = context.provider.provider === "native" ? context.provider.topics : context.provider.provider === "brevo" ? context.provider.lists : [];
|
|
224138
|
+
const selected = targeting.provider === "native" ? targeting.selection.tag === "fixed" ? targeting.selection.topicIds : targeting.selection.offeredTopicIds : targeting.provider === "brevo" ? targeting.selection.tag === "fixed" ? targeting.selection.listIds : targeting.selection.offeredListIds : [];
|
|
224139
|
+
if (options.length === 0) return /* @__PURE__ */ jsx("p", {
|
|
224140
|
+
className: "text-sm text-muted-foreground",
|
|
224141
|
+
children: "No choices are available yet. Add one in Mailing list, then refresh choices."
|
|
224142
|
+
});
|
|
224143
|
+
return /* @__PURE__ */ jsx(Checkboxes, {
|
|
224144
|
+
options,
|
|
224145
|
+
selected: selected.map(String),
|
|
224146
|
+
requireOne: true,
|
|
224147
|
+
onToggle: (id) => {
|
|
224148
|
+
const ids = toggleRequired(selected.map(String), id);
|
|
224149
|
+
if (targeting.provider === "native") {
|
|
224150
|
+
const parsed = ids.flatMap((item) => {
|
|
224151
|
+
const value = parseNewsletterListId(item);
|
|
224152
|
+
return value ? [value] : [];
|
|
224153
|
+
});
|
|
224154
|
+
if (!parsed[0]) return;
|
|
224155
|
+
setValue({
|
|
224156
|
+
mode: "custom",
|
|
224157
|
+
provider: "native",
|
|
224158
|
+
selection: targeting.selection.tag === "fixed" ? {
|
|
224159
|
+
tag: "fixed",
|
|
224160
|
+
topicIds: [parsed[0], ...parsed.slice(1)]
|
|
224161
|
+
} : {
|
|
224162
|
+
tag: "visitor_choice",
|
|
224163
|
+
offeredTopicIds: [parsed[0], ...parsed.slice(1)]
|
|
224164
|
+
}
|
|
224165
|
+
});
|
|
224166
|
+
} else if (targeting.provider === "brevo") {
|
|
224167
|
+
const parsed = ids.flatMap((item) => {
|
|
224168
|
+
const value = parseBrevoListId(Number(item));
|
|
224169
|
+
return value ? [value] : [];
|
|
224170
|
+
});
|
|
224171
|
+
if (!parsed[0]) return;
|
|
224172
|
+
setValue({
|
|
224173
|
+
mode: "custom",
|
|
224174
|
+
provider: "brevo",
|
|
224175
|
+
selection: targeting.selection.tag === "fixed" ? {
|
|
224176
|
+
tag: "fixed",
|
|
224177
|
+
listIds: [parsed[0], ...parsed.slice(1)]
|
|
224178
|
+
} : {
|
|
224179
|
+
tag: "visitor_choice",
|
|
224180
|
+
offeredListIds: [parsed[0], ...parsed.slice(1)]
|
|
224181
|
+
}
|
|
224182
|
+
});
|
|
224183
|
+
}
|
|
224184
|
+
}
|
|
224185
|
+
});
|
|
224186
|
+
}
|
|
224187
|
+
function MailchimpAudience({ context, targeting, setValue, name }) {
|
|
224188
|
+
if (context.provider.provider !== "mailchimp" || targeting.provider !== "mailchimp") return null;
|
|
224189
|
+
const selectId = `${name}-audience`;
|
|
224190
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
224191
|
+
className: "space-y-1",
|
|
224192
|
+
children: [/* @__PURE__ */ jsx("label", {
|
|
224193
|
+
htmlFor: selectId,
|
|
224194
|
+
className: "text-sm font-medium",
|
|
224195
|
+
children: "Audience"
|
|
224196
|
+
}), /* @__PURE__ */ jsx("select", {
|
|
224197
|
+
id: selectId,
|
|
224198
|
+
className: inputClass$2,
|
|
224199
|
+
value: targeting.audienceId,
|
|
224200
|
+
onChange: (event) => {
|
|
224201
|
+
const audienceId = parseMailchimpAudienceId(event.target.value);
|
|
224202
|
+
if (!audienceId) return;
|
|
224203
|
+
setValue({
|
|
224204
|
+
mode: "custom",
|
|
224205
|
+
provider: "mailchimp",
|
|
224206
|
+
audienceId,
|
|
224207
|
+
selection: {
|
|
224208
|
+
tag: "fixed",
|
|
224209
|
+
interestIds: []
|
|
224210
|
+
}
|
|
224211
|
+
});
|
|
224212
|
+
},
|
|
224213
|
+
children: context.provider.audiences.map((item) => /* @__PURE__ */ jsx("option", {
|
|
224214
|
+
value: item.id,
|
|
224215
|
+
children: item.name
|
|
224216
|
+
}, item.id))
|
|
224217
|
+
})]
|
|
224218
|
+
});
|
|
224219
|
+
}
|
|
224220
|
+
function MailchimpChoices({ context, targeting, setValue }) {
|
|
224221
|
+
if (context.provider.provider !== "mailchimp" || targeting.provider !== "mailchimp") return null;
|
|
224222
|
+
const audience = context.provider.audiences.find((item) => item.id === targeting.audienceId);
|
|
224223
|
+
const selected = targeting.selection.tag === "fixed" ? targeting.selection.interestIds : targeting.selection.offeredInterestIds;
|
|
224224
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
224225
|
+
className: "space-y-3",
|
|
224226
|
+
children: [/* @__PURE__ */ jsx(Checkboxes, {
|
|
224227
|
+
options: audience?.interests ?? [],
|
|
224228
|
+
selected: selected.map(String),
|
|
224229
|
+
requireOne: targeting.selection.tag === "visitor_choice",
|
|
224230
|
+
onToggle: (id) => {
|
|
224231
|
+
const parsed = toggle(selected.map(String), id).flatMap((item) => {
|
|
224232
|
+
const value = parseMailchimpInterestId(item);
|
|
224233
|
+
return value ? [value] : [];
|
|
224234
|
+
});
|
|
224235
|
+
setValue({
|
|
224236
|
+
...targeting,
|
|
224237
|
+
selection: targeting.selection.tag === "fixed" ? {
|
|
224238
|
+
tag: "fixed",
|
|
224239
|
+
interestIds: parsed
|
|
224240
|
+
} : parsed[0] ? {
|
|
224241
|
+
tag: "visitor_choice",
|
|
224242
|
+
offeredInterestIds: [parsed[0], ...parsed.slice(1)]
|
|
224243
|
+
} : targeting.selection
|
|
224244
|
+
});
|
|
224245
|
+
}
|
|
224246
|
+
}), targeting.selection.tag === "fixed" && selected.length === 0 ? /* @__PURE__ */ jsx("p", {
|
|
224247
|
+
className: "text-xs text-muted-foreground",
|
|
224248
|
+
children: "No interests selected: people join the audience without an interest."
|
|
224249
|
+
}) : null]
|
|
224250
|
+
});
|
|
224251
|
+
}
|
|
224252
|
+
function Checkboxes({ options, selected, onToggle, requireOne = false }) {
|
|
224253
|
+
const [refusedLast, setRefusedLast] = useState(false);
|
|
224254
|
+
const refusedId = useId();
|
|
224255
|
+
useEffect(() => {
|
|
224256
|
+
setRefusedLast(false);
|
|
224257
|
+
}, [selected.join("\0")]);
|
|
224258
|
+
return /* @__PURE__ */ jsxs("fieldset", {
|
|
224259
|
+
className: "space-y-2",
|
|
224260
|
+
children: [
|
|
224261
|
+
/* @__PURE__ */ jsx("legend", {
|
|
224262
|
+
className: "sr-only",
|
|
224263
|
+
children: "Available mailing-list choices"
|
|
224264
|
+
}),
|
|
224265
|
+
options.map((item) => {
|
|
224266
|
+
const id = String(item.id);
|
|
224267
|
+
const isLastSelected = requireOne && selected.length === 1 && selected.includes(id);
|
|
224268
|
+
return /* @__PURE__ */ jsxs("label", {
|
|
224269
|
+
className: "flex items-center gap-2 text-sm",
|
|
224270
|
+
children: [/* @__PURE__ */ jsx("input", {
|
|
224271
|
+
type: "checkbox",
|
|
224272
|
+
checked: selected.includes(id),
|
|
224273
|
+
"aria-describedby": isLastSelected && refusedLast ? refusedId : void 0,
|
|
224274
|
+
onChange: () => {
|
|
224275
|
+
if (isLastSelected) {
|
|
224276
|
+
setRefusedLast(true);
|
|
224277
|
+
return;
|
|
224278
|
+
}
|
|
224279
|
+
onToggle(id);
|
|
224280
|
+
}
|
|
224281
|
+
}), item.name]
|
|
224282
|
+
}, id);
|
|
224283
|
+
}),
|
|
224284
|
+
refusedLast && requireOne && selected.length === 1 ? /* @__PURE__ */ jsx("p", {
|
|
224285
|
+
id: refusedId,
|
|
224286
|
+
role: "status",
|
|
224287
|
+
className: "text-xs text-muted-foreground",
|
|
224288
|
+
children: "Keep at least one selected."
|
|
224289
|
+
}) : null
|
|
224290
|
+
]
|
|
224291
|
+
});
|
|
224292
|
+
}
|
|
224293
|
+
function Choice({ checked, disabled, label, description, name, onChange }) {
|
|
224294
|
+
return /* @__PURE__ */ jsxs("label", {
|
|
224295
|
+
className: "flex items-start gap-2 text-sm",
|
|
224296
|
+
children: [/* @__PURE__ */ jsx("input", {
|
|
224297
|
+
type: "radio",
|
|
224298
|
+
className: "mt-1",
|
|
224299
|
+
checked,
|
|
224300
|
+
disabled,
|
|
224301
|
+
name,
|
|
224302
|
+
onChange
|
|
224303
|
+
}), /* @__PURE__ */ jsxs("span", { children: [label, description ? /* @__PURE__ */ jsx("span", {
|
|
224304
|
+
className: "block text-xs text-muted-foreground",
|
|
224305
|
+
children: description
|
|
224306
|
+
}) : null] })]
|
|
224307
|
+
});
|
|
224308
|
+
}
|
|
224309
|
+
//#endregion
|
|
223377
224310
|
//#region ../editor-blocks/src/widgets/offerings-preview/OfferingsPreviewWidgetProvider.tsx
|
|
223378
224311
|
const OfferingsPreviewWidgetContext = createContext(null);
|
|
223379
224312
|
function OfferingsPreviewWidgetProvider({ bookingOfferingPresets, children }) {
|
|
@@ -224497,9 +225430,7 @@ function useInternalValue(props) {
|
|
|
224497
225430
|
};
|
|
224498
225431
|
}, [uiStore]);
|
|
224499
225432
|
const setEntry = (next) => {
|
|
224500
|
-
setEntryRaw((prev) =>
|
|
224501
|
-
return typeof next === "function" ? next(prev) : next;
|
|
224502
|
-
});
|
|
225433
|
+
setEntryRaw((prev) => typeof next === "function" ? next(prev) : next);
|
|
224503
225434
|
};
|
|
224504
225435
|
useEffect(() => {
|
|
224505
225436
|
if (initialEntry) setEntry((prev) => {
|
|
@@ -224707,7 +225638,8 @@ function useInternalValue(props) {
|
|
|
224707
225638
|
apiClient,
|
|
224708
225639
|
siteId,
|
|
224709
225640
|
hasRoute,
|
|
224710
|
-
owner
|
|
225641
|
+
owner,
|
|
225642
|
+
getExpectedMailingListProviderScope: props.getExpectedMailingListProviderScope
|
|
224711
225643
|
});
|
|
224712
225644
|
const linkedEntryAutosave = useLinkedEntryAutosave({
|
|
224713
225645
|
uiStore,
|
|
@@ -225687,7 +226619,12 @@ function MailingListChoice({ dispatch, draft, manageNewsletterHref, options }) {
|
|
|
225687
226619
|
return /* @__PURE__ */ jsxs("div", {
|
|
225688
226620
|
className: "space-y-3",
|
|
225689
226621
|
children: [
|
|
225690
|
-
options.mailingList.tag === "configured" ? /* @__PURE__ */ jsx(
|
|
226622
|
+
options.mailingList.tag === "configured" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(MailingListGlobalSettingsSummary, { context: {
|
|
226623
|
+
runtime: options.mailingList,
|
|
226624
|
+
expectedProviderScope: options.expectedMailingListProviderScope,
|
|
226625
|
+
confirmation: options.confirmation,
|
|
226626
|
+
canManageSetup: options.canManageMailingListSetup
|
|
226627
|
+
} }), /* @__PURE__ */ jsx(MailingListTargetingControl, {
|
|
225691
226628
|
context: options.mailingList,
|
|
225692
226629
|
targeting: draft.targeting,
|
|
225693
226630
|
name: "footer-mailing-list-targeting",
|
|
@@ -225695,14 +226632,17 @@ function MailingListChoice({ dispatch, draft, manageNewsletterHref, options }) {
|
|
|
225695
226632
|
type: "set-mailing-targeting",
|
|
225696
226633
|
targeting
|
|
225697
226634
|
})
|
|
225698
|
-
}) : /* @__PURE__ */ jsx("p", {
|
|
226635
|
+
})] }) : /* @__PURE__ */ jsx("p", {
|
|
225699
226636
|
className: "rounded-md border border-dashed p-3 text-sm text-muted-foreground",
|
|
225700
226637
|
children: "Set up a mailing list before adding this footer form."
|
|
225701
226638
|
}),
|
|
225702
|
-
/* @__PURE__ */ jsx("a", {
|
|
226639
|
+
options.canManageMailingListSetup ? /* @__PURE__ */ jsx("a", {
|
|
225703
226640
|
className: buttonClass$3,
|
|
225704
226641
|
href: manageNewsletterHref,
|
|
225705
226642
|
children: "Manage mailing list"
|
|
226643
|
+
}) : /* @__PURE__ */ jsx("p", {
|
|
226644
|
+
className: "text-xs text-muted-foreground",
|
|
226645
|
+
children: "Ask an administrator to change shared form settings."
|
|
225706
226646
|
}),
|
|
225707
226647
|
/* @__PURE__ */ jsx("div", {
|
|
225708
226648
|
className: "text-xs text-muted-foreground",
|
|
@@ -226568,6 +227508,7 @@ function useFooterComposerState({ apiClient, canEdit, initialTarget, initialTarg
|
|
|
226568
227508
|
apiClient,
|
|
226569
227509
|
canEdit,
|
|
226570
227510
|
compositionSnapshot: loaded.compositionSnapshot,
|
|
227511
|
+
engagementOptions: loaded.engagementOptions,
|
|
226571
227512
|
onSaved,
|
|
226572
227513
|
setCompositionSnapshot: loaded.setCompositionSnapshot,
|
|
226573
227514
|
setMessage,
|
|
@@ -226637,7 +227578,7 @@ function useFooterLoad(apiClient, rawSiteId, siteId) {
|
|
|
226637
227578
|
setProfileSnapshot
|
|
226638
227579
|
};
|
|
226639
227580
|
}
|
|
226640
|
-
function useCompositionSaver({ apiClient, canEdit, compositionSnapshot, onSaved, setCompositionSnapshot, setMessage, setSaveState, siteId }) {
|
|
227581
|
+
function useCompositionSaver({ apiClient, canEdit, compositionSnapshot, engagementOptions, onSaved, setCompositionSnapshot, setMessage, setSaveState, siteId }) {
|
|
226641
227582
|
return useCallback(async (next, optimistic = true) => {
|
|
226642
227583
|
if (!canEdit || compositionSnapshot?.kind !== "ready") return "failed";
|
|
226643
227584
|
if (optimistic) setCompositionSnapshot({
|
|
@@ -226650,7 +227591,8 @@ function useCompositionSaver({ apiClient, canEdit, compositionSnapshot, onSaved,
|
|
|
226650
227591
|
try {
|
|
226651
227592
|
const result = await updateFooterComposition(apiClient, siteId, {
|
|
226652
227593
|
composition: next,
|
|
226653
|
-
baseRevision: compositionSnapshot.revision
|
|
227594
|
+
baseRevision: compositionSnapshot.revision,
|
|
227595
|
+
expectedMailingListProviderScope: engagementOptions?.expectedMailingListProviderScope ?? void 0
|
|
226654
227596
|
});
|
|
226655
227597
|
if (result.kind === "conflict") {
|
|
226656
227598
|
setCompositionSnapshot(result.authoritative);
|
|
@@ -226671,6 +227613,7 @@ function useCompositionSaver({ apiClient, canEdit, compositionSnapshot, onSaved,
|
|
|
226671
227613
|
apiClient,
|
|
226672
227614
|
canEdit,
|
|
226673
227615
|
compositionSnapshot,
|
|
227616
|
+
engagementOptions,
|
|
226674
227617
|
onSaved,
|
|
226675
227618
|
setCompositionSnapshot,
|
|
226676
227619
|
setMessage,
|
|
@@ -230364,4 +231307,4 @@ function useSiteChromeCustomizeOptional() {
|
|
|
230364
231307
|
return useContext(SiteChromeCustomizeContext);
|
|
230365
231308
|
}
|
|
230366
231309
|
//#endregion
|
|
230367
|
-
export { FooterComposerPanel as $, Monitor as $a, FieldFrame as $i, coerceLinkedContentEntriesPayload as $n,
|
|
231310
|
+
export { FooterComposerPanel as $, Monitor as $a, FieldFrame as $i, coerceLinkedContentEntriesPayload as $n, runTransforms as $r, useMultiAutosave as $t, markApplySaving as A, DropdownMenu as Aa, buttonStyleSelectionParameterValue as Ai, containerResponsiveThemeCss as An, compileTransitionRuntime as Ar, RichTextField as At, setPaletteColors as B, X as Ba, ORDINARY_TEXT_MIN_CONTRAST_RATIO as Bi, compileManifestContentContract as Bn, curatedPalettes as Br, getBlockManifestFromSdkConfig as Bt, cancelPreview as C, DialogFooter as Ca, isRecord$17 as Ci, deriveLaunchReadiness as Cn, retargetCompiledRuntimeFieldsForContentAdjacency as Cr, ButtonVariantField as Ct, isPreviewingChange as D, CollapsibleContent as Da, assertNever$7 as Di, useApiMediaUploader as Dn, curatedSiteStyles as Dr, ReferenceField as Dt, dismissWarnings as E, Collapsible as Ea, asDesignBlockId as Ei, useMediaEditorOptional as En, componentRuntimeRulesForTheme as Er, MediaField as Et, previewFooterLook as F, DropdownMenuTrigger as Fa, buttonStyleSelectionKey as Fi, SITE_CHROME_VISIBLE_HEADER_SELECTOR as Fn, gradientToCss as Fr, LinkWidgetProvider as Ft, confirmAutosaveBatch as G, Sparkles as Ga, getFieldIntent as Gi, escapeStyleContent as Gn, backgroundAppearanceColorTokenNames as Gr, canRedoHistory as Gt, syncStyleConfiguratorState as H, Undo2 as Ha, paletteColorEntries as Hi, buildThemeRuntime as Hn, sectionTransitionFamilies as Hr, useEditorUiStore as Ht, previewHeaderLayout as I, Primitive as Ia, textColorStyle as Ii, SITE_OVERLAY_HEADER_CLEARANCE_CSS_VAR as In, GRADIENT_PRESETS as Ir, BlockEditor as It, idleEditorTransactionQueueState as J, RotateCcw as Ja, useSdkConfig as Ji, defaultTransforms as Jn, ctaButton as Jr, pushHistoryEntry as Jt, deriveTransactionCapabilities as K, Smartphone as Ka, isHeaderField as Ki, readBlockComposition as Kn, backgroundAppearanceQuickColorTokenNames as Kr, canUndoHistory as Kt, previewHeaderStyle as L, Button$1 as La, defaultThemeTokens as Li, planSiteOverlayHeaderClearance as Ln, GRADIENT_PRESET_IDS as Lr, hideThemeV2RawStyleFields as Lt, palettePreviewProjection as M, DropdownMenuItem as Ma, resolveButtonStyleSelection as Mi, makeDefaultBlockComponent as Mn, findFooterLook as Mr, EditorProvider as Mt, previewButtonStyle as N, DropdownMenuLabel as Na, updateButtonStyleHoverPreference as Ni, getBlockDefinition as Nn, getHeaderLayout as Nr, useEditor$1 as Nt, markApplyFailed as O, CollapsibleTrigger as Oa, makeBoundaryId as Oi, isSupportedLoaderEndpoint as On, designRuntimeRulesForTheme as Or, ReferenceWidgetProvider as Ot, previewCuratedPalette as P, DropdownMenuSeparator as Pa, updateButtonStyleSelectionChoice as Pi, projectRecurringSchedule as Pn, getHeaderStyle as Pr, LinkField as Pt, resolvePreviewSidebarTab as Q, Palette as Qa, unmapValueFromSelect as Qi, LINKED_CONTENT_ENTRY_META_KEY as Qn, parseBackgroundContent as Qr, recordsEqual as Qt, previewSiteStyle as R, cva as Ra, themeButtonClassName as Ri, visibleHeaderClearancePx as Rn, getGradientPreset as Rr, prepareBlockEditorManifest as Rt, applyTypographyDraftPatch as S, DialogDescription as Sa, isObjectRecord$1 as Si, DEFAULT_LAUNCH_READINESS_INPUT as Sn, retargetCompiledBoundaryRuntimeForContentAdjacency as Sr, EntryPickerWidgetProvider as St, deriveStyleConfiguratorCapabilities as T, DialogTitle as Ta, pageDesignEditorBackgroundOverrideOwner as Ti, MediaEditorContextProvider as Tn, planPageDesignLayoutLookCompatibility as Tr, FileField as Tt, toggleRow as U, TriangleAlert as Ua, paletteColorsSchema as Ui, DEFAULT_THEME_RESPONSIVE_MODE as Un, sectionTransitionFamilyForBoundaryOptionId as Ur, useEditorUiStoreInstance as Ut, styleConfiguratorHistoryEntryForPersistedSelection as V, Upload as Va, VARIANT_ROLES as Vi, validateManifestDraft as Vn, defaultSectionTransitionVariantForFamily as Vr, classifyHistoryShortcut as Vt, beginAutosaveBatch as W, Tablet as Wa, attachRenderableMediaAssetFields as Wi, getResponsiveScopeSpec as Wn, sectionTransitionVariantForBoundaryOptionId as Wr, useOptionalEditorUiStoreInstance as Wt, resolveStyleConfiguratorInitialSnapshot as X, Pencil as Xa, mapCurrentValueForSelect as Xi, resolvePageRouteTarget as Xn, EDITABLE_SURFACE_FORWARDING_PROP as Xr, undoHistory as Xt, rejectAutosaveBatch as Y, Redo2 as Ya, hasEmptyOption as Yi, resolveEntryRouteTarget as Yn, bindingSchema as Yr, redoHistory as Yt, createOptimisticActionRunner as Z, PenLine as Za, mapOptionValueForSelect as Zi, resolveRouteTarget as Zn, planSiteChromePlacement as Zr, unsafeAsLinkedContentEntryId as Zt, reportPreviewDesignError as _, TabsContent as _a, BlockApiProvider as _i, MediaEditor as _n, __exportAll as _o, heroCopyFragment as _r, loadMailingListAuthoringContext as _t, previewDesignHistoryDomainForCommand as a, SelectContent as aa, coerceInlineTextWithFallback as ai, parseReferenceKind as an, EllipsisVertical as ao, cardFragment as ar, useUISelector as at, planSiteChromeSelection as b, Dialog as ba, eventCalendarListLayoutOptions as bi, listEntryPageContentSlots as bn, applyCompiledRuntimeFieldsToContent as br, IconPickerField as bt, selectionSnapshotFromApplySiteStyleSelectionResponse as c, SelectValue as ca, Text$2 as ci, resolveContentTitle as cn, ChevronDown as co, blogFeaturedPostFragment as cr, useEntryController as ct, PreviewDesignCoordinatorProvider as d, SearchInput as da, getCurrentResolveImageUrlContext as di, ManifestForm as dn, unsafeAsEditorBlockId as do, formCopyFragment as dr, createSiteOptionWidgetAdapters as dt, useField as ea, parseBlockIconValue as ei, useDebouncedLatestSave as en, Maximize2 as eo, getLinkedContentEntryMeta as er, renderSiteChromeBlock as et, usePreviewDesignCoordinator as f, Popover as fa, resolveImageUrlWithContext as fi, createManifestFormAdapter as fn, unsafeAsEditorBlockValues as fo, testimonialsCarouselFragment as fr, SiteOptionPickerField as ft, PREVIEW_DESIGN_SAVE_ERROR_MESSAGE as g, Tabs as ga, siblingPath$1 as gi, createStoreBackend as gn, parseSiteId as go, ctaRowFragment as gr, MailingListTargetingField as gt, PREVIEW_DESIGN_LOAD_ERROR_MESSAGE as h, Input as ha, getAtPath as hi, evaluateVisibility as hn, parseMediaAssetId as ho, heroCtaRowFragment as hr, OfferingsPreviewWidgetProvider as ht, usePreviewDesignHistoryOrder as i, Select$1 as ia, logger$1 as ii, isAdapterReferenceKind as in, Eye as io, headingFragment as ir, ContentFieldsForm as it, openRow as j, DropdownMenuContent as ja, findButtonStyleRecipe as ji, createCustomBlockRegistry as jn, surfaceResolutionContextFromTheme as jr, RichTextWidgetProvider as jt, markApplySaved as k, Surface as ka, buttonStyleHoverPreferenceValue as ki, ThemeScope as kn, getCuratedSiteStyle as kr, useRichTextImagePicker as kt, deriveSiteStylePreviewUpdate as l, Callout as la, RichText as li, PaletteProvider as ln, Check as lo, singleButtonFragment as lr, useEntryEditorController as lt, usePreviewThemeOverlay as m, PopoverTrigger as ma, SECTION_BACKGROUND_MIN_SOURCE_WIDTH as mi, FormRenderer as mn, expectParsedBrandedId as mo, ctaCopyFragment as mr, OfferingsPreviewGroupOrderField as mt, useSiteChromeCustomizeOptional as n, TooltipContent as na, parseGeneratedIconSetId as ni, createSnapshotFromPageRecord as nn, Image as no, ImageResolveContextProvider as nr, PreviewInlineTextEditor as nt, selectPreviewDesignHistoryDomain as o, SelectItem as oa, inlineTextToPlainText as oi, deriveRouteMetadataPresentation as on, ChevronRight as oo, faqAccordionFragment as or, EditableBlockProvider as ot, PreviewThemeOverlayProvider as p, PopoverContent as pa, setContextResolveImageUrlContext as pi, createManifestValidation as pn, assertNever$10 as po, testimonialsHeadingFragment as pr, SiteOptionWidgetProvider as pt, enqueueTransaction as q, SlidersHorizontal as qa, SdkConfigProvider as qi, getDefaultComponentRegistry as qn, parseBackgroundAppearanceColorToken as qr, createHistoryState as qt, PreviewDesignHistoryOrderProvider as r, TooltipTrigger as ra, renderInlineText as ri, BUILT_IN_REFERENCE_KINDS as rn, GripVertical as ro, richTextFragment as rr, PreviewTextEditor as rt, buildApplySiteStyleSelectionBody as s, SelectTrigger as sa, isInlineTextEmpty as si, resolvePageRouteSlug as sn, ChevronLeft as so, faqHeadingFragment as sr, EntryControllerProvider as st, SiteChromeCustomizeProvider as t, Tooltip as ta, parseGeneratedIconAssetId as ti, createRoutingHelpers as tn, LoaderCircle as to, clientComponentRegistry as tr, PreviewRichTextEditor as tt, planConfiguratorPreview as u, CalloutDescription as ua, buildResolveImageUrlContext as ui, usePalette as un, parseFooterModuleId as uo, formEmbedFragment as ur, createSiteOptionApiLoader as ut, buildSiteChromeSelectionModels as v, TabsList as va, calendarWindowQuerySchema as vi, applyPageDesignEditorAction as vn, bodyCopyFragment as vr, MailingListTargetingProvider as vt, createStyleConfiguratorState as w, DialogHeader as wa, isThemeV2NormalEditorRawStyleFieldName as wi, AMBIENT_BACKGROUND_ROLES as wn, formatSiteChromeBackgroundTokenLabel as wr, ButtonWidgetProvider as wt, applyResolvedSelections as x, DialogContent as xa, bookingConsentCarrierSchema as xi, decodePublicProductCategorySelectorQuery as xn, compileEditorModelRuntime as xr, EntryPickerField as xt, cycleSiteChromeSelectionId as y, TabsTrigger as ya, eventCalendarListLayoutCompatibleDisplayModeValues as yi, getPageDesignEditorState as yn, defineFragment as yr, InlineTextField as yt, resetTypographyToSaved as z, cn$2 as za, parseThemeForPersistence as zi, resolveVariantKey as zn, parseGradientPresetId as zr, stripTopLevelRoutingUi as zt };
|