"use client" import * as React from "react" import { toast } from "sonner" import { CalendarIcon, Loader2, Plus, Check, ChevronsUpDown } from "lucide-react" import { Calendar } from "@/components/ui/calendar" import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover" import { format } from "date-fns" import { ko } from "date-fns/locale" import { Button } from "@/components/ui/button" import { Dialog, DialogContent, 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 { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select" import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from "@/components/ui/command" import { zodResolver } from "@hookform/resolvers/zod" import { useForm } from "react-hook-form" import * as z from "zod" import { createPcrPo, getVendorsForPcr } from "@/lib/pcr/service" import { PCR_CHANGE_TYPES } from "@/lib/pcr/types" import { cn } from "@/lib/utils" // PCR 생성 스키마 const createPcrSchema = z.object({ changeType: z.string().optional(), details: z.string().optional(), project: z.string().optional(), pcrRequestDate: z.date({ required_error: "PCR 요청일자를 선택해주세요.", }), poContractNumber: z.string().min(1, "PO/계약번호를 입력해주세요."), revItemNumber: z.string().optional(), purchaseContractManager: z.string().optional(), pcrCreator: z.string().optional(), poContractAmountBefore: z.number().optional(), poContractAmountAfter: z.number().optional(), contractCurrency: z.string().optional(), pcrReason: z.string().optional(), detailsReason: z.string().optional(), rejectionReason: z.string().optional(), pcrResponseDate: z.date().optional(), vendorId: z.number({ required_error: "협력업체를 선택해주세요.", }), }) type CreatePcrFormValues = z.infer interface CreatePcrDialogProps { open?: boolean onOpenChange?: (open: boolean) => void isEvcpPage?: boolean onSuccess?: () => void currentVendorId?: number // Partners 페이지에서 현재 사용자의 vendorId } interface Vendor { id: number vendorName: string vendorCode: string } export function CreatePcrDialog({ open, onOpenChange, isEvcpPage = false, onSuccess, currentVendorId, }: CreatePcrDialogProps) { const [isLoading, setIsLoading] = React.useState(false) const [internalOpen, setInternalOpen] = React.useState(false) const [vendors, setVendors] = React.useState([]) const [vendorsLoading, setVendorsLoading] = React.useState(false) const [vendorSearchOpen, setVendorSearchOpen] = React.useState(false) const dialogOpen = open !== undefined ? open : internalOpen const setDialogOpen = onOpenChange || setInternalOpen const form = useForm({ resolver: zodResolver(createPcrSchema), defaultValues: { changeType: "OTHER", contractCurrency: "KRW", pcrRequestDate: new Date(), }, }) const loadVendors = React.useCallback(async () => { try { setVendorsLoading(true) let result if (!isEvcpPage && currentVendorId) { // Partners 페이지: 특정 vendorId만 조회 result = await getVendorsForPcr({ vendorId: currentVendorId, limit: 1 }) } else { // EvcP 페이지: 모든 협력업체 조회 result = await getVendorsForPcr({ limit: 1000 }) } if (result.success) { setVendors(result.data.map(vendor => ({ id: vendor.id, vendorName: vendor.vendorName, vendorCode: vendor.vendorCode || "", }))) // Partners 페이지에서는 자동으로 해당 협력업체 선택 if (!isEvcpPage && currentVendorId && result.data.length > 0) { form.setValue("vendorId", currentVendorId) } } else { toast.error(result.error || "협력업체 목록을 불러오는 중 오류가 발생했습니다.") } } catch (error) { console.error("협력업체 로드 오류:", error) toast.error("협력업체 목록을 불러오는 중 오류가 발생했습니다.") } finally { setVendorsLoading(false) } }, [isEvcpPage, currentVendorId, form]) // 협력업체 데이터 로드 React.useEffect(() => { if (dialogOpen) { loadVendors() } }, [dialogOpen, loadVendors]) async function onSubmit(data: CreatePcrFormValues) { try { setIsLoading(true) const result = await createPcrPo({ ...data, pcrApprovalStatus: "PENDING", contractCurrency: data.contractCurrency || "KRW", changeType: data.changeType || "OTHER", }) if (result.success) { toast.success("PCR이 성공적으로 생성되었습니다.") form.reset() setDialogOpen(false) onSuccess?.() } else { toast.error(result.error || "PCR 생성에 실패했습니다.") } } catch (error) { console.error("PCR 생성 오류:", error) toast.error("PCR 생성 중 오류가 발생했습니다.") } finally { setIsLoading(false) } } return ( PCR 생성
{/* 기본 정보 섹션 */}

기본 정보

( 변경 구분 )} /> ( PCR 요청일자 * date > new Date() || date < new Date("1900-01-01") } initialFocus /> )} />
{/* 협력업체 선택 */} ( 협력업체 * {vendorsLoading ? "로딩 중..." : "협력업체를 찾을 수 없습니다."} {vendors.map((vendor) => ( { form.setValue("vendorId", vendor.id) setVendorSearchOpen(false) }} >
{vendor.vendorName} {vendor.vendorCode && ( 코드: {vendor.vendorCode} )}
))}
)} />
( PO/계약번호 * )} /> ( Rev./품번 )} />
( 프로젝트 )} /> ( 상세