"use client" import * as React from "react" import { useForm } from "react-hook-form" import { zodResolver } from "@hookform/resolvers/zod" import { Check, ChevronsUpDown } from "lucide-react" import { toast } from "sonner" import { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from "@/components/ui/dialog" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form" import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select" import { Popover, PopoverTrigger, PopoverContent } from "@/components/ui/popover" import { Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem } from "@/components/ui/command" import { useSession } from "next-auth/react" import { createRfqSchema, type CreateRfqSchema, RfqType } from "../validations" import { createRfq, getBudgetaryRfqs } from "../service" import { ProjectSelector } from "@/components/ProjectSelector" import { type Project } from "../service" import { cn } from "@/lib/utils" import { BudgetaryRfqSelector } from "./BudgetaryRfqSelector" import { type BudgetaryRfq as ServiceBudgetaryRfq } from "../service"; // 부모 RFQ 정보 타입 정의 interface BudgetaryRfq { id: number; rfqCode: string; description: string | null; } interface AddRfqDialogProps { rfqType?: RfqType; } export function AddRfqDialog({ rfqType = RfqType.PURCHASE }: AddRfqDialogProps) { const [open, setOpen] = React.useState(false) const { data: session, status } = useSession() const [budgetaryRfqs, setBudgetaryRfqs] = React.useState([]) const [isLoadingBudgetary, setIsLoadingBudgetary] = React.useState(false) const [budgetarySearchOpen, setBudgetarySearchOpen] = React.useState(false) const [budgetarySearchTerm, setBudgetarySearchTerm] = React.useState("") const [selectedBudgetaryRfq, setSelectedBudgetaryRfq] = React.useState(null) // Get the user ID safely, ensuring it's a valid number const userId = React.useMemo(() => { const id = session?.user?.id ? Number(session.user.id) : null; // Debug logging - remove in production console.log("Session status:", status); console.log("Session data:", session); console.log("User ID:", id); return id; }, [session, status]); // RfqType에 따른 타이틀 생성 const getTitle = () => { return rfqType === RfqType.PURCHASE ? "Purchase RFQ" : "Budgetary RFQ"; }; // RHF + Zod const form = useForm({ resolver: zodResolver(createRfqSchema), defaultValues: { rfqCode: "", description: "", projectId: undefined, parentRfqId: undefined, dueDate: new Date(), status: "DRAFT", rfqType: rfqType, // Don't set createdBy yet - we'll set it when the form is submitted createdBy: undefined, }, }); // Update form values when session loads React.useEffect(() => { if (status === "authenticated" && userId) { form.setValue("createdBy", userId); } }, [status, userId, form]); // Budgetary RFQ 목록 로드 (Purchase RFQ 생성 시만) React.useEffect(() => { if (rfqType === RfqType.PURCHASE && open) { const loadBudgetaryRfqs = async () => { setIsLoadingBudgetary(true); try { const result = await getBudgetaryRfqs(); if ('rfqs' in result) { setBudgetaryRfqs(result.rfqs as unknown as BudgetaryRfq[]); } else if ('error' in result) { console.error("Budgetary RFQs 로드 오류:", result.error); } } catch (error) { console.error("Budgetary RFQs 로드 오류:", error); } finally { setIsLoadingBudgetary(false); } }; loadBudgetaryRfqs(); } }, [rfqType, open]); // 검색어로 필터링된 Budgetary RFQ 목록 const filteredBudgetaryRfqs = React.useMemo(() => { if (!budgetarySearchTerm.trim()) return budgetaryRfqs; const lowerSearch = budgetarySearchTerm.toLowerCase(); return budgetaryRfqs.filter( rfq => rfq.rfqCode.toLowerCase().includes(lowerSearch) || (rfq.description && rfq.description.toLowerCase().includes(lowerSearch)) ); }, [budgetaryRfqs, budgetarySearchTerm]); // 프로젝트 선택 처리 const handleProjectSelect = (project: Project) => { form.setValue("projectId", project.id); }; // Budgetary RFQ 선택 처리 const handleBudgetaryRfqSelect = (rfq: BudgetaryRfq) => { setSelectedBudgetaryRfq(rfq); form.setValue("parentRfqId", rfq.id); setBudgetarySearchOpen(false); }; async function onSubmit(data: CreateRfqSchema) { // Check if user is authenticated before submitting if (status !== "authenticated" || !userId) { toast.error("사용자 인증이 필요합니다. 다시 로그인해주세요."); return; } // Make sure createdBy is set with the current user ID const submitData = { ...data, createdBy: userId }; console.log("Submitting form data:", submitData); const result = await createRfq(submitData); if (result.error) { toast.error(`에러: ${result.error}`); return; } toast.success("RFQ가 성공적으로 생성되었습니다."); form.reset(); setSelectedBudgetaryRfq(null); setOpen(false); } function handleDialogOpenChange(nextOpen: boolean) { if (!nextOpen) { form.reset(); setSelectedBudgetaryRfq(null); } setOpen(nextOpen); } // Return a message or disabled state if user is not authenticated if (status === "loading") { return ; } return ( {/* 모달을 열기 위한 버튼 */} Create New {getTitle()} 새 {getTitle()} 정보를 입력하고 Create 버튼을 누르세요.
{/* rfqType - hidden field */} ( )} /> {/* Project Selector */} ( Project )} /> {/* Budgetary RFQ Selector - 구매용 RFQ 생성 시에만 표시 */} {rfqType === RfqType.PURCHASE && ( ( Budgetary RFQ (Optional) { setSelectedBudgetaryRfq(rfq as any); form.setValue("parentRfqId", rfq?.id); }} placeholder="Budgetary RFQ 선택..." /> )} /> )} {/* rfqCode */} ( RFQ Code )} /> {/* description */} ( RFQ Description )} /> {/* dueDate */} ( Due Date { const val = e.target.value if (val) { field.onChange(new Date(val + "T00:00:00")) } }} /> )} /> {/* status (Read-only) */} ( Status {}} // Prevent changes /> )} />
) }