"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 { useRouter } from "next/navigation" 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, } 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 { toast } from "sonner" import { createTechVendorItemSchema, type CreateTechVendorItemSchema, } from "@/lib/tech-vendors/validations" import { createTechVendorItem, getItemsForTechVendor, ItemDropdownOption } from "../service" interface AddItemDialogProps { vendorId: number vendorType: string // UI에서 전달하지만 내부적으로는 사용하지 않음 } export function AddItemDialog({ vendorId }: AddItemDialogProps) { const router = useRouter() 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) const form = useForm({ resolver: zodResolver(createTechVendorItemSchema), defaultValues: { vendorId, itemCode: "", }, }) const fetchItems = React.useCallback(async () => { if (items.length > 0) return console.log(`[AddItemDialog] fetchItems - 벤더 ID: ${vendorId} 시작`) setIsLoading(true) try { console.log(`[AddItemDialog] getItemsForTechVendor 호출 - vendorId: ${vendorId}`) const result = await getItemsForTechVendor(vendorId) console.log(`[AddItemDialog] getItemsForTechVendor 결과:`, result) if (result.data) { console.log(`[AddItemDialog] 사용 가능한 아이템 목록:`, result.data) setItems(result.data as ItemDropdownOption[]) setFilteredItems(result.data as ItemDropdownOption[]) } else if (result.error) { console.error("[AddItemDialog] 아이템 조회 실패:", result.error) toast.error(result.error) } } catch (err) { console.error("[AddItemDialog] 아이템 조회 실패:", err) toast.error("아이템 목록을 불러오는데 실패했습니다.") } finally { setIsLoading(false) console.log(`[AddItemDialog] fetchItems 완료`) } }, [items.length, vendorId]) React.useEffect(() => { if (commandOpen) { console.log(`[AddItemDialog] Popover 열림 - fetchItems 호출`) fetchItems() } }, [commandOpen, fetchItems]) React.useEffect(() => { if (!items.length) return if (!searchTerm.trim()) { setFilteredItems(items) return } console.log(`[AddItemDialog] 검색어로 필터링: "${searchTerm}"`) const lowerSearch = searchTerm.toLowerCase() const filtered = items.filter(item => item.itemCode.toLowerCase().includes(lowerSearch) || item.itemList.toLowerCase().includes(lowerSearch) || (item.subItemList && item.subItemList.toLowerCase().includes(lowerSearch)) ) console.log(`[AddItemDialog] 필터링 결과: ${filtered.length}개 아이템`) setFilteredItems(filtered) }, [searchTerm, items]) const handleSelectItem = (item: ItemDropdownOption) => { console.log(`[AddItemDialog] 아이템 선택: ${item.itemCode}`) form.setValue("itemCode", item.itemCode, { shouldValidate: true }) setSelectedItem({ itemName: item.itemList, description: item.subItemList || "", }) console.log(`[AddItemDialog] 선택된 아이템 정보:`, { itemCode: item.itemCode, itemName: item.itemList, description: item.subItemList || "" }) setCommandOpen(false) } async function onSubmit(data: CreateTechVendorItemSchema) { console.log(`[AddItemDialog] 폼 제출 시작 - 데이터:`, data) try { if (!data.itemCode) { console.error(`[AddItemDialog] itemCode가 없습니다.`) toast.error("아이템을 선택해주세요.") return } console.log(`[AddItemDialog] createTechVendorItem 호출 - vendorId: ${data.vendorId}, itemCode: ${data.itemCode}`) const submitData = { ...data, itemName: selectedItem?.itemName || "기술영업" } console.log(`[AddItemDialog] 최종 제출 데이터:`, submitData) const result = await createTechVendorItem(submitData) console.log(`[AddItemDialog] createTechVendorItem 결과:`, result) if (result.error) { console.error(`[AddItemDialog] 추가 실패:`, result.error) toast.error(result.error) return } console.log(`[AddItemDialog] 아이템 추가 성공`) toast.success("아이템이 추가되었습니다.") form.reset() setSelectedItem(null) setOpen(false) console.log(`[AddItemDialog] 화면 새로고침 시작`) router.refresh() console.log(`[AddItemDialog] 화면 새로고침 완료`) } catch (err) { console.error("[AddItemDialog] 아이템 추가 오류:", err) toast.error("아이템 추가 중 오류가 발생했습니다.") } } function handleDialogOpenChange(nextOpen: boolean) { console.log(`[AddItemDialog] 다이얼로그 상태 변경: ${nextOpen ? '열림' : '닫힘'}`) if (!nextOpen) { form.reset() setSelectedItem(null) } setOpen(nextOpen) } const selectedItemCode = form.watch("itemCode") console.log(`[AddItemDialog] 현재 선택된 itemCode:`, selectedItemCode) const displayItemName = selectedItem?.itemName || "" return ( Create New Item 아이템을 선택한 후 Create 버튼을 누르세요.
{ console.log(`[AddItemDialog] 폼 제출 이벤트 발생`) form.handleSubmit(onSubmit)(e) }} className="flex flex-col flex-1 overflow-hidden">
아이템 선택 검색 결과가 없습니다 {isLoading ? (
로딩 중...
) : ( {filteredItems.map((item) => ( handleSelectItem(item)} > {item.itemCode} - {item.itemList} ))} )}
{selectedItem && (

선택된 아이템 정보

( )} />
Item Name
{selectedItem.itemName}
{selectedItem.description && (
Description
{selectedItem.description}
)}
)}
) }