"use client" import * as React from "react" import { zodResolver } from "@hookform/resolvers/zod" import { CalendarIcon, Loader, ChevronsUpDown, Check } from "lucide-react" import { useForm } from "react-hook-form" import { toast } from "sonner" import { format } from "date-fns" import { ko } from "date-fns/locale" import { cn } from "@/lib/utils" import { Button } from "@/components/ui/button" import { Calendar } from "@/components/ui/calendar" import { Checkbox } from "@/components/ui/checkbox" import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form" import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from "@/components/ui/command" import { Input } from "@/components/ui/input" import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select" import { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, } from "@/components/ui/sheet" import { UpdateInitialRfqSchema, updateInitialRfqSchema } from "../validations" import { getIncotermsForSelection, modifyInitialRfq } from "../service" import { InitialRfqDetailView } from "@/db/schema" interface UpdateInitialRfqSheetProps extends React.ComponentPropsWithRef { initialRfq: InitialRfqDetailView | null } interface Incoterm { id: number code: string description: string } export function UpdateInitialRfqSheet({ initialRfq, ...props }: UpdateInitialRfqSheetProps) { const [isUpdatePending, startUpdateTransition] = React.useTransition() const [incoterms, setIncoterms] = React.useState([]) const [incotermsLoading, setIncotermsLoading] = React.useState(false) const [incotermsSearchOpen, setIncotermsSearchOpen] = React.useState(false) const loadIncoterms = React.useCallback(async () => { setIncotermsLoading(true) try { const incotermsList = await getIncotermsForSelection() setIncoterms(incotermsList) } catch (error) { console.error("Failed to load incoterms:", error) toast.error("Incoterms 목록을 불러오는데 실패했습니다.") } finally { setIncotermsLoading(false) } }, []) React.useEffect(() => { if (incoterms.length === 0) { loadIncoterms() } }, [incoterms.length, loadIncoterms]) const form = useForm({ resolver: zodResolver(updateInitialRfqSchema), defaultValues: { initialRfqStatus: initialRfq?.initialRfqStatus ?? "DRAFT", dueDate: initialRfq?.dueDate ?? new Date(), validDate: initialRfq?.validDate ?? undefined, incotermsCode: initialRfq?.incotermsCode ?? "", classification: initialRfq?.classification ?? "", sparepart: initialRfq?.sparepart ?? "", rfqRevision: initialRfq?.rfqRevision ?? 0, shortList: initialRfq?.shortList ?? false, returnYn: initialRfq?.returnYn ?? false, cpRequestYn: initialRfq?.cpRequestYn ?? false, prjectGtcYn: initialRfq?.prjectGtcYn ?? false, }, }) // initialRfq가 변경될 때 폼 값을 업데이트 React.useEffect(() => { if (initialRfq) { form.reset({ initialRfqStatus: initialRfq.initialRfqStatus ?? "DRAFT", dueDate: initialRfq.dueDate, validDate: initialRfq.validDate, incotermsCode: initialRfq.incotermsCode ?? "", classification: initialRfq.classification ?? "", sparepart: initialRfq.sparepart ?? "", shortList: initialRfq.shortList ?? false, returnYn: initialRfq.returnYn ?? false, rfqRevision: initialRfq.rfqRevision ?? 0, cpRequestYn: initialRfq.cpRequestYn ?? false, prjectGtcYn: initialRfq.prjectGtcYn ?? false, }) } }, [initialRfq, form]) function onSubmit(input: UpdateInitialRfqSchema) { startUpdateTransition(async () => { if (!initialRfq || !initialRfq.initialRfqId) { toast.error("유효하지 않은 RFQ입니다.") return } const { error } = await modifyInitialRfq({ id: initialRfq.initialRfqId, ...input, }) if (error) { toast.error(error) return } form.reset() props.onOpenChange?.(false) toast.success("초기 RFQ가 수정되었습니다") }) } const selectedIncoterm = incoterms.find(incoterm => incoterm.code === form.watch("incotermsCode")) return ( {/* 고정 헤더 */} 초기 RFQ 수정 초기 RFQ 정보를 수정하고 변경사항을 저장하세요 {/* 스크롤 가능한 폼 영역 */}
{/* RFQ 리비전 */} ( RFQ 리비전 field.onChange(parseInt(e.target.value) || 0)} /> )} /> {/* 마감일 */} ( 마감일 * date < new Date("1900-01-01") } initialFocus /> )} /> {/* 유효일 */} ( 유효일 date < new Date("1900-01-01") } initialFocus /> )} /> {/* Incoterms 코드 */} ( Incoterms 검색 결과가 없습니다. {incoterms.map((incoterm) => ( { field.onChange(incoterm.code) setIncotermsSearchOpen(false) }} >
{incoterm.code} - {incoterm.description}
))}
)} /> {/* 체크박스 옵션들 */}
(
Short List
)} /> (
회신 여부
)} /> {/* 선급 */} ( 선급 )} /> {/* 예비부품 */} ( 예비부품 )} /> (
CP 요청
)} /> (
프로젝트 GTC
)} />
{/* 하단 여백 */}
{/* 고정 푸터 */} ) }