"use client" import * as React from "react" import { useForm } from "react-hook-form" import { zodResolver } from "@hookform/resolvers/zod" import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from "@/components/ui/dialog" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Textarea } from "@/components/ui/textarea" import { Badge } from "@/components/ui/badge" import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, FormDescription, } from "@/components/ui/form" import { Loader, Copy, Info } from "lucide-react" import { toast } from "sonner" import { createGtcClauseSchema, type CreateGtcClauseSchema } from "@/lib/gtc-contract/gtc-clauses/validations" import { createGtcClause } from "@/lib/gtc-contract/gtc-clauses/service" import { type GtcClauseTreeView } from "@/db/schema/gtc" import { useSession } from "next-auth/react" interface DuplicateGtcClauseDialogProps extends React.ComponentPropsWithRef { sourceClause: GtcClauseTreeView | null onSuccess?: () => void } export function DuplicateGtcClauseDialog({ sourceClause, onSuccess, ...props }: DuplicateGtcClauseDialogProps) { const [isCreatePending, startCreateTransition] = React.useTransition() const { data: session } = useSession() const currentUserId = React.useMemo(() => { return session?.user?.id ? Number(session.user.id) : null }, [session]) const form = useForm({ resolver: zodResolver(createGtcClauseSchema), defaultValues: { documentId: 0, parentId: null, itemNumber: "", category: "", subtitle: "", content: "", sortOrder: 0, // numberVariableName: "", // subtitleVariableName: "", // contentVariableName: "", editReason: "", }, }) // sourceClause가 변경될 때 폼 데이터 설정 React.useEffect(() => { if (sourceClause) { // 새로운 채번 생성 (원본에 "_copy" 추가) const newItemNumber = `${sourceClause.itemNumber}_copy` form.reset({ documentId: sourceClause.documentId, parentId: sourceClause.parentId, itemNumber: newItemNumber, category: sourceClause.category || "", subtitle: `${sourceClause.subtitle} (복제)`, content: sourceClause.content || "", sortOrder:parseFloat(sourceClause.sortOrder) + 0.1, // 원본 바로 다음에 위치 // numberVariableName: "", // subtitleVariableName: "", // contentVariableName: "", editReason: `조항 복제 (원본: ${sourceClause.itemNumber})`, }) // 자동 변수명 생성 // generateVariableNames(newItemNumber, sourceClause.parentId) } }, [sourceClause, form]) // const generateVariableNames = (itemNumber: string, parentId: number | null) => { // if (!sourceClause) return // let fullPath = itemNumber // if (parentId && sourceClause.fullPath) { // const parentPath = sourceClause.fullPath.split('.').slice(0, -1).join('.') // if (parentPath) { // fullPath = `${parentPath}.${itemNumber}` // } // } // const prefix = "CLAUSE_" + fullPath.replace(/\./g, "_") // form.setValue("numberVariableName", `${prefix}_NUMBER`) // form.setValue("subtitleVariableName", `${prefix}_SUBTITLE`) // form.setValue("contentVariableName", `${prefix}_CONTENT`) // } async function onSubmit(data: CreateGtcClauseSchema) { startCreateTransition(async () => { if (!currentUserId) { toast.error("로그인이 필요합니다") return } try { const result = await createGtcClause({ ...data, createdById: currentUserId }) if (result.error) { toast.error(`에러: ${result.error}`) return } form.reset() props.onOpenChange?.(false) toast.success("조항이 복제되었습니다.") onSuccess?.() } catch (error) { toast.error("조항 복제 중 오류가 발생했습니다.") } }) } function handleDialogOpenChange(nextOpen: boolean) { if (!nextOpen) { form.reset() } props.onOpenChange?.(nextOpen) } if (!sourceClause) { return null } return ( 조항 복제 기존 조항을 복제하여 새로운 조항을 생성합니다. {/* 원본 조항 정보 */}
복제할 원본 조항
{sourceClause.itemNumber} {sourceClause.subtitle}
{sourceClause.category && (
분류: {sourceClause.category}
)} {sourceClause.content && (
내용: {sourceClause.content.substring(0, 100)} {sourceClause.content.length > 100 && "..."}
)}
{/* 새 채번 */} ( 새 채번 * 복제된 조항의 새로운 번호입니다. 원본과 다른 번호를 사용해주세요. )} /> {/* 분류 */} ( 분류 )} /> {/* 소제목 */} ( 소제목 * 복제 시 "(복제)" 접미사가 자동으로 추가됩니다. )} /> {/* 상세항목 */} ( 상세항목