w-funnel/src/components/admin/builder/dialogs/AddScreenDialog.tsx
2025-10-07 00:44:57 +02:00

155 lines
4.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.

"use client";
import { useState } from "react";
import {
List,
FormInput,
Info,
Calendar,
Ticket,
Loader,
Heart,
Mail
} from "lucide-react";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import type { ScreenDefinition } from "@/lib/funnel/types";
interface AddScreenDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
onAddScreen: (template: ScreenDefinition["template"]) => void;
}
const TEMPLATE_OPTIONS = [
{
template: "list" as const,
title: "Список",
description: "Выбор из списка вариантов (single/multi)",
icon: List,
color: "bg-blue-50 text-blue-600 dark:bg-blue-900/20 dark:text-blue-400",
},
{
template: "form" as const,
title: "Форма",
description: "Ввод текстовых данных в поля",
icon: FormInput,
color: "bg-purple-50 text-purple-600 dark:bg-purple-900/20 dark:text-purple-400",
},
{
template: "email" as const,
title: "Email",
description: "Ввод и валидация email адреса",
icon: Mail,
color: "bg-teal-50 text-teal-600 dark:bg-teal-900/20 dark:text-teal-400",
},
{
template: "info" as const,
title: "Информация",
description: "Отображение информации с кнопкой продолжить",
icon: Info,
color: "bg-gray-50 text-gray-600 dark:bg-gray-800 dark:text-gray-400",
},
{
template: "date" as const,
title: "Дата рождения",
description: "Выбор даты (месяц, день, год) + автоматический расчет возраста",
icon: Calendar,
color: "bg-green-50 text-green-600 dark:bg-green-900/20 dark:text-green-400",
},
{
template: "loaders" as const,
title: "Загрузка",
description: "Анимированные прогресс-бары с этапами обработки",
icon: Loader,
color: "bg-cyan-50 text-cyan-600 dark:bg-cyan-900/20 dark:text-cyan-400",
},
{
template: "soulmate" as const,
title: "Портрет партнера",
description: "Отображение результата анализа и портрета партнера",
icon: Heart,
color: "bg-pink-50 text-pink-600 dark:bg-pink-900/20 dark:text-pink-400",
},
{
template: "coupon" as const,
title: "Купон",
description: "Отображение промокода и предложения",
icon: Ticket,
color: "bg-orange-50 text-orange-600 dark:bg-orange-900/20 dark:text-orange-400",
},
] as const;
export function AddScreenDialog({ open, onOpenChange, onAddScreen }: AddScreenDialogProps) {
const [selectedTemplate, setSelectedTemplate] = useState<ScreenDefinition["template"] | null>(null);
const handleAdd = () => {
if (selectedTemplate) {
onAddScreen(selectedTemplate);
setSelectedTemplate(null);
onOpenChange(false);
}
};
const handleCancel = () => {
setSelectedTemplate(null);
onOpenChange(false);
};
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-2xl">
<DialogHeader>
<DialogTitle>Выберите тип экрана</DialogTitle>
<DialogDescription>
Выберите шаблон для нового экрана воронки
</DialogDescription>
</DialogHeader>
<div className="grid grid-cols-1 gap-3 py-4">
{TEMPLATE_OPTIONS.map((option) => {
const Icon = option.icon;
const isSelected = selectedTemplate === option.template;
return (
<button
key={option.template}
onClick={() => setSelectedTemplate(option.template)}
className={`flex items-start gap-4 rounded-lg border-2 p-4 text-left transition-all hover:bg-muted/50 ${
isSelected
? "border-primary bg-primary/5"
: "border-border hover:border-primary/40"
}`}
>
<div className={`flex h-10 w-10 items-center justify-center rounded-lg ${option.color}`}>
<Icon className="h-5 w-5" />
</div>
<div className="flex-1">
<h3 className="font-medium">{option.title}</h3>
<p className="text-sm text-muted-foreground">{option.description}</p>
</div>
</button>
);
})}
</div>
<div className="flex justify-end gap-2">
<Button variant="outline" onClick={handleCancel}>
Отмена
</Button>
<Button onClick={handleAdd} disabled={!selectedTemplate}>
Добавить экран
</Button>
</div>
</DialogContent>
</Dialog>
);
}