"use client"; import * as React from "react"; import { Search, X } from "lucide-react"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Badge } from "@/components/ui/badge"; import { getItemsForTechVendor, addTechVendorPossibleItem } from "../service"; interface ItemData { id: number; itemCode: string | null; itemList: string | null; workType: string | null; shipTypes?: string | null; subItemList?: string | null; itemType: "SHIP" | "TOP" | "HULL"; createdAt: Date; updatedAt: Date; } interface AddItemDialogProps { open: boolean; onOpenChange: (open: boolean) => void; vendorId: number; } export function AddItemDialog({ open, onOpenChange, vendorId }: AddItemDialogProps) { // 아이템 관련 상태 const [items, setItems] = React.useState([]); const [filteredItems, setFilteredItems] = React.useState([]); const [itemSearch, setItemSearch] = React.useState(""); const [selectedItems, setSelectedItems] = React.useState([]); const [isLoading, setIsLoading] = React.useState(false); // 다이얼로그가 열릴 때 아이템 목록 로드 React.useEffect(() => { if (open && vendorId) { loadItems(); } }, [open, vendorId]); // 아이템 검색 필터링 React.useEffect(() => { if (!itemSearch) { setFilteredItems(items); } else { const filtered = items.filter(item => item.itemCode?.toLowerCase().includes(itemSearch.toLowerCase()) || item.itemList?.toLowerCase().includes(itemSearch.toLowerCase()) || item.workType?.toLowerCase().includes(itemSearch.toLowerCase()) ); setFilteredItems(filtered); } }, [items, itemSearch]); const loadItems = async () => { try { setIsLoading(true); console.log("Loading items for vendor:", vendorId); const result = await getItemsForTechVendor(vendorId); if (result.error) { throw new Error(result.error); } console.log("Loaded items:", result.data.length, result.data); // itemCode가 null이 아닌 항목만 필터링 const validItems = result.data.filter(item => item.itemCode != null); setItems(validItems as ItemData[]); } catch (error) { console.error("Failed to load items:", error); toast.error("아이템 목록을 불러오는데 실패했습니다."); } finally { setIsLoading(false); } }; const handleItemToggle = (item: ItemData) => { if (!item.itemCode) return; // itemCode가 null인 경우 처리하지 않음 setSelectedItems(prev => { // id + itemType 조합으로 중복 체크 const isSelected = prev.some(i => i.id === item.id && i.itemType === item.itemType ); if (isSelected) { return prev.filter(i => !(i.id === item.id && i.itemType === item.itemType) ); } else { return [...prev, item]; } }); }; const handleSubmit = async () => { if (selectedItems.length === 0) return; try { setIsLoading(true); let successCount = 0; let errorCount = 0; for (const item of selectedItems) { if (!item.itemCode) continue; // itemCode가 null인 경우 건너뛰기 const result = await addTechVendorPossibleItem({ vendorId: vendorId, itemId: item.id, itemType: item.itemType, }); if (result.success) { successCount++; } else { errorCount++; console.error("Failed to add item:", item.itemCode, result.error); } } if (successCount > 0) { toast.success( `${successCount}개의 아이템이 추가되었습니다.${ errorCount > 0 ? ` (${errorCount}개 실패)` : "" }` ); handleClose(); } else { toast.error("아이템 추가에 실패했습니다."); } } catch (error) { console.error("Failed to add items:", error); toast.error("아이템 추가 중 오류가 발생했습니다."); } finally { setIsLoading(false); } }; const handleClose = () => { onOpenChange(false); setTimeout(() => { setSelectedItems([]); setItemSearch(""); setItems([]); setFilteredItems([]); }, 200); }; return ( 아이템 연결 연결할 아이템을 선택하세요. 복수 선택이 가능합니다.
{/* 검색 */}
setItemSearch(e.target.value)} className="pl-10" />
{/* 선택된 아이템 표시 */} {selectedItems.length > 0 && (
{selectedItems.map((item) => { if (!item.itemCode) return null; const itemKey = `${item.itemType}-${item.id}-${item.itemCode}${item.shipTypes ? `-${item.shipTypes}` : ''}`; const displayText = `[${item.itemType}] ${item.itemCode}${item.shipTypes ? `-${item.shipTypes}` : ''}`; return ( {displayText} { e.stopPropagation(); handleItemToggle(item); }} /> ); })}
)} {/* 아이템 목록 */}
{isLoading ? (
아이템 로딩 중...
) : filteredItems.length === 0 && items.length === 0 ? (
해당 벤더 타입에 대한 추가 가능한 아이템이 없습니다.
) : filteredItems.length === 0 ? (
검색 결과가 없습니다.
) : ( filteredItems.map((item) => { if (!item.itemCode) return null; // itemCode가 null인 경우 렌더링하지 않음 // id + itemType 조합으로 선택 여부 체크 const isSelected = selectedItems.some(i => i.id === item.id && i.itemType === item.itemType ); const itemKey = `${item.itemType}-${item.id}-${item.itemCode}${item.shipTypes ? `-${item.shipTypes}` : ''}`; return (
handleItemToggle(item)} >
{`[${item.itemType}] ${item.itemCode}${item.shipTypes ? `-${item.shipTypes}` : ''}`}
{item.itemList || "-"}
공종: {item.workType || "-"} {item.shipTypes && 선종: {item.shipTypes}} {item.subItemList && 서브아이템: {item.subItemList}}
); }) )}
); }