diff options
| author | 0-Zz-ang <s1998319@gmail.com> | 2025-08-22 13:47:37 +0900 |
|---|---|---|
| committer | 0-Zz-ang <s1998319@gmail.com> | 2025-08-22 13:47:37 +0900 |
| commit | fefca6304eefea94f41057f9f934b0e19ceb54bb (patch) | |
| tree | f4914faa83e242a68d27feac58ebf0c527302cd2 /lib/compliance/table/compliance-template-create-dialog.tsx | |
| parent | dbdae213e39b82ff8ee565df0774bd2f72f06140 (diff) | |
(박서영)Compliance 설문/응답 리스트 생성
Diffstat (limited to 'lib/compliance/table/compliance-template-create-dialog.tsx')
| -rw-r--r-- | lib/compliance/table/compliance-template-create-dialog.tsx | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/lib/compliance/table/compliance-template-create-dialog.tsx b/lib/compliance/table/compliance-template-create-dialog.tsx new file mode 100644 index 00000000..4d16b0a1 --- /dev/null +++ b/lib/compliance/table/compliance-template-create-dialog.tsx @@ -0,0 +1,191 @@ +"use client" + +import * as React from "react" +import { useForm } from "react-hook-form" +import { zodResolver } from "@hookform/resolvers/zod" +import * as z from "zod" + +import { Button } from "@/components/ui/button" +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog" +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form" +import { Input } from "@/components/ui/input" +import { Textarea } from "@/components/ui/textarea" +import { Switch } from "@/components/ui/switch" +import { Plus, Loader2 } from "lucide-react" +import { toast } from "sonner" +import { createComplianceSurveyTemplate } from "../services" + +const createTemplateSchema = z.object({ + name: z.string().min(1, "템플릿명을 입력해주세요.").max(100, "템플릿명은 100자 이하여야 합니다."), + description: z.string().min(1, "설명을 입력해주세요.").max(500, "설명은 500자 이하여야 합니다."), + version: z.string().min(1, "버전을 입력해주세요.").max(20, "버전은 20자 이하여야 합니다."), + isActive: z.boolean().default(true), +}) + +type CreateTemplateFormValues = z.infer<typeof createTemplateSchema> + +export function ComplianceTemplateCreateDialog() { + const [open, setOpen] = React.useState(false) + const [isSubmitting, setIsSubmitting] = React.useState(false) + + // react-hook-form 세팅 + const form = useForm<CreateTemplateFormValues>({ + resolver: zodResolver(createTemplateSchema), + defaultValues: { + name: "", + description: "", + version: "1.0", + isActive: true, + }, + mode: "onChange", + }) + + async function onSubmit(data: CreateTemplateFormValues) { + setIsSubmitting(true) + try { + const result = await createComplianceSurveyTemplate(data) + if (result) { + toast.success("새로운 설문조사 템플릿이 생성되었습니다.") + form.reset() + setOpen(false) + // 페이지 새로고침으로 데이터 업데이트 + window.location.reload() + } + } catch (error) { + console.error("템플릿 생성 오류:", error) + toast.error("템플릿 생성에 실패했습니다.") + } finally { + setIsSubmitting(false) + } + } + + function handleDialogOpenChange(nextOpen: boolean) { + if (!nextOpen) { + form.reset() + } + setOpen(nextOpen) + } + + return ( + <Dialog open={open} onOpenChange={handleDialogOpenChange}> + <DialogTrigger asChild> + <Button variant="outline" size="sm"> + <Plus className="mr-2 h-4 w-4" /> + 템플릿 추가 + </Button> + </DialogTrigger> + <DialogContent className="sm:max-w-[500px]"> + <DialogHeader> + <DialogTitle>새 설문조사 템플릿 생성</DialogTitle> + <DialogDescription> + 새로운 준법 설문조사 템플릿을 생성합니다. 템플릿 생성 후 질문을 추가할 수 있습니다. + </DialogDescription> + </DialogHeader> + <Form {...form}> + <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4"> + <FormField + control={form.control} + name="name" + render={({ field }) => ( + <FormItem> + <FormLabel>템플릿명 *</FormLabel> + <FormControl> + <Input + placeholder="예: ESG 준법 설문조사" + {...field} + /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + + <FormField + control={form.control} + name="description" + render={({ field }) => ( + <FormItem> + <FormLabel>설명 *</FormLabel> + <FormControl> + <Textarea + placeholder="템플릿의 목적과 대상에 대한 설명을 입력하세요." + className="min-h-[80px]" + {...field} + /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + + <FormField + control={form.control} + name="version" + render={({ field }) => ( + <FormItem> + <FormLabel>버전 *</FormLabel> + <FormControl> + <Input + placeholder="예: 1.0" + {...field} + /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + + <FormField + control={form.control} + name="isActive" + render={({ field }) => ( + <FormItem className="flex items-center space-x-2"> + <FormControl> + <Switch + checked={field.value} + onCheckedChange={field.onChange} + /> + </FormControl> + <FormLabel>활성 상태</FormLabel> + </FormItem> + )} + /> + + <DialogFooter> + <Button + type="button" + variant="outline" + onClick={() => setOpen(false)} + disabled={isSubmitting} + > + 취소 + </Button> + <Button + type="submit" + disabled={isSubmitting} + > + {isSubmitting && <Loader2 className="mr-2 h-4 w-4 animate-spin" />} + {isSubmitting ? "생성 중..." : "템플릿 생성"} + </Button> + </DialogFooter> + </form> + </Form> + </DialogContent> + </Dialog> + ) +} |
