/** * Форма создания/редактирования персоны для использования с ModalContainer * Позволяет пользователю создавать новых персон или редактировать существующих */ import { Tag as TagIcon, Upload, User, X } from "lucide-react" import { useEffect, useRef, useState } from "react" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Textarea } from "@/components/ui/textarea" import { useModal } from "@/features/modals/services" import type { PersonProfile } from "../types/person" export function PersonFormModal() { const { modalData, closeModal } = useModal() const person = modalData?.person as PersonProfile | undefined const onSave = modalData?.onSave as ((personData: Partial) => Promise) | undefined const isLoading = modalData?.isLoading as boolean | undefined const [formData, setFormData] = useState({ name: "", notes: "", tags: [] as string[], thumbnailUrl: "", }) const [newTag, setNewTag] = useState("") const [thumbnailPreview, setThumbnailPreview] = useState(null) const fileInputRef = useRef(null) // Инициализация значений при открытии модального окна useEffect(() => { if (person) { setFormData({ name: person.name || "", notes: person.notes || "", tags: person.tags || [], thumbnailUrl: person.thumbnails?.[0]?.imageUrl || "", }) setThumbnailPreview(person.thumbnails?.[0]?.imageUrl || null) } }, [person]) const handleInputChange = (field: string, value: string) => { setFormData((prev) => ({ ...prev, [field]: value, })) } const handleAddTag = () => { if (newTag.trim() && !formData.tags.includes(newTag.trim())) { setFormData((prev) => ({ ...prev, tags: [...prev.tags, newTag.trim()], })) setNewTag("") } } const handleRemoveTag = (tagToRemove: string) => { setFormData((prev) => ({ ...prev, tags: prev.tags.filter((tag) => tag !== tagToRemove), })) } const handleFileSelect = (event: React.ChangeEvent) => { const file = event.target.files?.[0] if (file) { const reader = new FileReader() reader.onloadend = () => { setThumbnailPreview(reader.result as string) // В реальном приложении здесь должна быть логика сохранения файла setFormData((prev) => ({ ...prev, thumbnailUrl: reader.result as string, })) } reader.readAsDataURL(file) } } const handleSave = async () => { if (!formData.name.trim()) { return } const personData: Partial = { id: person?.id, name: formData.name, notes: formData.notes, tags: formData.tags, // В реальном приложении здесь должна быть логика создания thumbnails thumbnails: formData.thumbnailUrl ? [ { id: crypto.randomUUID(), imageUrl: formData.thumbnailUrl, width: 150, height: 150, sourceClipId: "", sourceTimestamp: { seconds: 0 }, quality: 1, isPrimary: true, isGenerated: false, }, ] : undefined, } await onSave?.(personData) closeModal() } return (
{/* Аватар */}
{thumbnailPreview ? ( Превью ) : (
)}
{/* Форма */}
handleInputChange("name", e.target.value)} placeholder="Введите имя персоны" required />