"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 { 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 { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover" import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from "@/components/ui/command" import { cn } from "@/lib/utils" import { createVendorItemSchema, type CreateVendorItemSchema, } from "../validations" import { createVendorItem, getItemsForVendor, ItemDropdownOption } from "../service" interface AddItemDialogProps { vendorId: number } export function AddItemDialog({ vendorId }: AddItemDialogProps) { const [open, setOpen] = React.useState(false) const [commandOpen, setCommandOpen] = React.useState(false) const [items, setItems] = React.useState([]) const [filteredItems, setFilteredItems] = React.useState([]) const [isLoading, setIsLoading] = React.useState(false) const [searchTerm, setSearchTerm] = React.useState("") // 선택된 아이템의 정보를 보여주기 위한 상태 const [selectedItem, setSelectedItem] = React.useState<{ itemName: string; description: string; } | null>(null) // react-hook-form 세팅 - 서버로 보낼 값은 vendorId와 itemCode만 const form = useForm({ resolver: zodResolver(createVendorItemSchema), defaultValues: { vendorId, itemCode: "", }, }) console.log(vendorId) // 아이템 목록 가져오기 (한 번만 호출) const fetchItems = React.useCallback(async () => { if (items.length > 0) return // 이미 로드된 경우 스킵 setIsLoading(true) try { const result = await getItemsForVendor(vendorId) if (result.data) { setItems(result.data) setFilteredItems(result.data) } } catch (error) { console.error("Failed to fetch items:", error) } finally { setIsLoading(false) } }, [items.length]) // 팝오버 열릴 때 아이템 목록 로드 React.useEffect(() => { if (commandOpen) { fetchItems() } }, [commandOpen, fetchItems]) // 클라이언트 사이드 필터링 React.useEffect(() => { if (!items.length) return if (!searchTerm.trim()) { setFilteredItems(items) return } const lowerSearch = searchTerm.toLowerCase() const filtered = items.filter(item => item.itemCode.toLowerCase().includes(lowerSearch) || item.itemName.toLowerCase().includes(lowerSearch) || (item.description && item.description.toLowerCase().includes(lowerSearch)) ) setFilteredItems(filtered) }, [searchTerm, items]) // 선택된 아이템 데이터로 폼 업데이트 const handleSelectItem = (item: ItemDropdownOption) => { // 폼에는 itemCode만 설정 form.setValue("itemCode", item.itemCode) // 나머지 정보는 표시용 상태에 저장 setSelectedItem({ itemName: item.itemName, description: item.description || "", }) setCommandOpen(false) } // 폼 제출 - itemCode만 서버로 전송 async function onSubmit(data: CreateVendorItemSchema) { // 서버에는 vendorId와 itemCode만 전송됨 const result = await createVendorItem(data) console.log(result) if (result.error) { alert(`에러: ${result.error}`) return } // 성공 시 모달 닫고 폼 리셋 form.reset() setSelectedItem(null) setOpen(false) } // 모달 열림/닫힘 핸들 function handleDialogOpenChange(nextOpen: boolean) { if (!nextOpen) { // 닫힐 때 폼 리셋 form.reset() setSelectedItem(null) } setOpen(nextOpen) } // 현재 선택된 아이템 코드 const selectedItemCode = form.watch("itemCode") // 선택된 아이템 코드가 있으면 상세 정보 표시를 위한 아이템 찾기 const displayItemCode = selectedItemCode || "아이템 선택..." const displayItemName = selectedItem?.itemName || "" return ( {/* 모달 열기 버튼 */} Create New Item 아이템을 선택한 후 Create 버튼을 누르세요. {/* shadcn/ui Form + react-hook-form */}
{/* 아이템 선택 */}
아이템 선택 검색 결과가 없습니다 {isLoading ? (
로딩 중...
) : ( {filteredItems.map((item) => ( handleSelectItem(item)} > {item.itemCode} - {item.itemName} ))} )}
{/* 아이템 정보 영역 - 선택된 경우에만 표시 */} {selectedItem && (

선택된 아이템 정보

{/* Item Code - readonly (hidden field) */} ( )} /> {/* Item Name (표시용) */}

Item Name

{selectedItem.itemName}

{/* Description (표시용) */} {selectedItem.description && (

Description

{selectedItem.description}

)}
)}
) }