"use client" import * as React from "react" import { useRouter } from "next/navigation" import { useForm } from "react-hook-form" import { zodResolver } from "@hookform/resolvers/zod" import * as z from "zod" import { Loader2, Check, ChevronsUpDown, Calendar, User } from "lucide-react" import { toast } from "sonner" import { Button } from "@/components/ui/button" import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "@/components/ui/dialog" import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select" import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from "@/components/ui/command" import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover" import { Input } from "@/components/ui/input" import { Badge } from "@/components/ui/badge" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Switch } from "@/components/ui/switch" import { cn } from "@/lib/utils" import { getVendorsForSelection } from "@/lib/b-rfq/service" import { createLegalWork } from "../service" import { useSession } from "next-auth/react" interface CreateLegalWorkDialogProps { open: boolean onOpenChange: (open: boolean) => void onSuccess?: () => void onDataChange?: () => void } // legalWorks 테이블에 맞춘 단순화된 폼 스키마 const createLegalWorkSchema = z.object({ category: z.enum(["CP", "GTC", "기타"]), vendorId: z.number().min(1, "벤더를 선택해주세요"), isUrgent: z.boolean().default(false), requestDate: z.string().min(1, "답변요청일을 선택해주세요"), expectedAnswerDate: z.string().optional(), reviewer: z.string().min(1, "검토요청자를 입력해주세요"), }) type CreateLegalWorkFormValues = z.infer interface Vendor { id: number vendorName: string vendorCode: string country: string taxId: string status: string } export function CreateLegalWorkDialog({ open, onOpenChange, onSuccess, onDataChange }: CreateLegalWorkDialogProps) { const router = useRouter() const [isSubmitting, setIsSubmitting] = React.useState(false) const [vendors, setVendors] = React.useState([]) const [vendorsLoading, setVendorsLoading] = React.useState(false) const [vendorOpen, setVendorOpen] = React.useState(false) const { data: session } = useSession() const userName = React.useMemo(() => { return session?.user?.name || ""; }, [session]); const userEmail = React.useMemo(() => { return session?.user?.email || ""; }, [session]); const defaultReviewer = React.useMemo(() => { if (userName && userEmail) { return `${userName} (${userEmail})`; } else if (userName) { return userName; } else if (userEmail) { return userEmail; } return ""; }, [userName, userEmail]); const loadVendors = React.useCallback(async () => { setVendorsLoading(true) try { const vendorList = await getVendorsForSelection() setVendors(vendorList) } catch (error) { console.error("Failed to load vendors:", error) toast.error("벤더 목록을 불러오는데 실패했습니다.") } finally { setVendorsLoading(false) } }, []) // 오늘 날짜 + 7일 후를 기본 답변요청일로 설정 const getDefaultRequestDate = () => { const date = new Date() date.setDate(date.getDate() + 7) return date.toISOString().split('T')[0] } // 답변요청일 + 3일 후를 기본 답변예정일로 설정 const getDefaultExpectedDate = (requestDate: string) => { if (!requestDate) return "" const date = new Date(requestDate) date.setDate(date.getDate() + 3) return date.toISOString().split('T')[0] } const form = useForm({ resolver: zodResolver(createLegalWorkSchema), defaultValues: { category: "CP", vendorId: 0, isUrgent: false, requestDate: getDefaultRequestDate(), expectedAnswerDate: "", reviewer: defaultReviewer, }, }) React.useEffect(() => { if (open) { loadVendors() } }, [open, loadVendors]) // 세션 정보가 로드되면 검토요청자 필드 업데이트 React.useEffect(() => { if (defaultReviewer) { form.setValue("reviewer", defaultReviewer) } }, [defaultReviewer, form]) // 답변요청일 변경시 답변예정일 자동 설정 const requestDate = form.watch("requestDate") React.useEffect(() => { if (requestDate) { const expectedDate = getDefaultExpectedDate(requestDate) form.setValue("expectedAnswerDate", expectedDate) } }, [requestDate, form]) // 폼 제출 - 서버 액션 적용 async function onSubmit(data: CreateLegalWorkFormValues) { console.log("Form submitted with data:", data) setIsSubmitting(true) try { // legalWorks 테이블에 맞춘 데이터 구조 const legalWorkData = { ...data, // status는 서버에서 "검토요청"으로 설정 // consultationDate는 서버에서 오늘 날짜로 설정 // hasAttachment는 서버에서 false로 설정 } const result = await createLegalWork(legalWorkData) if (result.success) { toast.success(result.data?.message || "법무업무가 성공적으로 등록되었습니다.") onOpenChange(false) form.reset({ category: "CP", vendorId: 0, isUrgent: false, requestDate: getDefaultRequestDate(), expectedAnswerDate: "", reviewer: defaultReviewer, }) onSuccess?.() onDataChange?.() router.refresh() } else { toast.error(result.error || "등록 중 오류가 발생했습니다.") } } catch (error) { console.error("Error creating legal work:", error) toast.error("등록 중 오류가 발생했습니다.") } finally { setIsSubmitting(false) } } // 다이얼로그 닫기 핸들러 const handleOpenChange = (open: boolean) => { onOpenChange(open) if (!open) { form.reset({ category: "CP", vendorId: 0, isUrgent: false, requestDate: getDefaultRequestDate(), expectedAnswerDate: "", reviewer: defaultReviewer, }) } } // 선택된 벤더 정보 const selectedVendor = vendors.find(v => v.id === form.watch("vendorId")) return ( {/* 고정 헤더 */}
법무업무 신규 등록 새로운 법무업무를 등록합니다. 상세한 검토 요청은 등록 후 별도로 진행할 수 있습니다.
{/* 스크롤 가능한 콘텐츠 영역 */}
{/* 기본 정보 */} 기본 정보
{/* 구분 */} ( 구분 )} /> {/* 긴급여부 */} (
긴급 요청
긴급 처리가 필요한 경우 체크
)} />
{/* 벤더 선택 */} ( 벤더 { e.stopPropagation(); // 이벤트 전파 차단 const target = e.currentTarget; target.scrollTop += e.deltaY; // 직접 스크롤 처리 }}> 검색 결과가 없습니다. {vendors.map((vendor) => ( { field.onChange(vendor.id) setVendorOpen(false) }} >
{vendor.vendorCode} {vendor.vendorName}
))}
)} />
{/* 담당자 및 일정 정보 */} 담당자 및 일정 {/* 검토요청자 */} ( 검토요청자 )} />
{/* 답변요청일 */} ( 답변요청일 )} /> {/* 답변예정일 */} ( 답변예정일 (선택사항)
답변요청일 기준으로 자동 설정됩니다
)} />
{/* 안내 메시지 */}

법무업무 등록 안내

기본 정보 등록 후, 목록에서 해당 업무를 선택하여 상세한 검토 요청을 진행할 수 있습니다.

• 상태: "검토요청"으로 자동 설정
• 의뢰일: 오늘 날짜로 자동 설정
• 법무답변자: 나중에 배정

{/* 고정 버튼 영역 */}
) }