import type { TypographyProps } from "@/components/ui/Typography/Typography"; import type { MainButtonProps } from "@/components/ui/MainButton/MainButton"; import { hasTextMarkup } from "@/lib/text-markup"; import type { HeaderDefinition, HeaderProgressDefinition, ListOptionDefinition, SelectionType, TypographyVariant, BottomActionButtonDefinition, ScreenDefinition, } from "./types"; import type { LayoutQuestionProps } from "@/components/layout/LayoutQuestion/LayoutQuestion"; import type { ActionButtonProps } from "@/components/ui/ActionButton/ActionButton"; import type { BottomActionButtonProps } from "@/components/widgets/BottomActionButton/BottomActionButton"; type TypographyAs = "span" | "p" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "div"; interface TypographyDefaults { font?: TypographyVariant["font"]; weight?: TypographyVariant["weight"]; size?: TypographyVariant["size"]; align?: TypographyVariant["align"]; color?: TypographyVariant["color"]; } interface BuildTypographyOptions { as: T; defaults?: TypographyDefaults; } export function buildTypographyProps( variant: TypographyVariant | undefined, options: BuildTypographyOptions ): TypographyProps | undefined { if (!variant) { return undefined; } const { as, defaults } = options; return { as, children: variant.text, font: variant.font ?? defaults?.font, weight: variant.weight ?? defaults?.weight, size: variant.size ?? defaults?.size, align: variant.align ?? defaults?.align, color: variant.color ?? defaults?.color, className: variant.className, enableMarkup: hasTextMarkup(variant.text || ''), // 🎨 ΠΠ’Π’ΠžΠœΠΠ’Π˜Π§Π•Π‘ΠšΠ˜ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΡƒ Ссли ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½Π° } as TypographyProps; } export function buildHeaderProgress(progress?: HeaderProgressDefinition) { if (!progress) { return undefined; } const { current, total, value, label, className } = progress; const computedValue = value ?? (current !== undefined && total ? (current / total) * 100 : undefined); return { value: computedValue, label, className, }; } export function buildAutoHeaderProgress( currentScreenId: string, totalScreens: number, currentPosition: number, explicitProgress?: HeaderProgressDefinition ) { // If explicit progress is provided, use it if (explicitProgress) { return buildHeaderProgress(explicitProgress); } // Otherwise, auto-calculate const autoProgress: HeaderProgressDefinition = { current: currentPosition, total: totalScreens, label: `${currentPosition} of ${totalScreens}`, }; return buildHeaderProgress(autoProgress); } export function mapListOptionsToButtons( options: ListOptionDefinition[], selectionType: SelectionType ): MainButtonProps[] { return options.map((option) => ({ id: option.id, children: option.label, emoji: option.emoji, isCheckbox: selectionType === "multi", disabled: option.disabled, })); } export function shouldShowBackButton(header?: HeaderDefinition, canGoBack?: boolean) { if (header?.showBackButton === false) { return false; } return Boolean(canGoBack); } export function shouldShowHeader(header?: HeaderDefinition) { return header?.show !== false; } interface BuildActionButtonOptions { defaultText?: string; disabled?: boolean; onClick: () => void; } export function buildActionButtonProps( options: BuildActionButtonOptions, buttonDef?: BottomActionButtonDefinition ): ActionButtonProps { const { defaultText = "Continue", disabled = false, onClick } = options; return { children: buttonDef?.text ?? defaultText, cornerRadius: buttonDef?.cornerRadius, disabled: disabled, // disabled управляСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ экрана, Π½Π΅ Π°Π΄ΠΌΠΈΠ½ΠΊΠΎΠΉ onClick: disabled ? undefined : onClick, }; } export function buildBottomActionButtonProps( options: BuildActionButtonOptions, buttonDef?: BottomActionButtonDefinition ): BottomActionButtonProps | undefined { // Если ΠΊΠ½ΠΎΠΏΠΊΠ° ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½Π° (show: false) - Π½Π΅ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Π½ΠΈΡ‡Π΅Π³ΠΎ if (buttonDef?.show === false) { return undefined; } // Π’ ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… случаях ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΊΠ½ΠΎΠΏΠΊΡƒ с Π³Ρ€Π°Π΄ΠΈΠ΅Π½Ρ‚ΠΎΠΌ const actionButtonProps = buildActionButtonProps(options, buttonDef); return { actionButtonProps, showGradientBlur: true, // Π“Ρ€Π°Π΄ΠΈΠ΅Π½Ρ‚ всСгда Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ (ΠΊΠ°ΠΊ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π»ΠΎΡΡŒ) }; } interface BuildLayoutQuestionOptions { screen: ScreenDefinition; titleDefaults?: TypographyDefaults; subtitleDefaults?: TypographyDefaults; canGoBack: boolean; onBack: () => void; screenProgress?: { current: number; total: number }; } export function buildLayoutQuestionProps( options: BuildLayoutQuestionOptions ): Omit { const { screen, titleDefaults = { font: "manrope", weight: "bold", align: "left" }, subtitleDefaults = { font: "inter", weight: "medium", color: "muted", align: "left" }, canGoBack, onBack, screenProgress } = options; const showBackButton = shouldShowBackButton(screen.header, canGoBack); const showHeader = shouldShowHeader(screen.header); return { headerProps: showHeader ? { progressProps: screenProgress ? buildHeaderProgress({ current: screenProgress.current, total: screenProgress.total, label: `${screenProgress.current} of ${screenProgress.total}` }) : buildHeaderProgress(screen.header?.progress), onBack: showBackButton ? onBack : undefined, showBackButton, } : undefined, title: buildTypographyProps(screen.title, { as: "h2", defaults: titleDefaults, }) ?? { as: "h2", children: screen.title.text, }, subtitle: 'subtitle' in screen ? buildTypographyProps(screen.subtitle, { as: "p", defaults: subtitleDefaults, }) : undefined, }; } // ΠžΡ‚Π΄Π΅Π»ΡŒΠ½Π°Ρ функция для получСния bottomActionButtonProps export function buildTemplateBottomActionButtonProps(options: { screen: ScreenDefinition; actionButtonOptions: BuildActionButtonOptions; }) { const { screen, actionButtonOptions } = options; // НаличиС actionButtonOptions β€” явный сигнал ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΊΠ½ΠΎΠΏΠΊΡƒ. // ΠŸΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ΠΊΠ½ΠΎΠΏΠΊΡƒ нСзависимо ΠΎΡ‚ screen.bottomActionButton.show return buildBottomActionButtonProps( actionButtonOptions, 'bottomActionButton' in screen ? (screen.bottomActionButton?.show === false ? { ...screen.bottomActionButton, show: true } : screen.bottomActionButton) : undefined ); }