"use client" import * as React from "react" import { zodResolver } from "@hookform/resolvers/zod" import { useForm } from "react-hook-form" import { toast } from "sonner" import * as z from "zod" import { Plus, Check, ChevronsUpDown } from "lucide-react" 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 { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, } from "@/components/ui/command" import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover" import { cn } from "@/lib/utils" import { useParams } from "next/navigation" import { createDocumentClassOptionItem, getProjectKindScheduleSetting, ScheduleSetting } from "@/lib/docu-list-rule/document-class/service" import { getProjectCode } from "@/lib/projects/service" const createOptionSchema = z.object({ optionCode: z.string().min(1, "옵션을 선택해주세요."), description: z.string().optional(), }) type CreateOptionSchema = z.infer interface DocumentClassOptionAddDialogProps { documentClassId: number onSuccess?: () => void } export function DocumentClassOptionAddDialog({ documentClassId, onSuccess }: DocumentClassOptionAddDialogProps) { const [open, setOpen] = React.useState(false) const [comboboxOpen, setComboboxOpen] = React.useState(false) const [isPending, startTransition] = React.useTransition() const [scheduleSettings, setScheduleSettings] = React.useState([]) const [isLoading, setIsLoading] = React.useState(false) const params = useParams() const projectId = Number(params?.projectId) const form = useForm({ resolver: zodResolver(createOptionSchema), defaultValues: { optionCode: "", description: "", }, }) // Dialog가 열릴 때 데이터 로드 React.useEffect(() => { if (open && projectId) { loadScheduleSettings() } }, [open, projectId]) const loadScheduleSettings = async () => { setIsLoading(true) try { // 먼저 projectId로 프로젝트 코드 가져오기 const projectCode = await getProjectCode(projectId) if (!projectCode) { toast.error("프로젝트 코드를 찾을 수 없습니다.") return } // 프로젝트 코드로 일정 설정 가져오기 const settings = await getProjectKindScheduleSetting(projectCode) setScheduleSettings(settings) } catch (error) { console.error("Error loading schedule settings:", error) toast.error("옵션 목록을 불러오는 중 오류가 발생했습니다.") } finally { setIsLoading(false) } } const handleSubmit = (data: CreateOptionSchema) => { startTransition(async () => { try { const result = await createDocumentClassOptionItem({ documentClassId, optionCode: data.optionCode, description: data.description, }) if (result.success) { toast.success("옵션이 성공적으로 추가되었습니다.") setOpen(false) form.reset() onSuccess?.() } else { toast.error(`옵션 추가 실패: ${result.error}`) } } catch (error) { console.error("Create error:", error) toast.error("옵션 추가 중 오류가 발생했습니다.") } }) } const handleCancel = () => { setOpen(false) form.reset() } const selectedOption = scheduleSettings.find( (setting) => setting.COL_NM === form.watch("optionCode") ) return ( 옵션 추가 새로운 Document Class 옵션을 추가합니다.
( 옵션 선택 {isLoading ? "로딩 중..." : "검색 결과가 없습니다."} { e.stopPropagation(); const target = e.currentTarget; target.scrollTop += e.deltaY; }} > {scheduleSettings.map((setting) => ( { form.setValue("optionCode", setting.COL_NM, { shouldValidate: true }) form.setValue("description", setting.PROJ_COL_NM || "", { shouldValidate: true }) setComboboxOpen(false) }} >
{setting.COL_NM} {setting.PROJ_COL_NM}
))}
)} />
) }