From bcd462d6e60871b86008e072f4b914138fc5c328 Mon Sep 17 00:00:00 2001
From: joonhoekim <26rote@gmail.com>
Date: Mon, 11 Aug 2025 09:34:40 +0000
Subject: (김준회) 리치텍스트에디터 (결재템플릿을 위한 공통컴포넌트),
 command-menu 에러 수정, 결재 템플릿 관리, 결재선 관리, ECC RFQ+PR Item 수신시
 비즈니스테이블(ProcurementRFQ) 데이터 적재, WSDL 오류 수정
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../table/duplicate-approval-template-sheet.tsx    | 143 +++++++++++++++++++++
 1 file changed, 143 insertions(+)
 create mode 100644 lib/approval-template/table/duplicate-approval-template-sheet.tsx

(limited to 'lib/approval-template/table/duplicate-approval-template-sheet.tsx')

diff --git a/lib/approval-template/table/duplicate-approval-template-sheet.tsx b/lib/approval-template/table/duplicate-approval-template-sheet.tsx
new file mode 100644
index 00000000..e49000ff
--- /dev/null
+++ b/lib/approval-template/table/duplicate-approval-template-sheet.tsx
@@ -0,0 +1,143 @@
+"use client"
+
+import * as React from "react"
+import { zodResolver } from "@hookform/resolvers/zod"
+import { Loader } from "lucide-react"
+import { useForm } from "react-hook-form"
+import { toast } from "sonner"
+import { z } from "zod"
+import { useRouter } from "next/navigation"
+
+import { Button } from "@/components/ui/button"
+import {
+  Form,
+  FormControl,
+  FormField,
+  FormItem,
+  FormLabel,
+  FormMessage,
+} from "@/components/ui/form"
+import { Input } from "@/components/ui/input"
+import {
+  Sheet,
+  SheetClose,
+  SheetContent,
+  SheetDescription,
+  SheetFooter,
+  SheetHeader,
+  SheetTitle,
+} from "@/components/ui/sheet"
+
+import { type ApprovalTemplate } from "@/lib/approval-template/service"
+import { duplicateApprovalTemplate } from "../service"
+import { useSession } from "next-auth/react"
+
+const duplicateSchema = z.object({
+  name: z.string().min(1, "템플릿 이름은 필수입니다").max(100, "100자 이내여야 합니다"),
+})
+
+type DuplicateSchema = z.infer<typeof duplicateSchema>
+
+interface DuplicateApprovalTemplateSheetProps extends React.ComponentPropsWithRef<typeof Sheet> {
+  template: ApprovalTemplate | null
+}
+
+export function DuplicateApprovalTemplateSheet({ template, ...props }: DuplicateApprovalTemplateSheetProps) {
+  const [isPending, startTransition] = React.useTransition()
+  const router = useRouter()
+  const { data: session } = useSession()
+
+  const form = useForm<DuplicateSchema>({
+    resolver: zodResolver(duplicateSchema),
+    defaultValues: { name: "" },
+  })
+
+  React.useEffect(() => {
+    if (template) {
+      form.reset({ name: `${template.name} (복사본)` })
+    }
+  }, [template, form])
+
+  function onSubmit(values: DuplicateSchema) {
+    startTransition(async () => {
+      if (!template) return
+      if (!session?.user?.id) {
+        toast.error("로그인이 필요합니다")
+        return
+      }
+
+      const { success, error, data } = await duplicateApprovalTemplate(
+        template.id,
+        values.name,
+        Number(session.user.id),
+      )
+
+      if (!success || error) {
+        toast.error(error ?? "복제에 실패했습니다")
+        return
+      }
+
+      toast.success("템플릿이 복제되었습니다")
+      props.onOpenChange?.(false)
+
+      // 상세 페이지로 이동 (id 기반)
+      if (data?.id) {
+        router.push(`/evcp/approval/template/${data.id}`)
+      } else {
+        window.location.reload()
+      }
+    })
+  }
+
+  return (
+    <Sheet {...props}>
+      <SheetContent className="flex flex-col gap-6 sm:max-w-md">
+        <SheetHeader className="text-left">
+          <SheetTitle>템플릿 복제</SheetTitle>
+          <SheetDescription>기존 템플릿을 복사하여 새로운 템플릿을 생성합니다.</SheetDescription>
+        </SheetHeader>
+
+        {template && (
+          <div className="rounded-lg bg-muted p-3">
+            <h4 className="text-sm font-medium mb-2">원본 템플릿</h4>
+            <div className="space-y-1 text-xs text-muted-foreground">
+              <div>이름: {template.name}</div>
+              <div>ID: <code className="bg-background px-1 rounded">{template.id}</code></div>
+              <div>카테고리: {template.category ?? "-"}</div>
+            </div>
+          </div>
+        )}
+
+        <Form {...form}>
+          <form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-col gap-4">
+            <FormField
+              control={form.control}
+              name="name"
+              render={({ field }) => (
+                <FormItem>
+                  <FormLabel>새 템플릿 이름</FormLabel>
+                  <FormControl>
+                    <Input placeholder="복제된 템플릿 이름" {...field} />
+                  </FormControl>
+                  <FormMessage />
+                </FormItem>
+              )}
+            />
+
+            <SheetFooter className="gap-2 pt-2 sm:space-x-0">
+              <SheetClose asChild>
+                <Button type="button" variant="outline">
+                  취소
+                </Button>
+              </SheetClose>
+              <Button disabled={isPending}>
+                {isPending && <Loader className="mr-2 size-4 animate-spin" aria-hidden="true" />}
+                복제하기
+              </Button>
+            </SheetFooter>
+          </form>
+        </Form>
+      </SheetContent>
+    </Sheet>
+  )
+}
-- 
cgit v1.2.3

