@riverbankcms/sdk 0.147.0 → 0.148.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/CHANGELOG.md +16 -0
- package/dist/{PreviewEditorSidebar-DtpB3_sS.mjs → PreviewEditorSidebar-DvEPG3Z2.mjs} +202 -143
- package/dist/{PreviewEditorUI-DxTLgaHo.mjs → PreviewEditorUI-D6eb6fkx.mjs} +68 -60
- package/dist/{PreviewQueryProvider-Dd4dxOiU.mjs → PreviewQueryProvider-5znTyJuz.mjs} +1 -1
- package/dist/{SdkPreviewModeRuntime-DMMNCngt.mjs → SdkPreviewModeRuntime-DJ6utQ_R.mjs} +1191 -513
- package/dist/{SiteChromeCustomizeContext-DQXZXiqS.mjs → SiteChromeCustomizeContext-CFJYh6vo.mjs} +201798 -197304
- package/dist/_dts/ai/src/contracts/proposals.d.ts +0 -33
- package/dist/_dts/ai/src/contracts/siteStyleProposalSchemas.d.ts +0 -3
- package/dist/_dts/api/src/accessAdmin.d.ts +0 -4
- package/dist/_dts/api/src/accountApi.d.ts +1 -1
- package/dist/_dts/api/src/admin.d.ts +22 -22
- package/dist/_dts/api/src/aiPatch.d.ts +2 -2
- package/dist/_dts/api/src/aiPlayground.d.ts +1 -0
- package/dist/_dts/api/src/analytics.d.ts +2 -2
- package/dist/_dts/api/src/apiEndpointTypes.d.ts +2 -0
- package/dist/_dts/api/src/appointmentSetup.d.ts +2 -2
- package/dist/_dts/api/src/auth.d.ts +10 -10
- package/dist/_dts/api/src/availability.d.ts +6 -6
- package/dist/_dts/api/src/billing.d.ts +42 -15
- package/dist/_dts/api/src/billingEndpointDefinitions.d.ts +8 -0
- package/dist/_dts/api/src/billingEndpointTypes.d.ts +15 -6
- package/dist/_dts/api/src/blocks.d.ts +15 -14
- package/dist/_dts/api/src/blocksKeys.d.ts +2 -0
- package/dist/_dts/api/src/bookingConfig.d.ts +0 -2
- package/dist/_dts/api/src/bookingOperations.d.ts +4 -4
- package/dist/_dts/api/src/bookingRecords.d.ts +1 -0
- package/dist/_dts/api/src/bookings.d.ts +7 -7
- package/dist/_dts/api/src/calendar.d.ts +9 -9
- package/dist/_dts/api/src/commercePortalEndpoints.d.ts +7 -6
- package/dist/_dts/api/src/common/envelope.d.ts +2 -2
- package/dist/_dts/api/src/content-editor.d.ts +2 -2
- package/dist/_dts/api/src/contentEntries.d.ts +17 -48
- package/dist/_dts/api/src/contentRuntime.d.ts +51 -37
- package/dist/_dts/api/src/contentTypes.d.ts +11 -11
- package/dist/_dts/api/src/contentVersionHistoryClient.d.ts +6 -6
- package/dist/_dts/api/src/documentLifecycle.d.ts +67 -0
- package/dist/_dts/api/src/domains.d.ts +16 -16
- package/dist/_dts/api/src/editLeaseEndpoints.d.ts +72 -0
- package/dist/_dts/api/src/emailSettings.d.ts +4 -4
- package/dist/_dts/api/src/endpoints.d.ts +133 -41
- package/dist/_dts/api/src/eventEmailTemplates.d.ts +2 -2
- package/dist/_dts/api/src/eventManagementContracts.d.ts +25 -0
- package/dist/_dts/api/src/eventManagementEndpointDefinitions.d.ts +0 -8
- package/dist/_dts/api/src/eventPageWords.d.ts +7 -12
- package/dist/_dts/api/src/footerSettings.d.ts +6 -6
- package/dist/_dts/api/src/index.d.ts +6 -5
- package/dist/_dts/api/src/indexCoreTypes.d.ts +1 -0
- package/dist/_dts/api/src/indexExtendedTypes.d.ts +1 -1
- package/dist/_dts/api/src/navigation.d.ts +5 -5
- package/dist/_dts/api/src/pageSurfaceEditorEndpoints.d.ts +55 -0
- package/dist/_dts/api/src/pageSurfaceEndpoints.d.ts +28 -7
- package/dist/_dts/api/src/pages.d.ts +7 -7
- package/dist/_dts/api/src/performance.d.ts +1 -1
- package/dist/_dts/api/src/public/index.d.ts +1 -1
- package/dist/_dts/api/src/publicAppointmentBookingContracts.d.ts +2 -0
- package/dist/_dts/api/src/publicExperience/commerceEndpoints.d.ts +4 -0
- package/dist/_dts/api/src/redirects.d.ts +3 -3
- package/dist/_dts/api/src/request.d.ts +10 -1
- package/dist/_dts/api/src/resources.d.ts +4 -4
- package/dist/_dts/api/src/routes.d.ts +8 -3
- package/dist/_dts/api/src/sdk-event-upsert.d.ts +0 -1
- package/dist/_dts/api/src/sdkBlockUpsertContracts.d.ts +21 -0
- package/dist/_dts/api/src/sdkContracts.d.ts +5 -28
- package/dist/_dts/api/src/sdkEventEndpointDefinitions.d.ts +1 -1
- package/dist/_dts/api/src/sdkEventOccurrenceRequestContracts.d.ts +43 -0
- package/dist/_dts/api/src/sdkManagedEventContracts.d.ts +4 -2
- package/dist/_dts/api/src/sdkPullEventContracts.d.ts +8 -1
- package/dist/_dts/api/src/seo.d.ts +4 -4
- package/dist/_dts/api/src/services.d.ts +4 -4
- package/dist/_dts/api/src/siteManagementEndpoints.d.ts +15 -8
- package/dist/_dts/api/src/siteMembers.d.ts +10 -10
- package/dist/_dts/api/src/siteOnboarding.d.ts +14 -0
- package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +7 -3
- package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +5 -12
- package/dist/_dts/api/src/siteRuntimeEntry.d.ts +31 -0
- package/dist/_dts/billing/src/checkout/platform.d.ts +77 -0
- package/dist/_dts/billing/src/components/index.d.ts +25 -40
- package/dist/_dts/billing/src/membership/index.d.ts +1 -3
- package/dist/_dts/billing/src/plans/entitlements.d.ts +80 -0
- package/dist/_dts/billing/src/plans/registry.d.ts +16 -16
- package/dist/_dts/billing/src/plans/standing.d.ts +9 -2
- package/dist/_dts/billing/src/plans/types.d.ts +5 -15
- package/dist/_dts/billing/src/site-arrangements.d.ts +2 -2
- package/dist/_dts/billing/src/subscriptions/standingEvidence.d.ts +2 -4
- package/dist/_dts/billing/src/subscriptions/store.d.ts +17 -11
- package/dist/_dts/block-form/src/backend/store-backend.d.ts +6 -7
- package/dist/_dts/block-form/src/backend/types.d.ts +7 -0
- package/dist/_dts/block-form/src/widgets/FieldFrame.d.ts +3 -1
- package/dist/_dts/blocks/src/client/events.d.ts +3 -0
- package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +16 -4
- package/dist/_dts/blocks/src/pageRenderAdmission.d.ts +4 -13
- package/dist/_dts/blocks/src/pageRendererContracts.d.ts +2 -0
- package/dist/_dts/blocks/src/portal/types.d.ts +0 -2
- package/dist/_dts/blocks/src/system/blocks/contact-newsletter.d.ts +2 -1
- package/dist/_dts/blocks/src/system/blocks/event-registration.d.ts +3 -1
- package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +4 -4
- package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +6 -1
- package/dist/_dts/blocks/src/system/runtime/api/client.d.ts +2 -2
- package/dist/_dts/blocks/src/system/runtime/api/index.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/api/types/appointments.d.ts +2 -0
- package/dist/_dts/blocks/src/system/runtime/api/types/events.d.ts +6 -0
- package/dist/_dts/blocks/src/system/runtime/api/types/portal.d.ts +6 -0
- package/dist/_dts/blocks/src/system/runtime/api/types/shop.d.ts +4 -0
- package/dist/_dts/blocks/src/system/runtime/components/booking/SuccessMessage.d.ts +4 -1
- package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +24 -6
- package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +12 -3
- package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessBookingFlow.d.ts +3 -0
- package/dist/_dts/blocks/src/system/runtime/hooks/usePaymentVerification.d.ts +2 -1
- package/dist/_dts/blocks/src/system/runtime/hooks/usePolling.d.ts +7 -48
- package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.checkout-return-context.d.ts +7 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.completion.d.ts +3 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.headless.state.d.ts +4 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.interactive.d.ts +9 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.payment-confirmation.d.ts +13 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.state.d.ts +15 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.submit-actions.d.ts +8 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.submit-handler.d.ts +1 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/booking-runtime-sources.d.ts +1 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/checkout.server.d.ts +2 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationSurface.d.ts +2 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationWizard.d.ts +5 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/SuccessStep.d.ts +4 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +2 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +2 -5
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +9 -5
- package/dist/_dts/blocks/src/system/runtime/nodes/events/EventListing.interactive.d.ts +6 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/dates.d.ts +37 -3
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/EventCard.client.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/EventCard.d.ts +16 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCardPresentations.d.ts +13 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +5 -5
- package/dist/_dts/blocks/src/system/runtime/nodes/shared/MagicLinkForm.d.ts +1 -14
- package/dist/_dts/blocks/src/system/runtime/nodes/shared/MagicLinkForm.state.d.ts +12 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/shop.interactive.d.ts +13 -0
- package/dist/_dts/blocks/src/system/runtime/shared/components/DemoBookingPortalAccess.d.ts +22 -0
- package/dist/_dts/blocks/src/system/runtime/shared/components/DemoPortalSignInLink.d.ts +4 -0
- package/dist/_dts/blocks/src/system/runtime/shared/components/index.d.ts +1 -0
- package/dist/_dts/blocks/src/system/runtime/shared/utils/demoBookingPassStorage.d.ts +10 -0
- package/dist/_dts/blocks/src/system/runtime/shared/utils/demoPortalMagicLink.d.ts +29 -0
- package/dist/_dts/commerce/src/purchase/event-registration-errors.d.ts +4 -0
- package/dist/_dts/content-editor/src/components/ContentFieldsForm.d.ts +2 -7
- package/dist/_dts/content-editor/src/controller/EditLeaseController.d.ts +39 -0
- package/dist/_dts/content-editor/src/controller/EditorWriteGate.d.ts +38 -0
- package/dist/_dts/content-editor/src/controller/EntryControllerProvider.d.ts +25 -61
- package/dist/_dts/content-editor/src/controller/LinkedEntryLeaseBanner.d.ts +7 -0
- package/dist/_dts/content-editor/src/controller/LinkedEntryLeaseControllers.d.ts +14 -0
- package/dist/_dts/content-editor/src/controller/deriveEditorUnpublishedState.d.ts +6 -0
- package/dist/_dts/content-editor/src/controller/documentValueBaseline.d.ts +25 -0
- package/dist/_dts/content-editor/src/controller/editLeaseLossSignal.d.ts +6 -0
- package/dist/_dts/content-editor/src/controller/editLeaseNotice.d.ts +28 -0
- package/dist/_dts/content-editor/src/controller/editorClientId.d.ts +2 -0
- package/dist/_dts/content-editor/src/controller/editorEditability.d.ts +38 -0
- package/dist/_dts/content-editor/src/controller/editorLeaseParticipation.d.ts +34 -0
- package/dist/_dts/content-editor/src/controller/normalizedMetadataBaseline.d.ts +29 -0
- package/dist/_dts/content-editor/src/controller/pageSurfaceDocumentBaselines.d.ts +14 -0
- package/dist/_dts/content-editor/src/controller/pageSurfaceLifecycle.d.ts +11 -0
- package/dist/_dts/content-editor/src/controller/planDocumentBaselineRefresh.d.ts +19 -0
- package/dist/_dts/content-editor/src/controller/readDocumentLeaseBaselines.d.ts +19 -0
- package/dist/_dts/content-editor/src/controller/refreshDocumentLeaseBaseline.d.ts +12 -0
- package/dist/_dts/content-editor/src/controller/refreshLinkedEntry.d.ts +17 -0
- package/dist/_dts/content-editor/src/controller/replayRestoredEditorEffects.d.ts +2 -3
- package/dist/_dts/content-editor/src/controller/routeWrites.d.ts +26 -0
- package/dist/_dts/content-editor/src/controller/useAutosaveTriggers.d.ts +16 -17
- package/dist/_dts/content-editor/src/controller/useBlockedPublishPlan.d.ts +6 -2
- package/dist/_dts/content-editor/src/controller/useBlocksList.d.ts +3 -3
- package/dist/_dts/content-editor/src/controller/useEntryValueAutosaves.d.ts +21 -0
- package/dist/_dts/content-editor/src/controller/useInitialEditorUiStore.d.ts +24 -0
- package/dist/_dts/content-editor/src/controller/useServerBaselineReconciliation.d.ts +17 -0
- package/dist/_dts/content-editor/src/footerComposerPanelTypes.d.ts +1 -1
- package/dist/_dts/content-editor/src/hooks/applyBlockedPublishPlan.d.ts +5 -1
- package/dist/_dts/content-editor/src/hooks/blockDraftLifecycle.d.ts +8 -47
- package/dist/_dts/content-editor/src/hooks/editLeaseMachine.d.ts +120 -0
- package/dist/_dts/content-editor/src/hooks/publishability.d.ts +6 -10
- package/dist/_dts/content-editor/src/hooks/useAutosaveStatus.d.ts +3 -0
- package/dist/_dts/content-editor/src/hooks/useBlockAutosave.d.ts +5 -15
- package/dist/_dts/content-editor/src/hooks/useDebouncedLatestSave.d.ts +7 -5
- package/dist/_dts/content-editor/src/hooks/useEditLease.d.ts +28 -0
- package/dist/_dts/content-editor/src/hooks/useEntryActions.d.ts +25 -39
- package/dist/_dts/content-editor/src/hooks/useEntryMutations.d.ts +17 -19
- package/dist/_dts/content-editor/src/hooks/useLinkedEntryAutosave.d.ts +5 -8
- package/dist/_dts/content-editor/src/hooks/useValueAutosave.d.ts +64 -0
- package/dist/_dts/content-editor/src/hooks/validateBlocksForPublish.d.ts +0 -7
- package/dist/_dts/content-editor/src/index.d.ts +26 -7
- package/dist/_dts/content-editor/src/linkedEntries/domain.d.ts +12 -0
- package/dist/_dts/content-editor/src/linkedEntries/owner.d.ts +9 -0
- package/dist/_dts/content-editor/src/liveDrafts/draftProjection.d.ts +66 -0
- package/dist/_dts/content-editor/src/liveDrafts/linkedSaveHandovers.d.ts +37 -0
- package/dist/_dts/content-editor/src/liveDrafts/remoteDraftOverlay.d.ts +113 -0
- package/dist/_dts/content-editor/src/liveDrafts/useLiveDrafts.d.ts +32 -0
- package/dist/_dts/content-editor/src/liveDrafts/useRetentionTicks.d.ts +7 -0
- package/dist/_dts/content-editor/src/primitives/shared/activePreviewField.d.ts +6 -0
- package/dist/_dts/content-editor/src/primitives/shared/storeBinding.d.ts +1 -0
- package/dist/_dts/content-editor/src/services/contentEntryServices.d.ts +96 -19
- package/dist/_dts/content-editor/src/services/editorApiClient.d.ts +13 -0
- package/dist/_dts/content-editor/src/services/index.d.ts +2 -0
- package/dist/_dts/content-editor/src/services/pageSurfaceEditorServices.d.ts +23 -0
- package/dist/_dts/content-editor/src/sync/flushValues.d.ts +13 -0
- package/dist/_dts/content-editor/src/sync/lifecycleFailure.d.ts +51 -0
- package/dist/_dts/content-editor/src/sync/runLifecycle.d.ts +64 -0
- package/dist/_dts/content-editor/src/sync/schedulerValues.d.ts +27 -0
- package/dist/_dts/content-editor/src/sync/sendPlanning.d.ts +104 -0
- package/dist/_dts/content-editor/src/sync/valueSync.d.ts +114 -0
- package/dist/_dts/content-editor/src/ui/blockCollection.d.ts +8 -0
- package/dist/_dts/content-editor/src/ui/documentLifecycle.d.ts +18 -0
- package/dist/_dts/content-editor/src/ui/editorLeaseUiState.d.ts +7 -0
- package/dist/_dts/content-editor/src/ui/editorRefresh.d.ts +82 -0
- package/dist/_dts/content-editor/src/ui/editorSnapshot.d.ts +102 -127
- package/dist/_dts/content-editor/src/ui/editorTransactionState.d.ts +1 -1
- package/dist/_dts/content-editor/src/ui/editorUiStore.d.ts +126 -72
- package/dist/_dts/content-editor/src/ui/editorValueSnapshot.d.ts +18 -0
- package/dist/_dts/content-editor/src/ui/serverBlockAdmission.d.ts +26 -0
- package/dist/_dts/content-editor/src/ui/stores/autosaveStore.d.ts +16 -27
- package/dist/_dts/content-editor/src/ui/stores/blockVersionsStore.d.ts +24 -0
- package/dist/_dts/content-editor/src/ui/stores/linkedEntryLeaseStore.d.ts +54 -0
- package/dist/_dts/content-editor/src/ui/stores/linkedSaveHandoversStore.d.ts +11 -0
- package/dist/_dts/content-editor/src/ui/stores/remoteDraftsStore.d.ts +10 -0
- package/dist/_dts/content-editor/src/ui/stores/types.d.ts +63 -3
- package/dist/_dts/content-editor/src/useFooterComposerState.d.ts +2 -2
- package/dist/_dts/content-editor/src/useFooterNavigationLayout.d.ts +1 -1
- package/dist/_dts/content-model/src/content-types/builtin-schemas.d.ts +4 -4
- package/dist/_dts/content-model/src/content-types/builtins.d.ts +4 -4
- package/dist/_dts/content-model/src/definitions/shared.d.ts +11 -2
- package/dist/_dts/content-model/src/entry-slots/index.d.ts +1 -0
- package/dist/_dts/content-model/src/entry-slots/serializeAllowedBlocks.d.ts +2 -0
- package/dist/_dts/content-model/src/metadataConfig.d.ts +10 -38
- package/dist/_dts/content-model/src/templates/defaults.d.ts +0 -1
- package/dist/_dts/content-model/src/types.d.ts +0 -1
- package/dist/_dts/core/src/block-content-identity.d.ts +49 -1
- package/dist/_dts/core/src/branded.d.ts +12 -0
- package/dist/_dts/core/src/currency-format.d.ts +8 -2
- package/dist/_dts/core/src/demo-lifecycle-status.d.ts +2 -2
- package/dist/_dts/core/src/demo-warm-pool-target.d.ts +8 -0
- package/dist/_dts/core/src/edit-lease.d.ts +55 -0
- package/dist/_dts/core/src/editor-state.d.ts +38 -13
- package/dist/_dts/core/src/editor-value-sync.d.ts +79 -0
- package/dist/_dts/core/src/html-entities.d.ts +6 -0
- package/dist/_dts/core/src/index.d.ts +4 -0
- package/dist/_dts/core/src/uuid.d.ts +7 -5
- package/dist/_dts/db/src/generated/supabase/database.types.d.ts +159 -153
- package/dist/_dts/editor/src/EditorProvider.d.ts +5 -0
- package/dist/_dts/editor/src/chrome/EditorChrome.d.ts +14 -0
- package/dist/_dts/editor/src/chrome/EditorStatusBar.d.ts +1 -0
- package/dist/_dts/editor/src/chrome/statusBarPresentation.d.ts +0 -1
- package/dist/_dts/editor/src/index.d.ts +1 -1
- package/dist/_dts/editor-blocks/src/BlockEditor.d.ts +10 -9
- package/dist/_dts/editor-blocks/src/BlockForm.d.ts +1 -1
- package/dist/_dts/editor-blocks/src/block-editor/BlockCard.d.ts +1 -1
- package/dist/_dts/editor-blocks/src/block-editor/BlockCardFrame.d.ts +1 -1
- package/dist/_dts/editor-blocks/src/block-editor/BlockSettingsModal.d.ts +1 -1
- package/dist/_dts/editor-blocks/src/block-editor/applyExtendedFieldDefaults.d.ts +3 -4
- package/dist/_dts/editor-blocks/src/block-editor/blockDraftBaselineSeed.d.ts +4 -8
- package/dist/_dts/editor-blocks/src/block-editor/editorBlockItem.d.ts +23 -0
- package/dist/_dts/editor-blocks/src/block-editor/generatedIconApplyCoordination.d.ts +2 -7
- package/dist/_dts/editor-blocks/src/block-editor/hooks/applyBlockStructureChange.d.ts +4 -0
- package/dist/_dts/editor-blocks/src/block-editor/hooks/buildInsertBlockHistoryCommand.d.ts +14 -5
- package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockBaselineSync.d.ts +21 -19
- package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockCreation.d.ts +2 -10
- package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockDuplication.d.ts +8 -16
- package/dist/_dts/editor-blocks/src/block-editor/owner.d.ts +6 -16
- package/dist/_dts/editor-blocks/src/block-editor/types.d.ts +37 -9
- package/dist/_dts/editor-blocks/src/index.d.ts +2 -1
- package/dist/_dts/editor-blocks/src/widgets/entry-picker/loaders.d.ts +1 -1
- package/dist/_dts/editor-blocks/src/widgets/link/loaders.d.ts +1 -1
- package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/loaders.d.ts +1 -1
- package/dist/_dts/editor-blocks/src/widgets/reference/loaders.d.ts +1 -1
- package/dist/_dts/editor-blocks/src/widgets/site-option-picker/loaders.d.ts +3 -2
- package/dist/_dts/media-core/src/fileStorage.d.ts +4 -0
- package/dist/_dts/media-editor/src/context.d.ts +1 -1
- package/dist/_dts/media-editor/src/createMediaEditorProvider.d.ts +1 -2
- package/dist/_dts/media-editor/src/provider.d.ts +3 -2
- package/dist/_dts/media-react/src/hooks/internal/classification.d.ts +1 -1
- package/dist/_dts/media-react/src/hooks/useApiMediaUploader.d.ts +3 -1
- package/dist/_dts/preview-next/src/client/blocks/composer/mergeDrafts.d.ts +8 -3
- package/dist/_dts/preview-next/src/client/blocks/composer/types.d.ts +6 -3
- package/dist/_dts/preview-next/src/client/blocks/linkedEntryRenderOverlay.d.ts +22 -2
- package/dist/_dts/preview-next/src/client/blocks/previewProjection/entryFieldRebinding.d.ts +13 -0
- package/dist/_dts/preview-next/src/client/blocks/previewProjection/index.d.ts +2 -1
- package/dist/_dts/preview-next/src/client/blocks/previewProjection/types.d.ts +11 -1
- package/dist/_dts/preview-next/src/client/blocks/renderPrecedence.d.ts +17 -0
- package/dist/_dts/preview-next/src/client/blocks/useLinkedSaveHandoverRetention.d.ts +20 -0
- package/dist/_dts/preview-next/src/client/index.d.ts +1 -1
- package/dist/_dts/preview-next/src/client/preview/EntryEditorPanel.d.ts +2 -1
- package/dist/_dts/preview-next/src/client/preview/EntrySlotBlockEditorPanel.d.ts +2 -1
- package/dist/_dts/preview-next/src/client/preview/PreviewAccessBanners.d.ts +7 -0
- package/dist/_dts/preview-next/src/client/preview/PreviewEditorSidebar.d.ts +2 -1
- package/dist/_dts/preview-next/src/client/preview/PreviewEntryControllerProvider.d.ts +24 -14
- package/dist/_dts/preview-next/src/client/preview/PreviewLeaseEditingMode.d.ts +2 -0
- package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +9 -2
- package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +1 -0
- package/dist/_dts/preview-next/src/client/preview/previewCustomizeAutosave.d.ts +5 -0
- package/dist/_dts/preview-next/src/client/preview/previewCustomizeWorkflowState.d.ts +3 -4
- package/dist/_dts/preview-next/src/client/preview/sdkConfig.d.ts +1 -0
- package/dist/_dts/preview-next/src/client/preview/usePreviewCustomizeWorkflowState.d.ts +4 -0
- package/dist/_dts/realtime/src/client.d.ts +3 -0
- package/dist/_dts/realtime/src/draftChannel.d.ts +91 -0
- package/dist/_dts/realtime/src/drafts.d.ts +210 -0
- package/dist/_dts/realtime/src/index.d.ts +3 -0
- package/dist/_dts/realtime/src/leaseChangeSubscriptions.d.ts +8 -0
- package/dist/_dts/realtime/src/types.d.ts +113 -0
- package/dist/_dts/realtime/src/useDraftChannel.d.ts +34 -0
- package/dist/_dts/realtime/src/useSiteRealtimeReload.d.ts +27 -0
- package/dist/_dts/sdk/src/public-api/contracts.d.ts +6 -55
- package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +1 -0
- package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +1 -0
- package/dist/_dts/sdk/src/rendering/helpers/pageRuntimeSupport.d.ts +2 -0
- package/dist/_dts/sdk/src/version.d.ts +1 -1
- package/dist/_dts/surfaces/src/index.d.ts +1 -0
- package/dist/_dts/theme-core/src/site-styles/designState.d.ts +2 -2
- package/dist/client/{BookingMailingListNote-1n4Ch_u_.mjs → BookingMailingListNote-CzRt2dF_.mjs} +98 -96
- package/dist/client/DemoBookingPortalAccess-mxqwap3f.mjs +344 -0
- package/dist/client/{EventCombined.client-C0pgma9y.mjs → EventCombined.client-CDb11igO.mjs} +6 -6
- package/dist/client/{EventListing.client-4fhLOvHP.mjs → EventListing.client-EgYhzKPa.mjs} +2 -2
- package/dist/client/{LeafletStaticMap-DScC4F3w.mjs → LeafletStaticMap-gtmtaA2b.mjs} +1 -1
- package/dist/client/{TerminalPanel-B5ZUsYhe.mjs → TerminalPanel-DvNUP5ot.mjs} +1 -1
- package/dist/client/{ThemedButton-DoVIV1Ao.mjs → ThemedButton-C7CeUJjW.mjs} +1 -1
- package/dist/client/{accordion-CoT5g7zo.mjs → accordion-kjvt49rA.mjs} +1 -1
- package/dist/client/{bookingForm-BWxB46xD.mjs → bookingForm-pbRZordh.mjs} +212 -62
- package/dist/client/bookings.mjs +616 -225
- package/dist/client/{carousel-DtNYWFd3.mjs → carousel-f4Zbmicv.mjs} +1 -1
- package/dist/client/{cart-z4qZih1Y.mjs → cart-DO20An50.mjs} +3 -3
- package/dist/client/{checkout-DpL7euFH.mjs → checkout-Du5amDR_.mjs} +3 -3
- package/dist/client/{checkoutUrls-BEfR7kVu.mjs → checkoutUrls-CXhko2Rv.mjs} +1 -1
- package/dist/client/client.mjs +1753 -823
- package/dist/client/{context-C8TinPJc.mjs → context-eW97E945.mjs} +4 -3
- package/dist/client/{dates-vwwxTeB0.mjs → dates-jPCirRea.mjs} +56 -11
- package/dist/client/{eventCalendar-DIbHfJXO.mjs → eventCalendar-C2M-iE4j.mjs} +9 -9
- package/dist/client/{eventCombined-DoGMJ6cg.mjs → eventCombined-W6ns3LHg.mjs} +4 -4
- package/dist/client/{eventDetails-BjN9v6a1.mjs → eventDetails-CR-GT0f0.mjs} +4 -4
- package/dist/client/{eventListing-DajjWgOv.mjs → eventListing-BK8AfYZz.mjs} +4 -4
- package/dist/client/{eventRegistration-DMq9gMA-.mjs → eventRegistration-BJSd4KUu.mjs} +369 -242
- package/dist/client/{form-Qf6qTbos.mjs → form-BvpfbQaT.mjs} +3 -3
- package/dist/client/{headerSection-D7qJrqFX.mjs → headerSection-I5sUQ8x-.mjs} +3 -3
- package/dist/client/hooks.mjs +254 -53
- package/dist/client/{locationMap-CCF9-t_0.mjs → locationMap-BLvwf9_f.mjs} +3 -3
- package/dist/client/{media-CwBGetqC.mjs → media-Cl38iOMI.mjs} +10 -3
- package/dist/client/{newsletterForm-DzCLSP4S.mjs → newsletterForm-DrQ2weE8.mjs} +3 -3
- package/dist/client/{pricing-Cgxv2KLC.mjs → pricing-BES87mrR.mjs} +1 -1
- package/dist/client/{productDetail-ru9w5GHx.mjs → productDetail-Url9jcc5.mjs} +3 -3
- package/dist/client/{productList-zaapKSl-.mjs → productList-DE7ngEZJ.mjs} +3 -3
- package/dist/client/{propsDecoder-CwvvNOHx.mjs → propsDecoder-D1OtGXDV.mjs} +89 -17
- package/dist/client/rendering/client.mjs +1445 -658
- package/dist/client/rendering/islands.mjs +18 -18
- package/dist/client/rendering.mjs +2478 -1515
- package/dist/client/{routeIslandApiConfig-BwVFo0Y4.mjs → routeIslandApiConfig-BG9Y-SHg.mjs} +1 -1
- package/dist/client/{shop-mktkXvbV.mjs → shop-CJkuySJ3.mjs} +126 -79
- package/dist/client/{shop-commerce-De7gEnkA.mjs → shop-commerce-4rKj5n9h.mjs} +25 -13
- package/dist/client/{shop-commerce-store-B3MCxIBW.mjs → shop-commerce-store-Bxm75Pg6.mjs} +1 -1
- package/dist/client/{shopShared-TqExh235.mjs → shopShared-DpoQDWfz.mjs} +4 -4
- package/dist/client/{useEventFilters-n_OjkIjX.mjs → useEventFilters-D8HliSqR.mjs} +32 -17
- package/dist/preview-next/before-render.mjs +192 -83
- package/dist/preview-next/client/runtime.mjs +4 -4
- package/dist/preview-next/keepAlive.mjs +192 -83
- package/dist/preview-next/middleware.mjs +192 -83
- package/dist/{previewAuthStore-C_EHQ5XA.mjs → previewAuthStore-BXXF3hhW.mjs} +194 -83
- package/dist/{sdk-runtime-BIkJg5y1.mjs → sdk-runtime-C2a05WjL.mjs} +2 -2
- package/dist/{separator-C9qDP95Z.mjs → separator-CuNhBAhS.mjs} +1 -1
- package/dist/server/components.mjs +1720 -1392
- package/dist/server/config-validation.mjs +221 -37
- package/dist/server/config.mjs +221 -37
- package/dist/server/data.mjs +221 -37
- package/dist/server/index.mjs +195 -84
- package/dist/server/next.mjs +490 -196
- package/dist/server/page-converter.mjs +53 -14
- package/dist/server/prebuild.mjs +1 -1
- package/dist/server/rendering/server.mjs +1427 -1098
- package/dist/server/rendering.mjs +2693 -2365
- package/dist/server/routing.mjs +291 -55
- package/dist/server/server.mjs +281 -114
- package/package.json +1 -1
- package/dist/_dts/billing/src/plans/display.d.ts +0 -15
- package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.mailing-list-note.d.ts +0 -3
- package/dist/_dts/content-editor/src/controller/buildBlockPublishedBaselines.d.ts +0 -4
- package/dist/_dts/content-editor/src/controller/buildPublishSuccessTransition.d.ts +0 -16
- package/dist/_dts/content-editor/src/controller/driver.d.ts +0 -14
- package/dist/_dts/content-editor/src/controller/seedDraftBaselinesFromBlocks.d.ts +0 -7
- package/dist/_dts/content-editor/src/controller/useEntrySyncHelpers.d.ts +0 -29
- package/dist/_dts/content-editor/src/hooks/autosaveScopePlanning.d.ts +0 -26
- package/dist/_dts/content-editor/src/hooks/useSimpleAutosave.d.ts +0 -64
- package/dist/_dts/content-editor/src/hooks/useStoreAutosave.d.ts +0 -48
- package/dist/_dts/content-editor/src/types.d.ts +0 -44
- package/dist/client/DiscountCodeDisclosure-CKJtz0mY.mjs +0 -137
package/dist/client/bookings.mjs
CHANGED
|
@@ -2563,6 +2563,19 @@ const CURRENCY_LOCALE_BY_CODE = {
|
|
|
2563
2563
|
function resolveCurrencyLocale(currencyCode, override) {
|
|
2564
2564
|
return override ?? CURRENCY_LOCALE_BY_CODE[currencyCode] ?? "en";
|
|
2565
2565
|
}
|
|
2566
|
+
function fractionDigitsFor(decimals, exactFormatter) {
|
|
2567
|
+
switch (decimals) {
|
|
2568
|
+
case "exact": return {};
|
|
2569
|
+
case "auto": return {
|
|
2570
|
+
minimumFractionDigits: 0,
|
|
2571
|
+
maximumFractionDigits: exactFormatter.resolvedOptions().maximumFractionDigits
|
|
2572
|
+
};
|
|
2573
|
+
case "whole": return {
|
|
2574
|
+
minimumFractionDigits: 0,
|
|
2575
|
+
maximumFractionDigits: 0
|
|
2576
|
+
};
|
|
2577
|
+
}
|
|
2578
|
+
}
|
|
2566
2579
|
/**
|
|
2567
2580
|
* The single currency-amount formatter for the product: minor units in,
|
|
2568
2581
|
* localized string out.
|
|
@@ -2573,6 +2586,13 @@ function resolveCurrencyLocale(currencyCode, override) {
|
|
|
2573
2586
|
* own `Intl.NumberFormat`.
|
|
2574
2587
|
*/
|
|
2575
2588
|
function formatCurrencyAmount(amountCents, currency, options) {
|
|
2589
|
+
return formatCurrencyMajorUnits(amountCents / 100, currency, options);
|
|
2590
|
+
}
|
|
2591
|
+
/**
|
|
2592
|
+
* `formatCurrencyAmount` for an amount already in MAJOR units (29.99 = £29.99),
|
|
2593
|
+
* such as a registrar price. Prefer minor units everywhere else.
|
|
2594
|
+
*/
|
|
2595
|
+
function formatCurrencyMajorUnits(amount, currency, options) {
|
|
2576
2596
|
const currencyCode = currency.toUpperCase();
|
|
2577
2597
|
const locale = resolveCurrencyLocale(currencyCode, options?.locale);
|
|
2578
2598
|
try {
|
|
@@ -2580,17 +2600,13 @@ function formatCurrencyAmount(amountCents, currency, options) {
|
|
|
2580
2600
|
style: "currency",
|
|
2581
2601
|
currency: currencyCode
|
|
2582
2602
|
});
|
|
2583
|
-
const fractionDigits = options?.decimals === "auto" ? {
|
|
2584
|
-
minimumFractionDigits: 0,
|
|
2585
|
-
maximumFractionDigits: exactFormatter.resolvedOptions().maximumFractionDigits
|
|
2586
|
-
} : {};
|
|
2587
2603
|
return new Intl.NumberFormat(locale, {
|
|
2588
2604
|
style: "currency",
|
|
2589
2605
|
currency: currencyCode,
|
|
2590
|
-
...
|
|
2591
|
-
}).format(
|
|
2606
|
+
...fractionDigitsFor(options?.decimals ?? "exact", exactFormatter)
|
|
2607
|
+
}).format(amount);
|
|
2592
2608
|
} catch {
|
|
2593
|
-
return `${
|
|
2609
|
+
return `${amount.toFixed(2)} ${currencyCode}`;
|
|
2594
2610
|
}
|
|
2595
2611
|
}
|
|
2596
2612
|
//#endregion
|
|
@@ -2786,7 +2802,7 @@ function parseEventPageSurfaceDestinationMode(value) {
|
|
|
2786
2802
|
return value === "cms-managed" || value === "system-managed" ? value : void 0;
|
|
2787
2803
|
}
|
|
2788
2804
|
function parseEventPageSurfaceSubject(value) {
|
|
2789
|
-
if (!isRecord$
|
|
2805
|
+
if (!isRecord$9(value)) return err$1({ kind: "notObject" });
|
|
2790
2806
|
switch (value.kind) {
|
|
2791
2807
|
case "eventSeries": {
|
|
2792
2808
|
const eventSeriesId = parseEventSeriesId(value.eventSeriesId);
|
|
@@ -2841,7 +2857,7 @@ function parseEventSeriesIdList(values) {
|
|
|
2841
2857
|
}
|
|
2842
2858
|
return ok$1(parsed);
|
|
2843
2859
|
}
|
|
2844
|
-
function isRecord$
|
|
2860
|
+
function isRecord$9(value) {
|
|
2845
2861
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2846
2862
|
}
|
|
2847
2863
|
//#endregion
|
|
@@ -3168,6 +3184,16 @@ function resolveBookingSignupOffer(context, siteName) {
|
|
|
3168
3184
|
const name = siteName?.trim() ?? "";
|
|
3169
3185
|
return context?.tag === "configured" && context.bookingSignup.tag === "offered" ? { siteName: name.length > 0 ? name : "this site" } : null;
|
|
3170
3186
|
}
|
|
3187
|
+
//#endregion
|
|
3188
|
+
//#region ../core/src/uuid.ts
|
|
3189
|
+
function generateUuidV4(cryptoSource = globalThis.crypto) {
|
|
3190
|
+
if (typeof cryptoSource.randomUUID === "function") return cryptoSource.randomUUID();
|
|
3191
|
+
const bytes = cryptoSource.getRandomValues(/* @__PURE__ */ new Uint8Array(16));
|
|
3192
|
+
bytes[6] = (bytes[6] ?? 0) & 15 | 64;
|
|
3193
|
+
bytes[8] = (bytes[8] ?? 0) & 63 | 128;
|
|
3194
|
+
const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0"));
|
|
3195
|
+
return `${hex.slice(0, 4).join("")}-${hex.slice(4, 6).join("")}-${hex.slice(6, 8).join("")}-${hex.slice(8, 10).join("")}-${hex.slice(10).join("")}`;
|
|
3196
|
+
}
|
|
3171
3197
|
function sessionStartMs(session) {
|
|
3172
3198
|
return Date.parse(session.startsAt);
|
|
3173
3199
|
}
|
|
@@ -7023,7 +7049,7 @@ const boxBackgroundSchema = z.discriminatedUnion("type", [
|
|
|
7023
7049
|
})
|
|
7024
7050
|
]);
|
|
7025
7051
|
function normalizeAuthoringOpacity(value) {
|
|
7026
|
-
if (!isRecord$
|
|
7052
|
+
if (!isRecord$8(value)) return value;
|
|
7027
7053
|
return {
|
|
7028
7054
|
...value,
|
|
7029
7055
|
opacity: normalizeOpacity(value.opacity)
|
|
@@ -7032,7 +7058,7 @@ function normalizeAuthoringOpacity(value) {
|
|
|
7032
7058
|
function normalizeOpacity(value) {
|
|
7033
7059
|
return typeof value === "number" && value > 1 && value <= 100 ? value / 100 : value;
|
|
7034
7060
|
}
|
|
7035
|
-
function isRecord$
|
|
7061
|
+
function isRecord$8(value) {
|
|
7036
7062
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7037
7063
|
}
|
|
7038
7064
|
//#endregion
|
|
@@ -8156,7 +8182,6 @@ const publicEventBaseSchema = z.object({
|
|
|
8156
8182
|
description: z.string().nullable(),
|
|
8157
8183
|
content: z.object({ body: RichTextDocSchema.nullable().optional() }).optional(),
|
|
8158
8184
|
presentation: z.object({
|
|
8159
|
-
cardTitleOverride: z.string().nullable().optional(),
|
|
8160
8185
|
summary: z.string().nullable().optional(),
|
|
8161
8186
|
image: mediaSchema.nullable().optional()
|
|
8162
8187
|
}).optional(),
|
|
@@ -8189,6 +8214,7 @@ const publicEventBaseSchema = z.object({
|
|
|
8189
8214
|
"archived"
|
|
8190
8215
|
]).optional(),
|
|
8191
8216
|
timeZone: z.string(),
|
|
8217
|
+
siteTimeZone: z.string().optional(),
|
|
8192
8218
|
pricing: publicEventPricingSchema,
|
|
8193
8219
|
paymentTerms: blockBookingPaymentTermsSchema,
|
|
8194
8220
|
cancellationPolicy: z.object({ refunds: z.object({
|
|
@@ -8716,7 +8742,7 @@ var BlockApiError = class extends Error {
|
|
|
8716
8742
|
this.name = "BlockApiError";
|
|
8717
8743
|
}
|
|
8718
8744
|
};
|
|
8719
|
-
function isRecord$
|
|
8745
|
+
function isRecord$7(value) {
|
|
8720
8746
|
return typeof value === "object" && value !== null;
|
|
8721
8747
|
}
|
|
8722
8748
|
function isJsonResponseContentType(contentType) {
|
|
@@ -8740,15 +8766,15 @@ async function parseJsonBody(response) {
|
|
|
8740
8766
|
}
|
|
8741
8767
|
}
|
|
8742
8768
|
function isFieldError(value) {
|
|
8743
|
-
return isRecord$
|
|
8769
|
+
return isRecord$7(value) && !Array.isArray(value) && typeof value.field === "string" && typeof value.code === "string" && typeof value.message === "string";
|
|
8744
8770
|
}
|
|
8745
8771
|
function fieldErrorsFromUnknown(value) {
|
|
8746
8772
|
if (!Array.isArray(value)) return void 0;
|
|
8747
8773
|
return value.every(isFieldError) ? value : void 0;
|
|
8748
8774
|
}
|
|
8749
8775
|
function getBlockApiErrorDetails(data) {
|
|
8750
|
-
if (!isRecord$
|
|
8751
|
-
const nestedError = isRecord$
|
|
8776
|
+
if (!isRecord$7(data)) return {};
|
|
8777
|
+
const nestedError = isRecord$7(data.error) ? data.error : void 0;
|
|
8752
8778
|
const message = typeof nestedError?.message === "string" ? nestedError.message : typeof data.message === "string" ? data.message : void 0;
|
|
8753
8779
|
const code = typeof nestedError?.code === "string" ? nestedError.code : typeof data.code === "string" ? data.code : void 0;
|
|
8754
8780
|
const fieldErrors = fieldErrorsFromUnknown(nestedError?.fieldErrors) ?? fieldErrorsFromUnknown(data.fieldErrors);
|
|
@@ -9317,10 +9343,11 @@ function createBlockApi(config) {
|
|
|
9317
9343
|
},
|
|
9318
9344
|
async sendMagicLink(data) {
|
|
9319
9345
|
const sid = requireSiteId();
|
|
9320
|
-
|
|
9346
|
+
return request(PORTAL.sendMagicLink, { body: {
|
|
9321
9347
|
siteId: sid,
|
|
9322
9348
|
email: data.email,
|
|
9323
|
-
redirectUrl: data.redirectUrl
|
|
9349
|
+
redirectUrl: data.redirectUrl,
|
|
9350
|
+
demoBookingPass: data.demoBookingPass
|
|
9324
9351
|
} });
|
|
9325
9352
|
},
|
|
9326
9353
|
async logout() {
|
|
@@ -9543,7 +9570,7 @@ function resolveAppointmentCheckoutVerificationState(input) {
|
|
|
9543
9570
|
tag: "timeout",
|
|
9544
9571
|
sessionId: input.config.sessionId,
|
|
9545
9572
|
appointmentId,
|
|
9546
|
-
message: "
|
|
9573
|
+
message: "We’re still confirming your payment. This can take a minute – you can check again, and you won’t be charged twice."
|
|
9547
9574
|
};
|
|
9548
9575
|
if (input.pollingStatus === "failed") {
|
|
9549
9576
|
if (paymentStatus === "refunded") return {
|
|
@@ -9607,7 +9634,7 @@ function deriveBookingFormViewState(input) {
|
|
|
9607
9634
|
message: input.verificationState.message
|
|
9608
9635
|
};
|
|
9609
9636
|
case "timeout": return {
|
|
9610
|
-
kind: "
|
|
9637
|
+
kind: "timeout",
|
|
9611
9638
|
message: input.verificationState.message
|
|
9612
9639
|
};
|
|
9613
9640
|
case "confirmed": return {
|
|
@@ -9621,12 +9648,12 @@ function resolveBookingSiteId(siteId, form) {
|
|
|
9621
9648
|
return siteId || form?.siteId || "";
|
|
9622
9649
|
}
|
|
9623
9650
|
function normalizeBookingFormConfig(form) {
|
|
9624
|
-
if (!isRecord$
|
|
9651
|
+
if (!isRecord$6(form)) return null;
|
|
9625
9652
|
const id = readNonEmptyString(form.id);
|
|
9626
9653
|
const name = readNonEmptyString(form.name);
|
|
9627
9654
|
if (!id || !name) return null;
|
|
9628
|
-
const schemaSource = isRecord$
|
|
9629
|
-
const settingsSource = isRecord$
|
|
9655
|
+
const schemaSource = isRecord$6(form.schema) ? form.schema : isRecord$6(form.schemaJson) ? form.schemaJson : null;
|
|
9656
|
+
const settingsSource = isRecord$6(form.settings) ? form.settings : isRecord$6(form.settingsJson) ? form.settingsJson : null;
|
|
9630
9657
|
return {
|
|
9631
9658
|
id,
|
|
9632
9659
|
name,
|
|
@@ -9646,8 +9673,8 @@ function normalizeBookingServices(services) {
|
|
|
9646
9673
|
};
|
|
9647
9674
|
if (!services) return [];
|
|
9648
9675
|
if (Array.isArray(services)) return services.filter(isBookingFormService).map(normalizeService);
|
|
9649
|
-
if (isRecord$
|
|
9650
|
-
return isRecord$
|
|
9676
|
+
if (isRecord$6(services) && "services" in services) return Array.isArray(services.services) ? services.services.filter(isBookingFormService).map(normalizeService) : [];
|
|
9677
|
+
return isRecord$6(services) ? Object.values(services).filter(isBookingFormService).map(normalizeService) : [];
|
|
9651
9678
|
}
|
|
9652
9679
|
function normalizeBookingSchema(value) {
|
|
9653
9680
|
if (!value) return void 0;
|
|
@@ -9658,7 +9685,7 @@ function normalizeBookingSchema(value) {
|
|
|
9658
9685
|
};
|
|
9659
9686
|
}
|
|
9660
9687
|
function readBookingFormField(value) {
|
|
9661
|
-
if (!isRecord$
|
|
9688
|
+
if (!isRecord$6(value)) return null;
|
|
9662
9689
|
const id = readNonEmptyString(value.id);
|
|
9663
9690
|
const label = readNonEmptyString(value.label);
|
|
9664
9691
|
const type = readBookingFieldType(value.type);
|
|
@@ -9701,7 +9728,7 @@ function readBookingFieldOptions(value) {
|
|
|
9701
9728
|
return options.length > 0 ? options : void 0;
|
|
9702
9729
|
}
|
|
9703
9730
|
function readBookingFieldOption(value) {
|
|
9704
|
-
if (!isRecord$
|
|
9731
|
+
if (!isRecord$6(value)) return null;
|
|
9705
9732
|
const optionValue = readNonEmptyString(value.value);
|
|
9706
9733
|
const label = readNonEmptyString(value.label);
|
|
9707
9734
|
return optionValue && label ? {
|
|
@@ -9721,7 +9748,7 @@ function normalizeBookingSettings(value) {
|
|
|
9721
9748
|
};
|
|
9722
9749
|
}
|
|
9723
9750
|
function isBookingFormService(value) {
|
|
9724
|
-
return isRecord$
|
|
9751
|
+
return isRecord$6(value) && typeof value.id === "string" && typeof value.siteId === "string" && typeof value.title === "string" && (value.consent === void 0 || blockBookingConsentSchema.safeParse(value.consent).success);
|
|
9725
9752
|
}
|
|
9726
9753
|
function collectBookingCustomFields(data) {
|
|
9727
9754
|
const customFields = {};
|
|
@@ -9771,7 +9798,7 @@ function readStringArray(value) {
|
|
|
9771
9798
|
const strings = value.filter((item) => typeof item === "string");
|
|
9772
9799
|
return strings.length > 0 ? strings : void 0;
|
|
9773
9800
|
}
|
|
9774
|
-
function isRecord$
|
|
9801
|
+
function isRecord$6(value) {
|
|
9775
9802
|
return typeof value === "object" && value !== null;
|
|
9776
9803
|
}
|
|
9777
9804
|
function getBookingServicePaymentSelectionMode(service) {
|
|
@@ -9965,8 +9992,40 @@ function formatBookingSubmissionPreparationError(error) {
|
|
|
9965
9992
|
default: return assertNever(error);
|
|
9966
9993
|
}
|
|
9967
9994
|
}
|
|
9968
|
-
|
|
9969
|
-
|
|
9995
|
+
const DEFAULT_BOOKING_SUCCESS_COPY = {
|
|
9996
|
+
message: "Your booking has been confirmed.",
|
|
9997
|
+
defaultEmailSentence: "Check your email for details."
|
|
9998
|
+
};
|
|
9999
|
+
const DEFAULT_BOOKING_SUCCESS_MESSAGE = "Your booking has been confirmed. Check your email for details.";
|
|
10000
|
+
function getBookingSuccessCopy(successMessage) {
|
|
10001
|
+
const customMessage = successMessage?.trim();
|
|
10002
|
+
return customMessage && customMessage !== DEFAULT_BOOKING_SUCCESS_MESSAGE ? { message: customMessage } : DEFAULT_BOOKING_SUCCESS_COPY;
|
|
10003
|
+
}
|
|
10004
|
+
//#endregion
|
|
10005
|
+
//#region ../blocks/src/system/runtime/nodes/booking-form.payment-confirmation.ts
|
|
10006
|
+
function bookingServiceRequiresPaymentBeforeBooking(input) {
|
|
10007
|
+
switch (getBookingServicePaymentSelectionMode(input.service)) {
|
|
10008
|
+
case "implicit_upfront":
|
|
10009
|
+
case "implicit_instalment_plan":
|
|
10010
|
+
case "implicit_flexible_balance": return true;
|
|
10011
|
+
case "choice_required": return input.selectedCollectionOptionKind !== void 0 && input.selectedCollectionOptionKind !== "deferred_manual";
|
|
10012
|
+
case "implicit_deferred_manual":
|
|
10013
|
+
case "pending_stripe_setup":
|
|
10014
|
+
case "unsupported": return false;
|
|
10015
|
+
}
|
|
10016
|
+
}
|
|
10017
|
+
function resolveBookingPaymentConfirmationSummary(input) {
|
|
10018
|
+
const service = input.service;
|
|
10019
|
+
if (!service || input.hasSelectedAppointmentPackage || !Number.isFinite(input.priceAmount) || input.priceAmount <= 0 || !service.durationMinutes || !bookingServiceRequiresPaymentBeforeBooking({
|
|
10020
|
+
service,
|
|
10021
|
+
selectedCollectionOptionKind: input.selectedCollectionOptionKind
|
|
10022
|
+
})) return null;
|
|
10023
|
+
return {
|
|
10024
|
+
serviceTitle: service.title,
|
|
10025
|
+
durationMinutes: service.durationMinutes,
|
|
10026
|
+
priceAmount: input.priceAmount,
|
|
10027
|
+
priceCurrency: service.priceCurrency ?? service.pricing?.currency ?? "USD"
|
|
10028
|
+
};
|
|
9970
10029
|
}
|
|
9971
10030
|
//#endregion
|
|
9972
10031
|
//#region ../blocks/src/system/runtime/hooks/useSelectedAppointmentConsentForm.ts
|
|
@@ -10487,6 +10546,54 @@ function selectIsSubmitting(state) {
|
|
|
10487
10546
|
return state.status.tag === "submitting";
|
|
10488
10547
|
}
|
|
10489
10548
|
//#endregion
|
|
10549
|
+
//#region ../blocks/src/system/runtime/shared/utils/demoBookingPassStorage.ts
|
|
10550
|
+
const STORAGE_KEY = "riverbank:demo-booking-passes:v1";
|
|
10551
|
+
const MAX_STORED_PASSES = 10;
|
|
10552
|
+
function normalizeDemoBookingEmail(email) {
|
|
10553
|
+
return email.trim().toLowerCase();
|
|
10554
|
+
}
|
|
10555
|
+
function storeDemoBookingPass(email, pass) {
|
|
10556
|
+
try {
|
|
10557
|
+
const normalizedEmail = normalizeDemoBookingEmail(email);
|
|
10558
|
+
if (!normalizedEmail || !pass) return;
|
|
10559
|
+
const current = readStoredDemoBookingPasses();
|
|
10560
|
+
const updated = [{
|
|
10561
|
+
email: normalizedEmail,
|
|
10562
|
+
pass
|
|
10563
|
+
}, ...current.filter((entry) => entry.email !== normalizedEmail)].slice(0, MAX_STORED_PASSES);
|
|
10564
|
+
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(updated));
|
|
10565
|
+
} catch {}
|
|
10566
|
+
}
|
|
10567
|
+
function storeDemoBookingPassIfAvailable(email, pass) {
|
|
10568
|
+
if (email && pass) storeDemoBookingPass(email, pass);
|
|
10569
|
+
}
|
|
10570
|
+
function getDemoBookingPass(email) {
|
|
10571
|
+
try {
|
|
10572
|
+
const normalizedEmail = normalizeDemoBookingEmail(email);
|
|
10573
|
+
return readStoredDemoBookingPasses().find((entry) => entry.email === normalizedEmail)?.pass ?? null;
|
|
10574
|
+
} catch {
|
|
10575
|
+
return null;
|
|
10576
|
+
}
|
|
10577
|
+
}
|
|
10578
|
+
function readStoredDemoBookingPasses() {
|
|
10579
|
+
try {
|
|
10580
|
+
const raw = window.localStorage.getItem(STORAGE_KEY);
|
|
10581
|
+
if (!raw) return [];
|
|
10582
|
+
const parsed = JSON.parse(raw);
|
|
10583
|
+
return Array.isArray(parsed) ? parsed.filter(isStoredDemoBookingPass) : [];
|
|
10584
|
+
} catch {
|
|
10585
|
+
return [];
|
|
10586
|
+
}
|
|
10587
|
+
}
|
|
10588
|
+
function isStoredDemoBookingPass(value) {
|
|
10589
|
+
if (!isRecord$5(value)) return false;
|
|
10590
|
+
const record = value;
|
|
10591
|
+
return typeof record.email === "string" && record.email.length > 0 && typeof record.pass === "string" && record.pass.length > 0;
|
|
10592
|
+
}
|
|
10593
|
+
function isRecord$5(value) {
|
|
10594
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10595
|
+
}
|
|
10596
|
+
//#endregion
|
|
10490
10597
|
//#region ../blocks/src/system/runtime/hooks/useBookingSubmission.ts
|
|
10491
10598
|
/**
|
|
10492
10599
|
* Custom hook for submitting appointment bookings
|
|
@@ -10552,6 +10659,7 @@ function useBookingSubmission(_siteId) {
|
|
|
10552
10659
|
successUrl: data.successUrl,
|
|
10553
10660
|
cancelUrl: data.cancelUrl
|
|
10554
10661
|
});
|
|
10662
|
+
storeDemoBookingPassIfAvailable(response.customer.email, response.demoBookingPass);
|
|
10555
10663
|
dispatch({
|
|
10556
10664
|
type: "submission-succeeded",
|
|
10557
10665
|
message: response.type === "checkout_redirect" ? "Redirecting to secure checkout..." : "Booking submitted successfully."
|
|
@@ -10590,15 +10698,18 @@ function completeBookingSubmission(input) {
|
|
|
10590
10698
|
kind: "checkout_redirect",
|
|
10591
10699
|
checkoutUrl: data.checkoutUrl,
|
|
10592
10700
|
sessionId: data.sessionId,
|
|
10701
|
+
customerEmail: data.customer.email,
|
|
10702
|
+
...data.demoBookingPass ? { demoBookingPass: data.demoBookingPass } : {},
|
|
10593
10703
|
...data.mailingListSignupNote ? { mailingListSignupNote: data.mailingListSignupNote } : {}
|
|
10594
10704
|
}
|
|
10595
10705
|
};
|
|
10596
10706
|
}
|
|
10707
|
+
const successCopy = getBookingSuccessCopy(input.successMessage);
|
|
10597
10708
|
input.dispatch({
|
|
10598
10709
|
type: "feedback-set",
|
|
10599
10710
|
feedback: {
|
|
10600
10711
|
kind: "success",
|
|
10601
|
-
message:
|
|
10712
|
+
message: successCopy.defaultEmailSentence ? `${successCopy.message} ${successCopy.defaultEmailSentence}`.trim() : successCopy.message,
|
|
10602
10713
|
resourceName: data.appointment.resourceName
|
|
10603
10714
|
}
|
|
10604
10715
|
});
|
|
@@ -10608,6 +10719,8 @@ function completeBookingSubmission(input) {
|
|
|
10608
10719
|
kind: "booked",
|
|
10609
10720
|
appointmentId: data.appointment.id,
|
|
10610
10721
|
resourceName: data.appointment.resourceName,
|
|
10722
|
+
customerEmail: data.customer.email,
|
|
10723
|
+
...data.demoBookingPass ? { demoBookingPass: data.demoBookingPass } : {},
|
|
10611
10724
|
...data.mailingListSignupNote ? { mailingListSignupNote: data.mailingListSignupNote } : {}
|
|
10612
10725
|
}
|
|
10613
10726
|
};
|
|
@@ -11071,11 +11184,11 @@ function formatScheduleDate(isoString, locale) {
|
|
|
11071
11184
|
}
|
|
11072
11185
|
//#endregion
|
|
11073
11186
|
//#region ../blocks/src/system/runtime/nodes/booking-form.service-categories.ts
|
|
11074
|
-
function isRecord$
|
|
11187
|
+
function isRecord$4(value) {
|
|
11075
11188
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11076
11189
|
}
|
|
11077
11190
|
function readCategory(value) {
|
|
11078
|
-
if (!isRecord$
|
|
11191
|
+
if (!isRecord$4(value)) return [];
|
|
11079
11192
|
const { id, name, description } = value;
|
|
11080
11193
|
if (typeof id !== "string" || id.trim() === "" || typeof name !== "string") return [];
|
|
11081
11194
|
return [{
|
|
@@ -11091,7 +11204,7 @@ function readCategory(value) {
|
|
|
11091
11204
|
* it.
|
|
11092
11205
|
*/
|
|
11093
11206
|
function normalizeBookingServiceCategories(services) {
|
|
11094
|
-
if (!isRecord$
|
|
11207
|
+
if (!isRecord$4(services) || !Array.isArray(services.categories)) return [];
|
|
11095
11208
|
return services.categories.flatMap(readCategory);
|
|
11096
11209
|
}
|
|
11097
11210
|
/**
|
|
@@ -11099,7 +11212,7 @@ function normalizeBookingServiceCategories(services) {
|
|
|
11099
11212
|
* its loader data (`data.services`).
|
|
11100
11213
|
*/
|
|
11101
11214
|
function readOverrideServiceCategories(data) {
|
|
11102
|
-
return isRecord$
|
|
11215
|
+
return isRecord$4(data) ? normalizeBookingServiceCategories(data.services) : [];
|
|
11103
11216
|
}
|
|
11104
11217
|
//#endregion
|
|
11105
11218
|
//#region ../blocks/src/system/runtime/nodes/booking-form.validationErrors.ts
|
|
@@ -11865,7 +11978,7 @@ function isBlankFieldValue(value) {
|
|
|
11865
11978
|
return false;
|
|
11866
11979
|
}
|
|
11867
11980
|
function readAppointmentBookingOverrideData(value) {
|
|
11868
|
-
if (!isRecord$
|
|
11981
|
+
if (!isRecord$3(value)) return null;
|
|
11869
11982
|
const services = normalizeBookingServices(value.services);
|
|
11870
11983
|
return {
|
|
11871
11984
|
form: normalizeBookingFormConfig(value.form),
|
|
@@ -11880,7 +11993,7 @@ function createOverrideInputError(reason, message, warnInDev = false) {
|
|
|
11880
11993
|
message
|
|
11881
11994
|
};
|
|
11882
11995
|
}
|
|
11883
|
-
function isRecord$
|
|
11996
|
+
function isRecord$3(value) {
|
|
11884
11997
|
return typeof value === "object" && value !== null;
|
|
11885
11998
|
}
|
|
11886
11999
|
//#endregion
|
|
@@ -12383,6 +12496,12 @@ function useHeadlessBookingFlow(options) {
|
|
|
12383
12496
|
selectedService,
|
|
12384
12497
|
state.selectedSlot?.startAt
|
|
12385
12498
|
]);
|
|
12499
|
+
const paymentConfirmationSummary = resolveBookingPaymentConfirmationSummary({
|
|
12500
|
+
service: selectedService,
|
|
12501
|
+
priceAmount: selectedAppointmentPriceAmount,
|
|
12502
|
+
selectedCollectionOptionKind: state.selectedCollectionOptionKind,
|
|
12503
|
+
hasSelectedAppointmentPackage: Boolean(state.selectedAppointmentPackageId)
|
|
12504
|
+
});
|
|
12386
12505
|
const appointmentPackageItems = appointmentPackages.tag === "loaded" ? appointmentPackages.value : [];
|
|
12387
12506
|
const selectedAppointmentPackage = appointmentPackageItems.find((appointmentPackage) => appointmentPackage.customerPassId === state.selectedAppointmentPackageId) ?? null;
|
|
12388
12507
|
const spamProtectionEnabled = options.spamProtectionEnabled ?? isSpamProtectionEnabled();
|
|
@@ -12412,7 +12531,8 @@ function useHeadlessBookingFlow(options) {
|
|
|
12412
12531
|
selectedSlidingAmount,
|
|
12413
12532
|
slidingScale: selectedServiceSlidingScale,
|
|
12414
12533
|
appointmentPackages: appointmentPackagesModel,
|
|
12415
|
-
errorMessage: paymentResolution.errorMessage ?? "This service cannot be booked right now."
|
|
12534
|
+
errorMessage: paymentResolution.errorMessage ?? "This service cannot be booked right now.",
|
|
12535
|
+
confirmationSummary: null
|
|
12416
12536
|
} : {
|
|
12417
12537
|
kind: "ok",
|
|
12418
12538
|
mode: paymentResolution.mode,
|
|
@@ -12422,7 +12542,8 @@ function useHeadlessBookingFlow(options) {
|
|
|
12422
12542
|
selectedSlidingAmountInput: state.selectedSlidingAmountInput,
|
|
12423
12543
|
selectedSlidingAmount,
|
|
12424
12544
|
slidingScale: selectedServiceSlidingScale,
|
|
12425
|
-
appointmentPackages: appointmentPackagesModel
|
|
12545
|
+
appointmentPackages: appointmentPackagesModel,
|
|
12546
|
+
confirmationSummary: paymentConfirmationSummary
|
|
12426
12547
|
};
|
|
12427
12548
|
return {
|
|
12428
12549
|
mailingList,
|
|
@@ -12580,67 +12701,24 @@ function pollingReducer(state, action) {
|
|
|
12580
12701
|
* Provides a reusable polling mechanism with configurable intervals,
|
|
12581
12702
|
* max attempts, and completion detection. Used by usePaymentVerification
|
|
12582
12703
|
* and other hooks that need to poll for status changes.
|
|
12583
|
-
*
|
|
12584
|
-
* @example
|
|
12585
|
-
* ```tsx
|
|
12586
|
-
* const polling = usePolling(shouldPoll ? {
|
|
12587
|
-
* pollFn: () => api.getStatus(id),
|
|
12588
|
-
* isComplete: (result) => result.status === 'done',
|
|
12589
|
-
* } : null);
|
|
12590
|
-
*
|
|
12591
|
-
* useEffect(() => {
|
|
12592
|
-
* if (polling.status === 'completed') {
|
|
12593
|
-
* handleSuccess(polling.result);
|
|
12594
|
-
* }
|
|
12595
|
-
* }, [polling.status]);
|
|
12596
|
-
* ```
|
|
12597
12704
|
*/
|
|
12598
12705
|
const DEFAULT_MAX_ATTEMPTS = 10;
|
|
12599
12706
|
const DEFAULT_POLL_INTERVAL = 1e3;
|
|
12600
|
-
|
|
12601
|
-
|
|
12602
|
-
|
|
12603
|
-
|
|
12604
|
-
|
|
12605
|
-
|
|
12606
|
-
|
|
12607
|
-
|
|
12608
|
-
|
|
12609
|
-
|
|
12610
|
-
|
|
12611
|
-
|
|
12612
|
-
|
|
12613
|
-
|
|
12614
|
-
|
|
12615
|
-
* ```tsx
|
|
12616
|
-
* // BAD - inline object creates new identity every render
|
|
12617
|
-
* usePolling({
|
|
12618
|
-
* pollFn: () => api.getStatus(id),
|
|
12619
|
-
* isComplete: (result) => result.status === 'done',
|
|
12620
|
-
* });
|
|
12621
|
-
*
|
|
12622
|
-
* // GOOD - memoized config, stable identity
|
|
12623
|
-
* const pollConfig = useMemo(() => shouldPoll ? {
|
|
12624
|
-
* pollFn: () => api.getStatus(id),
|
|
12625
|
-
* isComplete: (result) => result.status === 'done',
|
|
12626
|
-
* } : null, [shouldPoll, api, id]);
|
|
12627
|
-
*
|
|
12628
|
-
* usePolling(pollConfig);
|
|
12629
|
-
* ```
|
|
12630
|
-
*
|
|
12631
|
-
* @param config - Configuration for polling, or null to stop
|
|
12632
|
-
* @returns Polling result with status, data, and retry function
|
|
12633
|
-
*/
|
|
12634
|
-
function usePolling(config) {
|
|
12635
|
-
const [state, dispatch] = useReducer(pollingReducer, void 0, createInitialPollingState);
|
|
12636
|
-
const attemptsRef = useRef(0);
|
|
12637
|
-
const timeoutRef = useRef(null);
|
|
12638
|
-
const isPollingRef = useRef(false);
|
|
12639
|
-
const isActiveRef = useRef(false);
|
|
12640
|
-
const generationRef = useRef(0);
|
|
12641
|
-
const configRef = useRef(config);
|
|
12642
|
-
configRef.current = config;
|
|
12643
|
-
const cleanup = useCallback(() => {
|
|
12707
|
+
function usePollingRuntime(config) {
|
|
12708
|
+
const runtime = {
|
|
12709
|
+
configRef: useRef(config),
|
|
12710
|
+
attemptsRef: useRef(0),
|
|
12711
|
+
timeoutRef: useRef(null),
|
|
12712
|
+
isPollingRef: useRef(false),
|
|
12713
|
+
isActiveRef: useRef(false),
|
|
12714
|
+
generationRef: useRef(0)
|
|
12715
|
+
};
|
|
12716
|
+
runtime.configRef.current = config;
|
|
12717
|
+
return runtime;
|
|
12718
|
+
}
|
|
12719
|
+
function usePollingCleanup(runtime) {
|
|
12720
|
+
const { isActiveRef, generationRef, timeoutRef, isPollingRef } = runtime;
|
|
12721
|
+
return useCallback(() => {
|
|
12644
12722
|
isActiveRef.current = false;
|
|
12645
12723
|
generationRef.current += 1;
|
|
12646
12724
|
if (timeoutRef.current) {
|
|
@@ -12648,16 +12726,27 @@ function usePolling(config) {
|
|
|
12648
12726
|
timeoutRef.current = null;
|
|
12649
12727
|
}
|
|
12650
12728
|
isPollingRef.current = false;
|
|
12651
|
-
}, [
|
|
12652
|
-
|
|
12729
|
+
}, [
|
|
12730
|
+
generationRef,
|
|
12731
|
+
isActiveRef,
|
|
12732
|
+
isPollingRef,
|
|
12733
|
+
timeoutRef
|
|
12734
|
+
]);
|
|
12735
|
+
}
|
|
12736
|
+
function usePollingReset(runtime, dispatch) {
|
|
12737
|
+
const { attemptsRef } = runtime;
|
|
12738
|
+
return useCallback(() => {
|
|
12653
12739
|
dispatch({ type: "polling-reset" });
|
|
12654
12740
|
attemptsRef.current = 0;
|
|
12655
|
-
}, []);
|
|
12656
|
-
|
|
12657
|
-
|
|
12658
|
-
|
|
12741
|
+
}, [attemptsRef, dispatch]);
|
|
12742
|
+
}
|
|
12743
|
+
function usePollingRequest(runtime, dispatch, cleanup) {
|
|
12744
|
+
const { configRef, attemptsRef, isPollingRef, isActiveRef, generationRef } = runtime;
|
|
12745
|
+
return useCallback(async () => {
|
|
12746
|
+
const config = configRef.current;
|
|
12747
|
+
if (!config) return true;
|
|
12659
12748
|
if (isPollingRef.current) return false;
|
|
12660
|
-
const maxAttempts =
|
|
12749
|
+
const maxAttempts = config.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
|
|
12661
12750
|
if (attemptsRef.current >= maxAttempts) {
|
|
12662
12751
|
dispatch({ type: "polling-timed-out" });
|
|
12663
12752
|
cleanup();
|
|
@@ -12667,81 +12756,115 @@ function usePolling(config) {
|
|
|
12667
12756
|
attemptsRef.current += 1;
|
|
12668
12757
|
const generation = generationRef.current;
|
|
12669
12758
|
try {
|
|
12670
|
-
const
|
|
12671
|
-
if (generation !== generationRef.current || !isActiveRef.current)
|
|
12672
|
-
|
|
12673
|
-
return true;
|
|
12674
|
-
}
|
|
12675
|
-
if (cfg.isFailed?.(data)) {
|
|
12759
|
+
const result = await config.pollFn();
|
|
12760
|
+
if (generation !== generationRef.current || !isActiveRef.current) return true;
|
|
12761
|
+
if (config.isFailed?.(result)) {
|
|
12676
12762
|
dispatch({
|
|
12677
12763
|
type: "polling-failed",
|
|
12678
|
-
result
|
|
12764
|
+
result
|
|
12679
12765
|
});
|
|
12680
12766
|
cleanup();
|
|
12681
12767
|
return true;
|
|
12682
12768
|
}
|
|
12683
|
-
if (
|
|
12769
|
+
if (config.isComplete(result)) {
|
|
12684
12770
|
dispatch({
|
|
12685
12771
|
type: "polling-completed",
|
|
12686
|
-
result
|
|
12772
|
+
result
|
|
12687
12773
|
});
|
|
12688
12774
|
cleanup();
|
|
12689
12775
|
return true;
|
|
12690
12776
|
}
|
|
12691
12777
|
dispatch({
|
|
12692
12778
|
type: "polling-progressed",
|
|
12693
|
-
result
|
|
12779
|
+
result
|
|
12694
12780
|
});
|
|
12695
12781
|
isPollingRef.current = false;
|
|
12696
12782
|
return false;
|
|
12697
|
-
} catch (
|
|
12698
|
-
if (generation !== generationRef.current || !isActiveRef.current)
|
|
12699
|
-
|
|
12700
|
-
return true;
|
|
12701
|
-
}
|
|
12702
|
-
if (err instanceof Error) dispatch({
|
|
12783
|
+
} catch (error) {
|
|
12784
|
+
if (generation !== generationRef.current || !isActiveRef.current) return true;
|
|
12785
|
+
if (error instanceof Error) dispatch({
|
|
12703
12786
|
type: "polling-request-failed",
|
|
12704
|
-
error
|
|
12787
|
+
error
|
|
12705
12788
|
});
|
|
12706
12789
|
isPollingRef.current = false;
|
|
12707
12790
|
return false;
|
|
12708
12791
|
}
|
|
12709
|
-
}, [
|
|
12710
|
-
|
|
12792
|
+
}, [
|
|
12793
|
+
attemptsRef,
|
|
12794
|
+
cleanup,
|
|
12795
|
+
configRef,
|
|
12796
|
+
dispatch,
|
|
12797
|
+
generationRef,
|
|
12798
|
+
isActiveRef,
|
|
12799
|
+
isPollingRef
|
|
12800
|
+
]);
|
|
12801
|
+
}
|
|
12802
|
+
function usePollingScheduler(runtime, poll) {
|
|
12803
|
+
const { attemptsRef, configRef, isActiveRef, timeoutRef } = runtime;
|
|
12804
|
+
return useCallback(() => {
|
|
12711
12805
|
if (!isActiveRef.current) return;
|
|
12712
|
-
const pollInterval = configRef.current?.interval ?? DEFAULT_POLL_INTERVAL;
|
|
12713
12806
|
const doPoll = async () => {
|
|
12714
|
-
if (!await poll() && isActiveRef.current)
|
|
12807
|
+
if (!await poll() && isActiveRef.current) {
|
|
12808
|
+
const configuredInterval = configRef.current?.interval;
|
|
12809
|
+
const interval = typeof configuredInterval === "function" ? configuredInterval(attemptsRef.current) : configuredInterval ?? DEFAULT_POLL_INTERVAL;
|
|
12810
|
+
timeoutRef.current = setTimeout(doPoll, interval);
|
|
12811
|
+
}
|
|
12715
12812
|
};
|
|
12716
12813
|
doPoll();
|
|
12717
|
-
}, [
|
|
12814
|
+
}, [
|
|
12815
|
+
attemptsRef,
|
|
12816
|
+
configRef,
|
|
12817
|
+
isActiveRef,
|
|
12818
|
+
poll,
|
|
12819
|
+
timeoutRef
|
|
12820
|
+
]);
|
|
12821
|
+
}
|
|
12822
|
+
function usePollingCycle(config, runtime, dispatch) {
|
|
12823
|
+
const cleanup = usePollingCleanup(runtime);
|
|
12824
|
+
const resetState = usePollingReset(runtime, dispatch);
|
|
12825
|
+
const schedulePoll = usePollingScheduler(runtime, usePollingRequest(runtime, dispatch, cleanup));
|
|
12826
|
+
const pollingEnabled = config !== null;
|
|
12718
12827
|
useEffect(() => {
|
|
12719
|
-
if (!
|
|
12828
|
+
if (!pollingEnabled) {
|
|
12720
12829
|
cleanup();
|
|
12721
12830
|
dispatch({ type: "polling-went-idle" });
|
|
12722
12831
|
return;
|
|
12723
12832
|
}
|
|
12724
12833
|
resetState();
|
|
12725
|
-
isActiveRef.current = true;
|
|
12834
|
+
runtime.isActiveRef.current = true;
|
|
12726
12835
|
schedulePoll();
|
|
12727
12836
|
return cleanup;
|
|
12728
12837
|
}, [
|
|
12729
|
-
config,
|
|
12730
12838
|
cleanup,
|
|
12839
|
+
dispatch,
|
|
12840
|
+
pollingEnabled,
|
|
12731
12841
|
resetState,
|
|
12842
|
+
config?.restartKey ?? null,
|
|
12843
|
+
runtime.isActiveRef,
|
|
12732
12844
|
schedulePoll
|
|
12733
12845
|
]);
|
|
12734
|
-
|
|
12735
|
-
if (!configRef.current) return;
|
|
12846
|
+
return useCallback(() => {
|
|
12847
|
+
if (!runtime.configRef.current) return;
|
|
12736
12848
|
cleanup();
|
|
12737
12849
|
resetState();
|
|
12738
|
-
isActiveRef.current = true;
|
|
12850
|
+
runtime.isActiveRef.current = true;
|
|
12739
12851
|
schedulePoll();
|
|
12740
12852
|
}, [
|
|
12741
12853
|
cleanup,
|
|
12742
12854
|
resetState,
|
|
12855
|
+
runtime.configRef,
|
|
12856
|
+
runtime.isActiveRef,
|
|
12743
12857
|
schedulePoll
|
|
12744
12858
|
]);
|
|
12859
|
+
}
|
|
12860
|
+
/**
|
|
12861
|
+
* Polls until the operation completes, fails, times out, or becomes disabled.
|
|
12862
|
+
* Config objects may be rebuilt across renders; change restartKey to begin a
|
|
12863
|
+
* new operation and reset its attempt budget.
|
|
12864
|
+
*/
|
|
12865
|
+
function usePolling(config) {
|
|
12866
|
+
const [state, dispatch] = useReducer(pollingReducer, void 0, createInitialPollingState);
|
|
12867
|
+
const retry = usePollingCycle(config, usePollingRuntime(config), dispatch);
|
|
12745
12868
|
return {
|
|
12746
12869
|
status: config ? state.tag : "idle",
|
|
12747
12870
|
result: config ? state.result : null,
|
|
@@ -12751,6 +12874,10 @@ function usePolling(config) {
|
|
|
12751
12874
|
}
|
|
12752
12875
|
//#endregion
|
|
12753
12876
|
//#region ../blocks/src/system/runtime/hooks/useAppointmentCheckoutVerification.ts
|
|
12877
|
+
const APPOINTMENT_CHECKOUT_MAX_ATTEMPTS = 12;
|
|
12878
|
+
function resolveAppointmentCheckoutPollInterval(attempt) {
|
|
12879
|
+
return Math.min(1e3 * 2 ** (attempt - 1), 4e3);
|
|
12880
|
+
}
|
|
12754
12881
|
const appointmentCheckoutVerificationDeps = {
|
|
12755
12882
|
useBlockApi,
|
|
12756
12883
|
usePolling
|
|
@@ -12760,16 +12887,25 @@ function useAppointmentCheckoutVerification(config) {
|
|
|
12760
12887
|
}
|
|
12761
12888
|
function useAppointmentCheckoutVerificationWithDeps(config, deps) {
|
|
12762
12889
|
const api = deps.useBlockApi();
|
|
12890
|
+
const sessionId = config?.sessionId ?? null;
|
|
12891
|
+
const maxAttempts = config?.maxAttempts;
|
|
12892
|
+
const pollInterval = config?.pollInterval;
|
|
12763
12893
|
const pollingConfig = useMemo(() => {
|
|
12764
|
-
if (
|
|
12894
|
+
if (sessionId === null) return null;
|
|
12765
12895
|
return {
|
|
12766
|
-
|
|
12896
|
+
restartKey: sessionId,
|
|
12897
|
+
pollFn: () => api.getAppointmentBookingStatus({ sessionId }),
|
|
12767
12898
|
isComplete: (result) => (result.paymentStatus === "completed" || result.paymentStatus === "not_required") && result.appointmentStatus === "confirmed",
|
|
12768
12899
|
isFailed: (result) => result.paymentStatus === "failed" || result.paymentStatus === "cancelled" || result.paymentStatus === "refunded" || result.appointmentStatus === "cancelled",
|
|
12769
|
-
maxAttempts:
|
|
12770
|
-
interval:
|
|
12900
|
+
maxAttempts: maxAttempts ?? APPOINTMENT_CHECKOUT_MAX_ATTEMPTS,
|
|
12901
|
+
interval: pollInterval ?? resolveAppointmentCheckoutPollInterval
|
|
12771
12902
|
};
|
|
12772
|
-
}, [
|
|
12903
|
+
}, [
|
|
12904
|
+
api,
|
|
12905
|
+
sessionId,
|
|
12906
|
+
maxAttempts,
|
|
12907
|
+
pollInterval
|
|
12908
|
+
]);
|
|
12773
12909
|
const polling = deps.usePolling(pollingConfig);
|
|
12774
12910
|
return {
|
|
12775
12911
|
state: resolveAppointmentCheckoutVerificationState({
|
|
@@ -13381,11 +13517,18 @@ function isReservedPathSegment(value) {
|
|
|
13381
13517
|
function isUnsafePathSegment(segment) {
|
|
13382
13518
|
return segment.trim().length === 0 || segment !== segment.trim() || isReservedPathSegment(segment) || containsUnsafePathSegmentCharacter(segment);
|
|
13383
13519
|
}
|
|
13384
|
-
|
|
13520
|
+
//#endregion
|
|
13521
|
+
//#region ../media-core/src/fileStorage.ts
|
|
13522
|
+
const FILE_STORAGE_BUCKETS = {
|
|
13385
13523
|
publicSite: unsafeAsStorageBucketName("media"),
|
|
13386
13524
|
privateSite: unsafeAsStorageBucketName("site-files-private"),
|
|
13387
|
-
temporary: unsafeAsStorageBucketName("temp-uploads")
|
|
13388
|
-
|
|
13525
|
+
temporary: unsafeAsStorageBucketName("temp-uploads"),
|
|
13526
|
+
siteAssets: unsafeAsStorageBucketName("site-assets"),
|
|
13527
|
+
siteFonts: unsafeAsStorageBucketName("site-fonts"),
|
|
13528
|
+
bookingRequirementDocuments: unsafeAsStorageBucketName("booking-requirement-documents")
|
|
13529
|
+
};
|
|
13530
|
+
FILE_STORAGE_BUCKETS.publicSite, FILE_STORAGE_BUCKETS.siteAssets, FILE_STORAGE_BUCKETS.siteFonts;
|
|
13531
|
+
FILE_STORAGE_BUCKETS.publicSite, FILE_STORAGE_BUCKETS.privateSite, FILE_STORAGE_BUCKETS.temporary, FILE_STORAGE_BUCKETS.siteAssets, FILE_STORAGE_BUCKETS.siteFonts, FILE_STORAGE_BUCKETS.bookingRequirementDocuments;
|
|
13389
13532
|
function parseStoragePath(value) {
|
|
13390
13533
|
return joinStoragePathSegments(value.split("/"));
|
|
13391
13534
|
}
|
|
@@ -14211,6 +14354,72 @@ function ServiceChoiceGrid({ booking, choices }) {
|
|
|
14211
14354
|
});
|
|
14212
14355
|
}
|
|
14213
14356
|
//#endregion
|
|
14357
|
+
//#region ../blocks/src/system/runtime/nodes/booking-form.submit-actions.tsx
|
|
14358
|
+
function resolvePrimaryActionLabel(isLastStep, requiresPayment) {
|
|
14359
|
+
if (!isLastStep) return "Continue";
|
|
14360
|
+
return requiresPayment ? "Continue to payment" : "Complete";
|
|
14361
|
+
}
|
|
14362
|
+
function formatBookingConfirmationDateTime(booking) {
|
|
14363
|
+
const startAt = booking.currentStep?.id === "datetime-selection" ? booking.availability.selectedSlot?.startAt : void 0;
|
|
14364
|
+
return startAt ? new Intl.DateTimeFormat(void 0, {
|
|
14365
|
+
dateStyle: "medium",
|
|
14366
|
+
timeStyle: "short",
|
|
14367
|
+
timeZone: booking.availability.timezone
|
|
14368
|
+
}).format(new Date(startAt)) : null;
|
|
14369
|
+
}
|
|
14370
|
+
function BookingPaymentConfirmationText({ booking, summary }) {
|
|
14371
|
+
if (!summary) return null;
|
|
14372
|
+
const dateTime = formatBookingConfirmationDateTime(booking);
|
|
14373
|
+
return /* @__PURE__ */ jsxs("p", {
|
|
14374
|
+
className: "ab-text rb-on-surface--muted",
|
|
14375
|
+
children: [
|
|
14376
|
+
summary.serviceTitle,
|
|
14377
|
+
" · ",
|
|
14378
|
+
summary.durationMinutes,
|
|
14379
|
+
" min ·",
|
|
14380
|
+
" ",
|
|
14381
|
+
formatCurrencyAmount(summary.priceAmount, summary.priceCurrency, { decimals: "auto" }),
|
|
14382
|
+
dateTime ? ` · ${dateTime}` : ""
|
|
14383
|
+
]
|
|
14384
|
+
});
|
|
14385
|
+
}
|
|
14386
|
+
function BookingFormSubmitActions({ booking, onSubmit }) {
|
|
14387
|
+
const currentStepIndex = booking.currentStep?.visibleIndex ?? 0;
|
|
14388
|
+
const isFirstStep = currentStepIndex === 0;
|
|
14389
|
+
const isLastStep = currentStepIndex === booking.steps.length - 1;
|
|
14390
|
+
const isSubmitting = booking.status.tag === "submitting";
|
|
14391
|
+
const paymentSummary = isLastStep && booking.payment.kind === "ok" ? booking.payment.confirmationSummary : null;
|
|
14392
|
+
const handlePrimaryAction = async () => {
|
|
14393
|
+
if ((await booking.actions.next()).ok && isLastStep) await onSubmit();
|
|
14394
|
+
};
|
|
14395
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(BookingPaymentConfirmationText, {
|
|
14396
|
+
booking,
|
|
14397
|
+
summary: paymentSummary
|
|
14398
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
14399
|
+
className: "rb-wizard-actions",
|
|
14400
|
+
children: [!isFirstStep ? /* @__PURE__ */ jsx(ThemedButton, {
|
|
14401
|
+
type: "button",
|
|
14402
|
+
onClick: booking.actions.back,
|
|
14403
|
+
variant: "outline",
|
|
14404
|
+
size: "md",
|
|
14405
|
+
label: "Back"
|
|
14406
|
+
}) : null, /* @__PURE__ */ jsx(ThemedButton, {
|
|
14407
|
+
type: "button",
|
|
14408
|
+
onClick: () => {
|
|
14409
|
+
handlePrimaryAction();
|
|
14410
|
+
},
|
|
14411
|
+
disabled: isSubmitting,
|
|
14412
|
+
variant: "primary",
|
|
14413
|
+
size: "md",
|
|
14414
|
+
label: resolvePrimaryActionLabel(isLastStep, Boolean(paymentSummary)),
|
|
14415
|
+
pending: isSubmitting ? {
|
|
14416
|
+
label: "Submitting...",
|
|
14417
|
+
srLabel: "Submitting"
|
|
14418
|
+
} : void 0
|
|
14419
|
+
})]
|
|
14420
|
+
})] });
|
|
14421
|
+
}
|
|
14422
|
+
//#endregion
|
|
14214
14423
|
//#region ../blocks/src/system/runtime/nodes/booking-form.default-ui.tsx
|
|
14215
14424
|
function formatBookingAmount(amount, currency) {
|
|
14216
14425
|
return formatCurrencyAmount(amount, currency, { decimals: "auto" });
|
|
@@ -14219,13 +14428,6 @@ function HeadlessBookingDefaultForm({ booking, onSubmit }) {
|
|
|
14219
14428
|
const currentStep = booking.currentStep;
|
|
14220
14429
|
const errorSummaryId = React.useId();
|
|
14221
14430
|
const currentStepIndex = currentStep?.visibleIndex ?? 0;
|
|
14222
|
-
const isFirstStep = currentStepIndex === 0;
|
|
14223
|
-
const isLastStep = currentStepIndex === booking.steps.length - 1;
|
|
14224
|
-
const isSubmitting = booking.status.tag === "submitting";
|
|
14225
|
-
const handlePrimaryAction = async () => {
|
|
14226
|
-
if (!(await booking.actions.next()).ok) return;
|
|
14227
|
-
if (isLastStep) await onSubmit();
|
|
14228
|
-
};
|
|
14229
14431
|
if (!currentStep) return /* @__PURE__ */ jsx("div", {
|
|
14230
14432
|
className: "rb-text-center rb-py-12",
|
|
14231
14433
|
children: /* @__PURE__ */ jsx("p", {
|
|
@@ -14253,28 +14455,9 @@ function HeadlessBookingDefaultForm({ booking, onSubmit }) {
|
|
|
14253
14455
|
errors: currentStep.errors,
|
|
14254
14456
|
id: errorSummaryId
|
|
14255
14457
|
}),
|
|
14256
|
-
/* @__PURE__ */
|
|
14257
|
-
|
|
14258
|
-
|
|
14259
|
-
type: "button",
|
|
14260
|
-
onClick: booking.actions.back,
|
|
14261
|
-
variant: "outline",
|
|
14262
|
-
size: "md",
|
|
14263
|
-
label: "Back"
|
|
14264
|
-
}) : null, /* @__PURE__ */ jsx(ThemedButton, {
|
|
14265
|
-
type: "button",
|
|
14266
|
-
onClick: () => {
|
|
14267
|
-
handlePrimaryAction();
|
|
14268
|
-
},
|
|
14269
|
-
disabled: isSubmitting,
|
|
14270
|
-
variant: "primary",
|
|
14271
|
-
size: "md",
|
|
14272
|
-
label: isLastStep ? "Complete" : "Continue",
|
|
14273
|
-
pending: isSubmitting ? {
|
|
14274
|
-
label: "Submitting...",
|
|
14275
|
-
srLabel: "Submitting"
|
|
14276
|
-
} : void 0
|
|
14277
|
-
})]
|
|
14458
|
+
/* @__PURE__ */ jsx(BookingFormSubmitActions, {
|
|
14459
|
+
booking,
|
|
14460
|
+
onSubmit
|
|
14278
14461
|
}),
|
|
14279
14462
|
/* @__PURE__ */ jsx(DefaultBookingDiscount, { booking }),
|
|
14280
14463
|
/* @__PURE__ */ jsx(DefaultBookingFeedback, { booking }),
|
|
@@ -15004,8 +15187,148 @@ function TerminalPanel({ tone, title, titleAs: Title = "h3", body, secondaryBody
|
|
|
15004
15187
|
});
|
|
15005
15188
|
}
|
|
15006
15189
|
//#endregion
|
|
15190
|
+
//#region ../blocks/src/system/runtime/shared/utils/demoPortalMagicLink.ts
|
|
15191
|
+
const CUSTOMER_PORTAL_PATH = "/portal";
|
|
15192
|
+
function buildPortalCallbackUrl(origin, redirectTo) {
|
|
15193
|
+
const url = new URL("/api/portal/callback", origin);
|
|
15194
|
+
url.searchParams.set("redirect_to", redirectTo);
|
|
15195
|
+
return url.toString();
|
|
15196
|
+
}
|
|
15197
|
+
async function requestDemoPortalMagicLink(input) {
|
|
15198
|
+
const email = normalizeDemoBookingEmail(input.email);
|
|
15199
|
+
const pass = getDemoBookingPass(email);
|
|
15200
|
+
const request = {
|
|
15201
|
+
email,
|
|
15202
|
+
redirectUrl: input.redirectUrl,
|
|
15203
|
+
...pass ? { demoBookingPass: pass } : {}
|
|
15204
|
+
};
|
|
15205
|
+
try {
|
|
15206
|
+
const response = await input.send(request);
|
|
15207
|
+
if ("kind" in response) return {
|
|
15208
|
+
kind: "refused",
|
|
15209
|
+
message: response.message
|
|
15210
|
+
};
|
|
15211
|
+
return "demoSignInUrl" in response ? {
|
|
15212
|
+
kind: "demo_sign_in",
|
|
15213
|
+
url: response.demoSignInUrl
|
|
15214
|
+
} : { kind: "email_sent" };
|
|
15215
|
+
} catch (error) {
|
|
15216
|
+
if (error instanceof BlockApiError && error.tag === "demo_email_not_booked_here") return {
|
|
15217
|
+
kind: "refused",
|
|
15218
|
+
message: error.message
|
|
15219
|
+
};
|
|
15220
|
+
throw error;
|
|
15221
|
+
}
|
|
15222
|
+
}
|
|
15223
|
+
//#endregion
|
|
15224
|
+
//#region ../blocks/src/system/runtime/shared/components/DemoBookingPortalAccess.tsx
|
|
15225
|
+
const SUPPRESSED_CONFIRMATION_NOTE = "This is a demo, so we haven’t sent a confirmation email. You can still see your booking in the customer portal.";
|
|
15226
|
+
function BookingConfirmation(props) {
|
|
15227
|
+
const content = renderConfirmationMessage((props.demoEmailSuppressed ? [props.copy.message] : [props.copy.message, props.copy.defaultEmailSentence ?? ""]).filter((part) => part.trim().length > 0).join(" "), props.messagePresentation);
|
|
15228
|
+
if (!props.demoEmailSuppressed) return content;
|
|
15229
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [content, /* @__PURE__ */ jsx(DemoBookingPortalAccess, {
|
|
15230
|
+
email: props.email,
|
|
15231
|
+
noteClassName: props.noteClassName,
|
|
15232
|
+
showConfirmationNote: props.showConfirmationNote
|
|
15233
|
+
})] });
|
|
15234
|
+
}
|
|
15235
|
+
function DemoBookingPortalAccess(props) {
|
|
15236
|
+
const { state, openPortal } = useDemoBookingPortalAccess(props.email);
|
|
15237
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
15238
|
+
className: "rb-mt-4 rb-flex rb-flex-col rb-items-start rb-gap-3",
|
|
15239
|
+
"data-testid": "demo-booking-portal-access",
|
|
15240
|
+
children: [
|
|
15241
|
+
props.showConfirmationNote === false ? null : /* @__PURE__ */ jsx("p", {
|
|
15242
|
+
className: props.noteClassName ?? "ab-text",
|
|
15243
|
+
children: SUPPRESSED_CONFIRMATION_NOTE
|
|
15244
|
+
}),
|
|
15245
|
+
/* @__PURE__ */ jsx(ThemedButton, {
|
|
15246
|
+
type: "button",
|
|
15247
|
+
variant: "default",
|
|
15248
|
+
size: "md",
|
|
15249
|
+
label: state.tag === "opening" ? "Opening…" : "Open the customer portal",
|
|
15250
|
+
disabled: state.tag === "opening",
|
|
15251
|
+
onClick: openPortal
|
|
15252
|
+
}),
|
|
15253
|
+
state.tag === "refused" ? /* @__PURE__ */ jsx("p", {
|
|
15254
|
+
role: "alert",
|
|
15255
|
+
children: state.message
|
|
15256
|
+
}) : null,
|
|
15257
|
+
state.tag === "error" ? /* @__PURE__ */ jsx("p", {
|
|
15258
|
+
role: "alert",
|
|
15259
|
+
children: state.message
|
|
15260
|
+
}) : null
|
|
15261
|
+
]
|
|
15262
|
+
});
|
|
15263
|
+
}
|
|
15264
|
+
function renderConfirmationMessage(message, presentation) {
|
|
15265
|
+
if (!message) return null;
|
|
15266
|
+
switch (presentation.kind) {
|
|
15267
|
+
case "paragraph": return /* @__PURE__ */ jsx("p", {
|
|
15268
|
+
className: presentation.className,
|
|
15269
|
+
children: message
|
|
15270
|
+
});
|
|
15271
|
+
case "plain": return message;
|
|
15272
|
+
}
|
|
15273
|
+
}
|
|
15274
|
+
function useDemoBookingPortalAccess(email) {
|
|
15275
|
+
const api = useBlockApi();
|
|
15276
|
+
const [state, setState] = React.useState({ tag: "idle" });
|
|
15277
|
+
const openPortal = async () => {
|
|
15278
|
+
if (state.tag === "opening") return;
|
|
15279
|
+
if (!email) {
|
|
15280
|
+
setState({
|
|
15281
|
+
tag: "error",
|
|
15282
|
+
message: "We couldn’t open the customer portal. Please try again."
|
|
15283
|
+
});
|
|
15284
|
+
return;
|
|
15285
|
+
}
|
|
15286
|
+
setState({ tag: "opening" });
|
|
15287
|
+
try {
|
|
15288
|
+
const result = await requestDemoPortalMagicLink({
|
|
15289
|
+
email,
|
|
15290
|
+
redirectUrl: buildPortalCallbackUrl(window.location.origin, CUSTOMER_PORTAL_PATH),
|
|
15291
|
+
send: (request) => api.sendMagicLink(request)
|
|
15292
|
+
});
|
|
15293
|
+
switch (result.kind) {
|
|
15294
|
+
case "demo_sign_in":
|
|
15295
|
+
window.location.assign(result.url);
|
|
15296
|
+
return;
|
|
15297
|
+
case "refused":
|
|
15298
|
+
setState({
|
|
15299
|
+
tag: "refused",
|
|
15300
|
+
message: result.message
|
|
15301
|
+
});
|
|
15302
|
+
return;
|
|
15303
|
+
case "email_sent":
|
|
15304
|
+
setState({ tag: "idle" });
|
|
15305
|
+
return;
|
|
15306
|
+
}
|
|
15307
|
+
} catch (error) {
|
|
15308
|
+
setState(handlePortalAccessError(error));
|
|
15309
|
+
}
|
|
15310
|
+
};
|
|
15311
|
+
return {
|
|
15312
|
+
state,
|
|
15313
|
+
openPortal
|
|
15314
|
+
};
|
|
15315
|
+
}
|
|
15316
|
+
function handlePortalAccessError(error) {
|
|
15317
|
+
if (error instanceof BlockApiError && error.tag === "demo_email_not_booked_here") return {
|
|
15318
|
+
tag: "refused",
|
|
15319
|
+
message: error.message
|
|
15320
|
+
};
|
|
15321
|
+
return error instanceof BlockApiError ? {
|
|
15322
|
+
tag: "error",
|
|
15323
|
+
message: error.message
|
|
15324
|
+
} : {
|
|
15325
|
+
tag: "error",
|
|
15326
|
+
message: "We couldn’t open the customer portal. Please try again."
|
|
15327
|
+
};
|
|
15328
|
+
}
|
|
15329
|
+
//#endregion
|
|
15007
15330
|
//#region ../blocks/src/system/runtime/components/booking/SuccessMessage.tsx
|
|
15008
|
-
const SuccessMessage = ({
|
|
15331
|
+
const SuccessMessage = ({ copy, resourceName, className, demoEmailSuppressed = false, customerEmail = null }) => {
|
|
15009
15332
|
return /* @__PURE__ */ jsx(TerminalPanel, {
|
|
15010
15333
|
tone: "success",
|
|
15011
15334
|
title: "Booking confirmed",
|
|
@@ -15013,9 +15336,15 @@ const SuccessMessage = ({ message, resourceName, className }) => {
|
|
|
15013
15336
|
variant: "success",
|
|
15014
15337
|
children: /* @__PURE__ */ jsx(CheckIcon, { strokeWidth: 3 })
|
|
15015
15338
|
}),
|
|
15016
|
-
body: /* @__PURE__ */ jsx(
|
|
15017
|
-
|
|
15018
|
-
|
|
15339
|
+
body: /* @__PURE__ */ jsx(BookingConfirmation, {
|
|
15340
|
+
demoEmailSuppressed,
|
|
15341
|
+
email: customerEmail,
|
|
15342
|
+
copy,
|
|
15343
|
+
messagePresentation: {
|
|
15344
|
+
kind: "paragraph",
|
|
15345
|
+
className: "ab-text"
|
|
15346
|
+
},
|
|
15347
|
+
noteClassName: "ab-text"
|
|
15019
15348
|
}),
|
|
15020
15349
|
secondaryBody: resourceName ? /* @__PURE__ */ jsxs("p", {
|
|
15021
15350
|
className: "ab-text rb-on-surface--muted",
|
|
@@ -15051,31 +15380,54 @@ function BookingMailingListNote(props) {
|
|
|
15051
15380
|
});
|
|
15052
15381
|
}
|
|
15053
15382
|
//#endregion
|
|
15054
|
-
//#region ../blocks/src/system/runtime/nodes/booking-form.
|
|
15383
|
+
//#region ../blocks/src/system/runtime/nodes/booking-form.checkout-return-context.ts
|
|
15055
15384
|
function storageKey(sessionId) {
|
|
15056
15385
|
return `riverbank:booking:mailing-list:${sessionId}`;
|
|
15057
15386
|
}
|
|
15058
|
-
function
|
|
15059
|
-
if (!
|
|
15387
|
+
function saveAppointmentCheckoutReturnContext(sessionId, context) {
|
|
15388
|
+
if (!context.customerEmail && !context.mailingListNote) return;
|
|
15060
15389
|
try {
|
|
15061
|
-
window.sessionStorage.setItem(storageKey(sessionId),
|
|
15390
|
+
window.sessionStorage.setItem(storageKey(sessionId), JSON.stringify(context));
|
|
15062
15391
|
} catch {}
|
|
15063
15392
|
}
|
|
15064
|
-
function
|
|
15393
|
+
function readAppointmentCheckoutReturnContext(sessionId) {
|
|
15065
15394
|
try {
|
|
15066
15395
|
const stored = window.sessionStorage.getItem(storageKey(sessionId));
|
|
15067
|
-
|
|
15396
|
+
if (!stored) return null;
|
|
15397
|
+
return parseContext(stored);
|
|
15068
15398
|
} catch {
|
|
15069
15399
|
return null;
|
|
15070
15400
|
}
|
|
15071
15401
|
}
|
|
15402
|
+
function parseContext(value) {
|
|
15403
|
+
try {
|
|
15404
|
+
const parsed = JSON.parse(value);
|
|
15405
|
+
return isContext(parsed) ? parsed : null;
|
|
15406
|
+
} catch {
|
|
15407
|
+
return value === "confirmation_required" || value === "not_confirmed" ? {
|
|
15408
|
+
customerEmail: null,
|
|
15409
|
+
mailingListNote: value
|
|
15410
|
+
} : null;
|
|
15411
|
+
}
|
|
15412
|
+
}
|
|
15413
|
+
function isContext(value) {
|
|
15414
|
+
if (!isRecord$2(value)) return false;
|
|
15415
|
+
return (typeof value.customerEmail === "string" || value.customerEmail === null) && (value.mailingListNote === null || value.mailingListNote === "confirmation_required" || value.mailingListNote === "not_confirmed");
|
|
15416
|
+
}
|
|
15417
|
+
function isRecord$2(value) {
|
|
15418
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
15419
|
+
}
|
|
15072
15420
|
//#endregion
|
|
15073
15421
|
//#region ../blocks/src/system/runtime/nodes/booking-form.completion.tsx
|
|
15074
|
-
function BookingFormCompletion({ resourceName, successMessage, redirectState, localNote }) {
|
|
15075
|
-
const
|
|
15422
|
+
function BookingFormCompletion({ resourceName, successMessage, redirectState, localNote, customerEmail, demoEmailSuppressed = false }) {
|
|
15423
|
+
const returnContext = redirectState.kind === "success" ? readAppointmentCheckoutReturnContext(redirectState.sessionId) : null;
|
|
15424
|
+
const note = redirectState.kind === "success" ? returnContext?.mailingListNote ?? null : localNote;
|
|
15425
|
+
const confirmedEmail = returnContext?.customerEmail ?? customerEmail;
|
|
15076
15426
|
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(SuccessMessage, {
|
|
15077
|
-
|
|
15078
|
-
resourceName
|
|
15427
|
+
copy: getBookingSuccessCopy(successMessage),
|
|
15428
|
+
resourceName,
|
|
15429
|
+
demoEmailSuppressed,
|
|
15430
|
+
customerEmail: confirmedEmail
|
|
15079
15431
|
}), note ? /* @__PURE__ */ jsx(BookingMailingListNote, {
|
|
15080
15432
|
note,
|
|
15081
15433
|
context: "booking",
|
|
@@ -15099,12 +15451,17 @@ function createBookingFormSubmitHandler(input) {
|
|
|
15099
15451
|
cancelUrl: appendRebookFlag(cancelUrl, input.isPortalRebook)
|
|
15100
15452
|
});
|
|
15101
15453
|
if (!result.ok) return;
|
|
15454
|
+
storeDemoBookingPassIfAvailable(result.outcome.customerEmail, result.outcome.demoBookingPass);
|
|
15102
15455
|
if (result.outcome.kind === "checkout_redirect") {
|
|
15103
|
-
|
|
15456
|
+
saveAppointmentCheckoutReturnContext(result.outcome.sessionId, {
|
|
15457
|
+
customerEmail: result.outcome.customerEmail,
|
|
15458
|
+
mailingListNote: result.outcome.mailingListSignupNote ?? null
|
|
15459
|
+
});
|
|
15104
15460
|
window.location.href = result.outcome.checkoutUrl;
|
|
15105
15461
|
return;
|
|
15106
15462
|
}
|
|
15107
15463
|
input.setLocalMailingListNote(result.outcome.mailingListSignupNote ?? null);
|
|
15464
|
+
input.setLocalCustomerEmail(result.outcome.customerEmail);
|
|
15108
15465
|
};
|
|
15109
15466
|
}
|
|
15110
15467
|
//#endregion
|
|
@@ -15144,6 +15501,7 @@ const BookingFormClient$1 = ({ siteId: siteIdProp, render }) => {
|
|
|
15144
15501
|
const hasLoggedRebookCompletionRef = useRef(false);
|
|
15145
15502
|
const [redirectState] = useState(() => getBookingRedirectStateFromLocation(getBookingRedirectLocationSnapshot()));
|
|
15146
15503
|
const [localMailingListNote, setLocalMailingListNote] = useState(null);
|
|
15504
|
+
const [localCustomerEmail, setLocalCustomerEmail] = useState(null);
|
|
15147
15505
|
const showSpamProtection = render.hydration.spamProtectionEnabled ?? isSpamProtectionEnabled();
|
|
15148
15506
|
const api = useBlockApi();
|
|
15149
15507
|
const hasPortalAuth = api.config.auth.type === "bearer" || api.config.authOverrides?.portal?.type === "bearer";
|
|
@@ -15226,7 +15584,8 @@ const BookingFormClient$1 = ({ siteId: siteIdProp, render }) => {
|
|
|
15226
15584
|
booking,
|
|
15227
15585
|
bookingAnchorId,
|
|
15228
15586
|
isPortalRebook,
|
|
15229
|
-
setLocalMailingListNote
|
|
15587
|
+
setLocalMailingListNote,
|
|
15588
|
+
setLocalCustomerEmail
|
|
15230
15589
|
});
|
|
15231
15590
|
if (viewState.kind === "success") return /* @__PURE__ */ jsx(BookingSurface, {
|
|
15232
15591
|
id: bookingAnchorId,
|
|
@@ -15235,7 +15594,9 @@ const BookingFormClient$1 = ({ siteId: siteIdProp, render }) => {
|
|
|
15235
15594
|
successMessage: render.display.successMessage,
|
|
15236
15595
|
resourceName: viewState.resourceName,
|
|
15237
15596
|
redirectState,
|
|
15238
|
-
localNote: localMailingListNote
|
|
15597
|
+
localNote: localMailingListNote,
|
|
15598
|
+
customerEmail: localCustomerEmail,
|
|
15599
|
+
demoEmailSuppressed: render.hydration.demoEmailSuppressed
|
|
15239
15600
|
})
|
|
15240
15601
|
});
|
|
15241
15602
|
if (viewState.kind === "verifying") return /* @__PURE__ */ jsx(BookingSurface, {
|
|
@@ -15251,6 +15612,25 @@ const BookingFormClient$1 = ({ siteId: siteIdProp, render }) => {
|
|
|
15251
15612
|
})
|
|
15252
15613
|
})
|
|
15253
15614
|
});
|
|
15615
|
+
if (viewState.kind === "timeout") return /* @__PURE__ */ jsxs(BookingSurface, {
|
|
15616
|
+
id: bookingAnchorId,
|
|
15617
|
+
className: render.display.className,
|
|
15618
|
+
children: [/* @__PURE__ */ jsx(FeedbackMessage, {
|
|
15619
|
+
tone: "info",
|
|
15620
|
+
className: "alert alert-info",
|
|
15621
|
+
role: "status",
|
|
15622
|
+
children: /* @__PURE__ */ jsx("p", {
|
|
15623
|
+
className: "ab-text",
|
|
15624
|
+
children: viewState.message
|
|
15625
|
+
})
|
|
15626
|
+
}), /* @__PURE__ */ jsx(ThemedButton, {
|
|
15627
|
+
type: "button",
|
|
15628
|
+
variant: "primary",
|
|
15629
|
+
size: "md",
|
|
15630
|
+
label: "Check again",
|
|
15631
|
+
onClick: verification.retry
|
|
15632
|
+
})]
|
|
15633
|
+
});
|
|
15254
15634
|
return /* @__PURE__ */ jsxs(BookingSurface, {
|
|
15255
15635
|
id: bookingAnchorId,
|
|
15256
15636
|
className: render.display.className,
|
|
@@ -15311,7 +15691,7 @@ function recoverRegistrationError(action, handlers) {
|
|
|
15311
15691
|
switch (action) {
|
|
15312
15692
|
case "none": return;
|
|
15313
15693
|
case "portal":
|
|
15314
|
-
window.location.assign(
|
|
15694
|
+
window.location.assign(CUSTOMER_PORTAL_PATH);
|
|
15315
15695
|
return;
|
|
15316
15696
|
case "event":
|
|
15317
15697
|
window.location.assign(window.location.pathname);
|
|
@@ -15976,6 +16356,10 @@ const eventRegistrationErrors = {
|
|
|
15976
16356
|
message: "The payment options for this event have changed. Please check the latest options before continuing.",
|
|
15977
16357
|
action: "payment-options"
|
|
15978
16358
|
},
|
|
16359
|
+
verificationFailed: {
|
|
16360
|
+
message: "We couldn’t confirm this request came from a person. Please refresh the page and try again.",
|
|
16361
|
+
action: "none"
|
|
16362
|
+
},
|
|
15979
16363
|
idempotencyConflict: {
|
|
15980
16364
|
message: "You’ve already started booking this event. Please finish in the other tab if it’s still open, or check your booking status before starting again.",
|
|
15981
16365
|
action: "portal"
|
|
@@ -16163,11 +16547,50 @@ function useResolvedWaitlistClaim(deps, credential) {
|
|
|
16163
16547
|
* ```
|
|
16164
16548
|
*/
|
|
16165
16549
|
const paymentVerificationDeps = { useBlockApi };
|
|
16550
|
+
function resolvePaymentPollingTarget(config) {
|
|
16551
|
+
const reference = config.reference;
|
|
16552
|
+
return reference.scope === "occurrence" ? {
|
|
16553
|
+
key: `occurrence:${reference.attendeeId}`,
|
|
16554
|
+
reference
|
|
16555
|
+
} : {
|
|
16556
|
+
key: `wholeSeries:${reference.registrationId}`,
|
|
16557
|
+
reference
|
|
16558
|
+
};
|
|
16559
|
+
}
|
|
16560
|
+
function createPaymentPollingConfig(api, settings) {
|
|
16561
|
+
if (settings === null) return null;
|
|
16562
|
+
const target = resolvePaymentPollingTarget(settings);
|
|
16563
|
+
return {
|
|
16564
|
+
restartKey: target.key,
|
|
16565
|
+
pollFn: () => api.getEventRegistrationStatus(target.reference),
|
|
16566
|
+
isComplete: (result) => result.paymentStatus === "completed" || result.paymentStatus === "not_required",
|
|
16567
|
+
isFailed: (result) => result.paymentStatus === "failed" || result.paymentStatus === "refunded",
|
|
16568
|
+
maxAttempts: settings.maxAttempts,
|
|
16569
|
+
interval: settings.pollInterval
|
|
16570
|
+
};
|
|
16571
|
+
}
|
|
16572
|
+
function getPaymentVerificationError(polling, paymentStatus) {
|
|
16573
|
+
if (polling.status === "timeout") return "Could not verify payment. If you were charged, please contact support.";
|
|
16574
|
+
if (polling.status === "failed" && paymentStatus !== null) return paymentStatus === "refunded" ? "Payment was refunded. Please contact support." : "Payment was declined. Please try again.";
|
|
16575
|
+
return polling.error?.message ?? null;
|
|
16576
|
+
}
|
|
16577
|
+
function mapPaymentVerificationResult(polling) {
|
|
16578
|
+
const paymentStatus = polling.result?.paymentStatus ?? null;
|
|
16579
|
+
return {
|
|
16580
|
+
status: polling.status,
|
|
16581
|
+
paymentStatus,
|
|
16582
|
+
attendeeStatus: polling.result?.attendeeStatus ?? null,
|
|
16583
|
+
waitlistPosition: polling.result?.waitlistPosition ?? null,
|
|
16584
|
+
error: getPaymentVerificationError(polling, paymentStatus),
|
|
16585
|
+
retry: polling.retry
|
|
16586
|
+
};
|
|
16587
|
+
}
|
|
16166
16588
|
/**
|
|
16167
16589
|
* Hook for polling payment status after Stripe redirects.
|
|
16168
16590
|
*
|
|
16169
16591
|
* Pass config to start polling, or null to stop/idle.
|
|
16170
|
-
* The hook handles cleanup on unmount and
|
|
16592
|
+
* The hook handles cleanup on unmount and starts a new cycle when the status
|
|
16593
|
+
* reference changes.
|
|
16171
16594
|
*
|
|
16172
16595
|
* @param config - Configuration for polling, or null to stop
|
|
16173
16596
|
* @returns Verification result with status, data, and retry function
|
|
@@ -16176,30 +16599,7 @@ function usePaymentVerification(config) {
|
|
|
16176
16599
|
return usePaymentVerificationWithDeps(config, paymentVerificationDeps);
|
|
16177
16600
|
}
|
|
16178
16601
|
function usePaymentVerificationWithDeps(config, deps) {
|
|
16179
|
-
|
|
16180
|
-
const polling = usePolling(useMemo(() => {
|
|
16181
|
-
if (!config) return null;
|
|
16182
|
-
return {
|
|
16183
|
-
pollFn: () => api.getEventRegistrationStatus(config.reference),
|
|
16184
|
-
isComplete: (result) => result.paymentStatus === "completed" || result.paymentStatus === "not_required",
|
|
16185
|
-
isFailed: (result) => result.paymentStatus === "failed" || result.paymentStatus === "refunded",
|
|
16186
|
-
maxAttempts: config.maxAttempts,
|
|
16187
|
-
interval: config.pollInterval
|
|
16188
|
-
};
|
|
16189
|
-
}, [api, config]));
|
|
16190
|
-
const paymentStatus = polling.result?.paymentStatus ?? null;
|
|
16191
|
-
let errorMessage = null;
|
|
16192
|
-
if (polling.status === "timeout") errorMessage = "Could not verify payment. If you were charged, please contact support.";
|
|
16193
|
-
else if (polling.status === "failed" && paymentStatus) errorMessage = paymentStatus === "refunded" ? "Payment was refunded. Please contact support." : "Payment was declined. Please try again.";
|
|
16194
|
-
else if (polling.error) errorMessage = polling.error.message;
|
|
16195
|
-
return {
|
|
16196
|
-
status: polling.status,
|
|
16197
|
-
paymentStatus,
|
|
16198
|
-
attendeeStatus: polling.result?.attendeeStatus ?? null,
|
|
16199
|
-
waitlistPosition: polling.result?.waitlistPosition ?? null,
|
|
16200
|
-
error: errorMessage,
|
|
16201
|
-
retry: polling.retry
|
|
16202
|
-
};
|
|
16602
|
+
return mapPaymentVerificationResult(usePolling(createPaymentPollingConfig(deps.useBlockApi(), config)));
|
|
16203
16603
|
}
|
|
16204
16604
|
//#endregion
|
|
16205
16605
|
//#region ../blocks/src/system/runtime/nodes/event-registration/constants.ts
|
|
@@ -16572,20 +16972,9 @@ function registrationErrorPresentation(error) {
|
|
|
16572
16972
|
function wantsMailingListSignup(options) {
|
|
16573
16973
|
return options.mailingListSignup !== null && options.formData.mailingListOptIn === true;
|
|
16574
16974
|
}
|
|
16575
|
-
function createClientCommandId(cryptoSource = {
|
|
16576
|
-
randomUUID: globalThis.crypto.randomUUID?.bind(globalThis.crypto),
|
|
16577
|
-
getRandomValues: (bytes) => globalThis.crypto.getRandomValues(bytes)
|
|
16578
|
-
}) {
|
|
16579
|
-
if (cryptoSource.randomUUID) return cryptoSource.randomUUID();
|
|
16580
|
-
const bytes = cryptoSource.getRandomValues(/* @__PURE__ */ new Uint8Array(16));
|
|
16581
|
-
bytes[6] = (bytes[6] ?? 0) & 15 | 64;
|
|
16582
|
-
bytes[8] = (bytes[8] ?? 0) & 63 | 128;
|
|
16583
|
-
const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0"));
|
|
16584
|
-
return `${hex.slice(0, 4).join("")}-${hex.slice(4, 6).join("")}-${hex.slice(6, 8).join("")}-${hex.slice(8, 10).join("")}-${hex.slice(10).join("")}`;
|
|
16585
|
-
}
|
|
16586
16975
|
const eventRegistrationSubmitDeps = {
|
|
16587
16976
|
savePendingRegistration,
|
|
16588
|
-
createClientCommandId
|
|
16977
|
+
createClientCommandId: generateUuidV4
|
|
16589
16978
|
};
|
|
16590
16979
|
function useEventRegistrationSubmit(options) {
|
|
16591
16980
|
return useEventRegistrationSubmitWithDeps(options, eventRegistrationSubmitDeps);
|
|
@@ -16665,6 +17054,7 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
|
|
|
16665
17054
|
};
|
|
16666
17055
|
}
|
|
16667
17056
|
async function completeRegistrationSubmission(options, deps, prepared, result, submitOptions) {
|
|
17057
|
+
if (result.demoBookingPass) storeDemoBookingPass(options.formData.email, result.demoBookingPass);
|
|
16668
17058
|
switch (result.kind) {
|
|
16669
17059
|
case "paymentStatusRequired":
|
|
16670
17060
|
options.setPaymentStatusRecovery({
|
|
@@ -16687,6 +17077,7 @@ async function completeRegistrationSubmission(options, deps, prepared, result, s
|
|
|
16687
17077
|
status: "waitlist",
|
|
16688
17078
|
title: "Added to waitlist",
|
|
16689
17079
|
message: result.waitlist.message,
|
|
17080
|
+
emailFollowupMessage: result.waitlist.emailFollowupMessage,
|
|
16690
17081
|
mailingListSignupNote: result.mailingListSignupNote
|
|
16691
17082
|
});
|
|
16692
17083
|
break;
|