'use client'; /* IMPORT */ import { Button } from '@/components/ui/button'; import { duplicateTemplate, getCurrentUserId } from '../service'; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, FormDescription, } from '@/components/ui/form'; import { getCategoryDisplayName } from '../validations'; import { Input } from '@/components/ui/input'; import { Loader } from 'lucide-react'; import { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, } from '@/components/ui/sheet'; import { toast } from 'sonner'; import { type ComponentPropsWithRef, useEffect, useTransition } from 'react'; import { type TemplateListView } from '@/db/schema'; import { useForm } from 'react-hook-form'; import { useRouter } from 'next/navigation'; import { z } from 'zod'; import { zodResolver } from '@hookform/resolvers/zod'; // ---------------------------------------------------------------------------------------------------- /* TYPES */ const duplicateTemplateSchema = z.object({ name: z.string() .min(1, '템플릿 이름은 필수입니다.') .max(100, '템플릿 이름은 100자 이하여야 합니다.'), slug: z.string() .min(1, 'Slug는 필수입니다.') .max(50, 'Slug는 50자 이하여야 합니다.') .regex(/^[a-z0-9-]+$/, 'Slug는 소문자, 숫자, 하이픈만 사용 가능합니다.'), }); type DuplicateTemplateSchema = z.infer; interface DuplicateTemplateSheetProps extends ComponentPropsWithRef { template: TemplateListView | null; } // ---------------------------------------------------------------------------------------------------- /* DUPLICATE EMAIL TEMPLATE SHEET COMPONENT */ function DuplicateTemplateSheet({ template, ...props }: DuplicateTemplateSheetProps) { const [isDuplicatePending, startDuplicateTransition] = useTransition(); const form = useForm({ resolver: zodResolver(duplicateTemplateSchema), defaultValues: { name: '', slug: '', }, }) const router = useRouter(); const watchedName = form.watch('name'); useEffect(() => { if (template) { const copyName = `${template.name} (복사본)`; const copySlug = `${template.slug}-copy-${Date.now()}`; form.reset({ name: copyName, slug: copySlug, }); } }, [template, form]); useEffect(() => { if (watchedName && !form.formState.dirtyFields.slug) { const autoSlug = watchedName .toLowerCase() .replace(/[^a-z0-9\s-]/g, '') .replace(/\s+/g, '-') .replace(/-+/g, '-') .trim() .slice(0, 50); form.setValue('slug', autoSlug, { shouldValidate: false }); } }, [watchedName, form]); function onSubmit(input: DuplicateTemplateSchema) { startDuplicateTransition(async () => { if (!template) { return; } const currentUserId = await getCurrentUserId(); const { error, data } = await duplicateTemplate( template.id, input.name, input.slug, currentUserId, ); if (error) { toast.error(error); return; } form.reset(); props.onOpenChange?.(false); toast.success('템플릿이 복제되었습니다.'); if (data?.slug) { router.push(`/evcp/email-template/${data.slug}`); } else { window.location.reload(); } }); } return ( 템플릿 복제 기존 템플릿을 복사하여 새로운 템플릿을 생성합니다. 모든 내용과 변수가 복제됩니다. {template && (

원본 템플릿

이름: {template.name}
Slug: {template.slug}
카테고리: {getCategoryDisplayName(template.category)}
변수: {template.variableCount}개
)}
( 새 템플릿 이름 )} /> ( 새 Slug 고유한 식별자여야 합니다. 소문자, 숫자, 하이픈만 사용 가능합니다. )} />
); } // ---------------------------------------------------------------------------------------------------- /* EXPORT */ export default DuplicateTemplateSheet;