diff options
Diffstat (limited to 'lib/compliance/table/compliance-template-create-dialog.tsx')
| -rw-r--r-- | lib/compliance/table/compliance-template-create-dialog.tsx | 103 |
1 files changed, 84 insertions, 19 deletions
diff --git a/lib/compliance/table/compliance-template-create-dialog.tsx b/lib/compliance/table/compliance-template-create-dialog.tsx index 5b7e1092..db4ede4e 100644 --- a/lib/compliance/table/compliance-template-create-dialog.tsx +++ b/lib/compliance/table/compliance-template-create-dialog.tsx @@ -29,19 +29,33 @@ import { Switch } from "@/components/ui/switch" import { Plus, Loader2 } from "lucide-react" import { toast } from "sonner" import { createComplianceSurveyTemplate } from "../services" +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select" +import { complianceSurveyTemplates } from "@/db/schema/compliance" 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() { +interface ComplianceTemplateCreateDialogProps { + templates?: typeof complianceSurveyTemplates.$inferSelect[] +} + +export function ComplianceTemplateCreateDialog({ + templates = [], +}: ComplianceTemplateCreateDialogProps) { const [open, setOpen] = React.useState(false) const [isSubmitting, setIsSubmitting] = React.useState(false) + const [selectedTemplateId, setSelectedTemplateId] = React.useState<string>("none") // react-hook-form 세팅 const form = useForm<CreateTemplateFormValues>({ @@ -49,19 +63,54 @@ export function ComplianceTemplateCreateDialog() { defaultValues: { name: "", description: "", - version: "1.0", isActive: true, }, mode: "onChange", }) + const selectedTemplate = React.useMemo(() => { + if (selectedTemplateId === "none") { + return undefined + } + return templates.find((template) => String(template.id) === selectedTemplateId) + }, [selectedTemplateId, templates]) + + const nextVersionLabel = React.useMemo(() => { + if (!selectedTemplate) { + return null + } + const baseVersion = selectedTemplate.version || "1.0" + const numericValue = Number(baseVersion) + if (!Number.isNaN(numericValue)) { + const hasDecimal = baseVersion.includes(".") + const decimalDigits = hasDecimal ? baseVersion.split(".")[1]?.length ?? 0 : 0 + const incremented = numericValue + 1 + return hasDecimal ? incremented.toFixed(decimalDigits) : String(incremented) + } + return "1.0" + }, [selectedTemplate]) + + React.useEffect(() => { + if (selectedTemplate) { + form.setValue("name", selectedTemplate.name ?? "") + form.setValue("description", selectedTemplate.description ?? "") + } + }, [selectedTemplate, form]) + async function onSubmit(data: CreateTemplateFormValues) { setIsSubmitting(true) try { - const result = await createComplianceSurveyTemplate(data) + const baseTemplateNumericId = + selectedTemplateId !== "none" ? Number(selectedTemplateId) : undefined + + const result = await createComplianceSurveyTemplate({ + ...data, + baseTemplateId: baseTemplateNumericId, + }) if (result) { toast.success("새로운 설문조사 템플릿이 생성되었습니다.") form.reset() + setSelectedTemplateId("none") setOpen(false) // 페이지 새로고침으로 데이터 업데이트 window.location.reload() @@ -77,6 +126,7 @@ export function ComplianceTemplateCreateDialog() { function handleDialogOpenChange(nextOpen: boolean) { if (!nextOpen) { form.reset() + setSelectedTemplateId("none") } setOpen(nextOpen) } @@ -133,22 +183,37 @@ export function ComplianceTemplateCreateDialog() { )} /> - <FormField - control={form.control} - name="version" - render={({ field }) => ( - <FormItem> - <FormLabel>버전 *</FormLabel> - <FormControl> - <Input - placeholder="예: 1.0" - {...field} - /> - </FormControl> - <FormMessage /> - </FormItem> + <div className="space-y-2"> + <FormLabel>기존 템플릿 불러오기 (선택)</FormLabel> + <Select + value={selectedTemplateId} + onValueChange={(value) => setSelectedTemplateId(value)} + > + <FormControl> + <SelectTrigger> + <SelectValue placeholder="불러올 템플릿을 선택하세요" /> + </SelectTrigger> + </FormControl> + <SelectContent> + <SelectItem value="none">선택하지 않음</SelectItem> + {templates.map((template) => ( + <SelectItem key={template.id} value={String(template.id)}> + {template.name} (v{template.version}) + </SelectItem> + ))} + </SelectContent> + </Select> + {selectedTemplate ? ( + <p className="text-sm text-muted-foreground"> + 선택한 템플릿을 기반으로 새 버전(v{nextVersionLabel})이 생성되며, + 기존 템플릿은 자동으로 비활성화됩니다. + </p> + ) : ( + <p className="text-sm text-muted-foreground"> + 템플릿을 선택하지 않으면 새 템플릿이 기본 버전(v1.0)으로 생성됩니다. + </p> )} - /> + </div> <FormField control={form.control} |
