/** * 품목 검색 모달 * * SearchableSelectionModal 공통 컴포넌트 기반 */ 'use client'; import { useCallback } from 'react'; import { SearchableSelectionModal } from '@/components/organisms/SearchableSelectionModal'; import { fetchItems } from '@/lib/api/items'; import type { ItemMaster, ItemType } from '@/types/item'; // ============================================================================= // Props (기존과 동일 — 사용처 변경 없음) // ============================================================================= interface ItemSearchModalProps { open: boolean; onOpenChange: (open: boolean) => void; onSelectItem: (item: { code: string; name: string; specification?: string; unit?: string }) => void; tabLabel?: string; /** 품목 유형 필터 (예: 'RM', 'SF', 'FG') */ itemType?: string; /** BOM 카테고리 필터 (material, motor, controller, steel, parts, inspection) */ bomCategory?: string; } // 검색어 유효성: 영문, 한글, 숫자 1자 이상 const isValidSearchQuery = (query: string) => { if (!query || !query.trim()) return false; return /[a-zA-Z가-힣ㄱ-ㅎㅏ-ㅣ0-9]/.test(query); }; // ============================================================================= // 컴포넌트 // ============================================================================= export function ItemSearchModal({ open, onOpenChange, onSelectItem, tabLabel, itemType, bomCategory, }: ItemSearchModalProps) { const handleFetchData = useCallback(async (query: string) => { const data = await fetchItems({ search: query || undefined, itemType: itemType as ItemType | undefined, bom_category: bomCategory || undefined, per_page: 50, }); return data; }, [itemType, bomCategory]); const handleSelect = useCallback((item: ItemMaster) => { onSelectItem({ code: item.itemCode, name: item.itemName, specification: item.specification || undefined, unit: item.unit || undefined, }); }, [onSelectItem]); return ( open={open} onOpenChange={onOpenChange} title={ <> 품목 검색 {tabLabel && ({tabLabel})} } searchPlaceholder="품목코드 또는 품목명 검색..." fetchData={handleFetchData} keyExtractor={(item) => item.id?.toString() ?? item.itemCode} validateSearch={isValidSearchQuery} invalidSearchMessage="영문, 한글 또는 숫자 1자 이상 입력하세요" emptyQueryMessage="품목코드 또는 품목명을 입력하세요" loadingMessage="품목 검색 중..." dialogClassName="sm:max-w-[500px]" infoText={(items, isLoading) => !isLoading ? ( 총 {items.length}개 품목 ) : null } mode="single" onSelect={handleSelect} renderItem={(item) => (
{item.itemCode} {item.itemName} {item.hasInspectionTemplate && ( 수입검사 )}
{item.unit && ( {item.unit} )}
{item.specification && (

{item.specification}

)}
)} /> ); }