"use client"; import type { JSX } from "react"; import { ListTemplate, InfoTemplate, DateTemplate, CouponTemplate, FormTemplate, EmailTemplate, LoadersTemplate, SoulmatePortraitTemplate, TrialPaymentTemplate, } from "@/components/funnel/templates"; import type { ListScreenDefinition, DateScreenDefinition, FormScreenDefinition, CouponScreenDefinition, InfoScreenDefinition, EmailScreenDefinition, LoadersScreenDefinition, SoulmatePortraitScreenDefinition, TrialPaymentScreenDefinition, ScreenDefinition, DefaultTexts, FunnelDefinition, FunnelAnswers, } from "@/lib/funnel/types"; export interface ScreenRenderProps { funnel: FunnelDefinition; screen: ScreenDefinition; selectedOptionIds: string[]; onSelectionChange: (ids: string[]) => void; onContinue: () => void; canGoBack: boolean; onBack: () => void; screenProgress: { current: number; total: number }; defaultTexts?: DefaultTexts; answers: FunnelAnswers; } export type TemplateRenderer = (props: ScreenRenderProps) => JSX.Element; const TEMPLATE_REGISTRY: Record< ScreenDefinition["template"], TemplateRenderer > = { info: ({ screen, onContinue, canGoBack, onBack, screenProgress, defaultTexts, answers, }) => { const infoScreen = screen as InfoScreenDefinition; return ( ); }, date: ({ screen, selectedOptionIds, onSelectionChange, onContinue, canGoBack, onBack, screenProgress, defaultTexts, }) => { const dateScreen = screen as DateScreenDefinition; // For date screens, we store date components as array: [month, day, year] const currentDateArray = selectedOptionIds; const selectedDate = { month: currentDateArray[0] || "", day: currentDateArray[1] || "", year: currentDateArray[2] || "", }; const handleDateChange = (date: { month?: string; day?: string; year?: string; }) => { const dateArray = [date.month || "", date.day || "", date.year || ""]; onSelectionChange(dateArray); }; return ( ); }, form: ({ screen, selectedOptionIds, onSelectionChange, onContinue, canGoBack, onBack, screenProgress, defaultTexts, }) => { const formScreen = screen as FormScreenDefinition; // For form screens, we store form data as JSON string in the first element const formDataJson = selectedOptionIds[0] || "{}"; let formData: Record = {}; try { formData = JSON.parse(formDataJson); } catch { formData = {}; } const handleFormDataChange = (data: Record) => { const dataJson = JSON.stringify(data); onSelectionChange([dataJson]); }; return ( ); }, coupon: ({ screen, onContinue, canGoBack, onBack, screenProgress, defaultTexts, }) => { const couponScreen = screen as CouponScreenDefinition; return ( ); }, list: ({ screen, selectedOptionIds, onSelectionChange, onContinue, canGoBack, onBack, screenProgress, defaultTexts, }) => { const listScreen = screen as ListScreenDefinition; const isSelectionEmpty = selectedOptionIds.length === 0; // Используем только общую кнопку экрана const bottomActionButton = listScreen.bottomActionButton; const isButtonDisabled = bottomActionButton?.show === false; // Простая логика: кнопка есть если не отключена (show: false) const hasActionButton = !isButtonDisabled; // Правильная логика приоритетов для текста кнопки: // 1. bottomActionButton.text (настройка экрана) // 2. defaultTexts.nextButton (глобальная настройка воронки) // 3. "Next" (хардкод fallback) const buttonText = bottomActionButton?.text || defaultTexts?.nextButton || "Next"; const actionDisabled = hasActionButton && isSelectionEmpty; return ( ); }, email: ({ screen, selectedOptionIds, onSelectionChange, onContinue, canGoBack, onBack, screenProgress, defaultTexts, funnel, }) => { const emailScreen = screen as EmailScreenDefinition; // For email screens, we store email as single string in first element const selectedEmail = selectedOptionIds[0] || ""; const handleEmailChange = (email: string) => { onSelectionChange([email]); }; return ( ); }, loaders: ({ screen, onContinue, canGoBack, onBack, screenProgress, defaultTexts, }) => { const loadersScreen = screen as LoadersScreenDefinition; return ( ); }, soulmate: ({ screen, onContinue, canGoBack, onBack, screenProgress, defaultTexts, }) => { const soulmateScreen = screen as SoulmatePortraitScreenDefinition; return ( ); }, trialPayment: ({ screen, onContinue, canGoBack, onBack, screenProgress, defaultTexts, funnel, }) => { const trialPaymentScreen = screen as TrialPaymentScreenDefinition; return ( ); }, }; export function renderScreen(props: ScreenRenderProps): JSX.Element { const renderer = TEMPLATE_REGISTRY[props.screen.template]; if (!renderer) { throw new Error(`Unsupported template: ${props.screen.template}`); } return renderer(props); } export function getTemplateRenderer( screen: ScreenDefinition ): TemplateRenderer { const renderer = TEMPLATE_REGISTRY[screen.template]; if (!renderer) { throw new Error(`Unsupported template: ${screen.template}`); } return renderer; }