w-funnel/src/lib/admin/builder/templates.ts
2025-09-25 18:04:52 +02:00

107 lines
2.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { BuilderScreen } from "@/lib/admin/builder/types";
import type { ListOptionDefinition } from "@/lib/funnel/types";
export interface CreateTemplateScreenOptions {
templateId?: string;
screenId: string;
position: { x: number; y: number };
}
export interface BuilderTemplateDefinition {
id: string;
label: string;
description?: string;
create: (options: CreateTemplateScreenOptions, overrides?: Partial<BuilderScreen>) => BuilderScreen;
}
export const DEFAULT_TEMPLATE_ID = "list";
function cloneOptions(options: ListOptionDefinition[]): ListOptionDefinition[] {
return options.map((option) => ({ ...option }));
}
const LIST_TEMPLATE: BuilderTemplateDefinition = {
id: "list",
label: "Вопрос с вариантами",
create: ({ screenId, position }, overrides) => {
const base: BuilderScreen = {
id: screenId,
template: "list",
header: {
progress: {
current: 1,
total: 1,
label: "1 of 1",
},
},
title: {
text: "Новый экран",
font: "manrope",
weight: "bold",
},
subtitle: {
text: "Опишите вопрос справа",
color: "muted",
font: "inter",
},
list: {
selectionType: "single",
options: cloneOptions([
{ id: "option-1", label: "Вариант 1" },
{ id: "option-2", label: "Вариант 2" },
]),
},
navigation: {
defaultNextScreenId: undefined,
rules: [],
},
position,
};
if (!overrides) {
return base;
}
return {
...base,
...overrides,
list: overrides.list
? {
...base.list,
...overrides.list,
options: overrides.list.options ?? base.list.options,
}
: base.list,
navigation: overrides.navigation
? {
defaultNextScreenId:
overrides.navigation.defaultNextScreenId ?? base.navigation?.defaultNextScreenId,
rules: overrides.navigation.rules ?? base.navigation?.rules ?? [],
}
: base.navigation,
};
},
};
const BUILDER_TEMPLATES: BuilderTemplateDefinition[] = [LIST_TEMPLATE];
export function getTemplateDefinition(templateId: string): BuilderTemplateDefinition {
return BUILDER_TEMPLATES.find((template) => template.id === templateId) ?? LIST_TEMPLATE;
}
export function createTemplateScreen(
options: CreateTemplateScreenOptions,
overrides?: Partial<BuilderScreen>
): BuilderScreen {
const definition = getTemplateDefinition(options.templateId ?? DEFAULT_TEMPLATE_ID);
return definition.create(options, overrides);
}
export function getTemplateOptions(): { id: string; label: string; description?: string }[] {
return BUILDER_TEMPLATES.map((template) => ({
id: template.id,
label: template.label,
description: template.description,
}));
}