"use client" import * as React from "react" import { useForm } from "react-hook-form" import { zodResolver } from "@hookform/resolvers/zod" import { toast } from "sonner" import { Loader } from "lucide-react" import { Button } from "@/components/ui/button" import { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, } from "@/components/ui/sheet" import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form" import { Input } from "@/components/ui/input" import { Switch } from "@/components/ui/switch" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select" import { updateCodeGroup } from "../service" import { codeGroups } from "@/db/schema/codeGroups" import { z } from "zod" const updateCodeGroupSchema = z.object({ description: z.string().min(1, "Description은 필수입니다."), codeFormat: z.string().optional().refine((val) => { if (!val) return true; // 빈 값은 허용 return /^[ANX]*$/.test(val); }, "Code Format은 A(영어 대문자), N(숫자), X(영어/숫자)만 입력 가능합니다."), controlType: z.string().min(1, "Control Type은 필수입니다."), isActive: z.boolean().default(true), }) type UpdateCodeGroupFormValues = z.infer interface CodeGroupsEditSheetProps { open: boolean onOpenChange: (open: boolean) => void data: typeof codeGroups.$inferSelect | null onSuccess: () => void } export function CodeGroupsEditSheet({ open, onOpenChange, data, onSuccess, }: CodeGroupsEditSheetProps) { const [isUpdatePending, startUpdateTransition] = React.useTransition() const form = useForm({ resolver: zodResolver(updateCodeGroupSchema), defaultValues: { description: data?.description ?? "", codeFormat: data?.codeFormat ?? "", controlType: data?.controlType ?? "", isActive: data?.isActive ?? true, }, mode: "onChange" }) // Code Format을 기반으로 정규식 자동 생성 함수 const generateExpression = (codeFormat: string): string => { if (!codeFormat) return '' let expression = '^' let currentChar = codeFormat[0] let count = 1 for (let i = 1; i < codeFormat.length; i++) { if (codeFormat[i] === currentChar) { count++ } else { // 이전 문자에 대한 정규식 추가 if (currentChar === 'A') { expression += `[A-Z]{${count}}` } else if (currentChar === 'N') { expression += `[0-9]{${count}}` } else if (currentChar === 'X') { expression += `[A-Z0-9]{${count}}` } currentChar = codeFormat[i] count = 1 } } // 마지막 문자 처리 if (currentChar === 'A') { expression += `[A-Z]{${count}}` } else if (currentChar === 'N') { expression += `[0-9]{${count}}` } else if (currentChar === 'X') { expression += `[A-Z0-9]{${count}}` } expression += '$' return expression } React.useEffect(() => { if (data) { form.reset({ description: data.description, codeFormat: data.codeFormat || "", controlType: data.controlType, isActive: data.isActive ?? true, }) } }, [data, form]) async function onSubmit(input: UpdateCodeGroupFormValues) { if (!data) return startUpdateTransition(async () => { try { // Code Format이 변경되면 Expression 자동 업데이트 const expressions = generateExpression(input.codeFormat || "") const result = await updateCodeGroup({ id: data.id, description: input.description, codeFormat: input.codeFormat, expressions: expressions, controlType: input.controlType, isActive: input.isActive, }) if (result.success) { toast.success("Code Group이 성공적으로 수정되었습니다.") onSuccess() onOpenChange(false) } else { toast.error(result.error || "Code Group 수정에 실패했습니다.") } } catch (error) { console.error("Update error:", error) toast.error("Code Group 수정 중 오류가 발생했습니다.") } }) } return ( Code Group 수정 Code Group 정보를 수정하고 변경사항을 저장하세요
( Description )} /> ( Code Format form.trigger('codeFormat')} /> A: 영어 대문자, N: 숫자, X: 영어 대문자 또는 숫자 )} /> ( Control Type )} /> (
활성 상태
)} />
) }