'use client'; import { createElement, useEffect, useMemo, useSyncExternalStore, type ComponentType } from 'react'; import { FunnelProvider, FunnelRuntimeConfigBoundary, PrimaryButton, isPreviewFrameRuntime, runtimePublicConfig, scheduleNextStepImagePreload, usePreviewDefinitionOverrideRevision, usePreviewStepLocalizedContent, } from '@funnelsgrove/runtime'; import { FunnelEditorPanel, FunnelEditorPanelStyles } from './FunnelEditorPanel'; import { runtimeContent } from '@/steps/content/runtime.content'; import { getStepContentLocale } from '@/runtime/step-content-context'; import { funnelManifest } from '@/config/funnel.manifest'; import type { FunnelStepId } from '@/runtime/funnel-runtime'; import { useFunnelFlowController } from '@/runtime/use-funnel-flow-controller'; type FunnelFlowProps = { initialStepId?: FunnelStepId; lockToInitialStep?: boolean; isPreviewFrame?: boolean; isPreviewThumbnail?: boolean; }; function RuntimeConfigLoading() { const content = usePreviewStepLocalizedContent('runtime', runtimeContent, getStepContentLocale({})); return ( ); } function RuntimeConfigStatus() { const content = usePreviewStepLocalizedContent('runtime', runtimeContent, getStepContentLocale({})); return ( {content.unavailableTitle} {content.unavailableDescription} window.location.reload()}> {content.retryLabel} ); } export function FunnelFlow({ initialStepId, lockToInitialStep, isPreviewFrame, isPreviewThumbnail, }: FunnelFlowProps = {}) { const isPreviewRuntime = useMemo(() => { if (typeof isPreviewFrame === 'boolean') { return isPreviewFrame; } return isPreviewFrameRuntime(); }, [isPreviewFrame]); const previewFrameMounted = useSyncExternalStore( () => () => undefined, () => isPreviewRuntime, () => false, ); return ( } errorFallback={} > ); } function FunnelFlowRuntime({ initialStepId, lockToInitialStep, previewFrameMounted, isPreviewThumbnail, }: FunnelFlowProps & { previewFrameMounted: boolean; }) { const previewDefinitionRevision = usePreviewDefinitionOverrideRevision(); const content = usePreviewStepLocalizedContent('runtime', runtimeContent, getStepContentLocale({})); const controller = useFunnelFlowController({ initialStepId, lockToInitialStep, }); useEffect( () => scheduleNextStepImagePreload(funnelManifest, controller.activeStepId), [controller.activeStepId], ); if (!controller.activeStepComponent || !controller.activeStepMeta || !controller.renderedStepMeta) { return null; } const ActiveStep = controller.activeStepComponent as ComponentType>; return ( {controller.renderSuspended ? ( ) : ( {createElement(ActiveStep)} )} {controller.showShellContinue && !controller.renderSuspended ? ( ) : null} { controller.setEditorPanelExpanded((currentValue) => !currentValue); }} /> ); }
{content.unavailableDescription}