From 043dfe2f7ac3965de60d3f3caf636237b9d986b0 Mon Sep 17 00:00:00 2001
From: joonhoekim <26rote@gmail.com>
Date: Tue, 11 Nov 2025 19:19:25 +0900
Subject: (김준회) 정규업체 등록관리: 주요품목 컬럼 오류 수정, 주요품목
 업데이트 dialog 수정
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../table/major-items-update-dialog.tsx            | 167 +++++----------------
 1 file changed, 35 insertions(+), 132 deletions(-)

(limited to 'lib/vendor-regular-registrations/table/major-items-update-dialog.tsx')

diff --git a/lib/vendor-regular-registrations/table/major-items-update-dialog.tsx b/lib/vendor-regular-registrations/table/major-items-update-dialog.tsx
index 26741a1b..04635d2c 100644
--- a/lib/vendor-regular-registrations/table/major-items-update-dialog.tsx
+++ b/lib/vendor-regular-registrations/table/major-items-update-dialog.tsx
@@ -3,7 +3,6 @@
 import * as React from "react"
 import { useState } from "react"
 import { toast } from "sonner"
-import { X, Plus, Search } from "lucide-react"
 
 import {
   Dialog,
@@ -13,18 +12,11 @@ import {
   DialogTitle,
 } from "@/components/ui/dialog"
 import { Button } from "@/components/ui/button"
-import { Input } from "@/components/ui/input"
-import { Badge } from "@/components/ui/badge"
 import { Label } from "@/components/ui/label"
-import { searchItemsForPQ } from "@/lib/items/service"
+import { MaterialGroupSelector } from "@/components/common/material/material-group-selector"
+import { MaterialSearchItem } from "@/lib/material/material-group-service"
 import { updateMajorItems } from "../service"
 
-// PQ 대상 품목 타입 정의
-interface PQItem {
-  itemCode: string
-  itemName: string
-}
-
 interface MajorItemsUpdateDialogProps {
   open: boolean
   onOpenChange: (open: boolean) => void
@@ -43,12 +35,7 @@ export function MajorItemsUpdateDialog({
   onSuccess,
 }: MajorItemsUpdateDialogProps) {
   const [isLoading, setIsLoading] = useState(false)
-  const [selectedItems, setSelectedItems] = useState<PQItem[]>([])
-  
-  // 아이템 검색 관련 상태
-  const [itemSearchQuery, setItemSearchQuery] = useState<string>("")
-  const [filteredItems, setFilteredItems] = useState<PQItem[]>([])
-  const [showItemDropdown, setShowItemDropdown] = useState<boolean>(false)
+  const [selectedMaterials, setSelectedMaterials] = useState<MaterialSearchItem[]>([])
 
   // 기존 아이템들 파싱 및 초기화
   React.useEffect(() => {
@@ -56,65 +43,26 @@ export function MajorItemsUpdateDialog({
       try {
         const parsedItems = JSON.parse(currentItems)
         if (Array.isArray(parsedItems)) {
-          setSelectedItems(parsedItems)
+          // materialGroupCode와 materialGroupDescription이 있는 항목들만 변환
+          const materials = parsedItems
+            .filter((item: any) => item.materialGroupCode && item.materialGroupDescription)
+            .map((item: any) => ({
+              materialGroupCode: item.materialGroupCode,
+              materialGroupDescription: item.materialGroupDescription,
+              materialGroupUom: item.materialGroupUom,
+              displayText: `${item.materialGroupCode} - ${item.materialGroupDescription}`,
+            }))
+          setSelectedMaterials(materials)
         }
       } catch (error) {
         console.error("기존 주요품목 파싱 오류:", error)
-        setSelectedItems([])
+        setSelectedMaterials([])
       }
     } else if (open) {
-      setSelectedItems([])
+      setSelectedMaterials([])
     }
   }, [open, currentItems])
 
-  // 아이템 검색 필터링
-  React.useEffect(() => {
-    if (itemSearchQuery.trim() === "") {
-      setFilteredItems([])
-      setShowItemDropdown(false)
-      return
-    }
-
-    const searchItems = async () => {
-      try {
-        const results = await searchItemsForPQ(itemSearchQuery)
-        setFilteredItems(results)
-        setShowItemDropdown(true)
-      } catch (error) {
-        console.error("아이템 검색 오류:", error)
-        toast.error("아이템 검색 중 오류가 발생했습니다.")
-        setFilteredItems([])
-        setShowItemDropdown(false)
-      }
-    }
-
-    // 디바운싱: 300ms 후에 검색 실행
-    const timeoutId = setTimeout(searchItems, 300)
-    return () => clearTimeout(timeoutId)
-  }, [itemSearchQuery])
-
-  // 아이템 선택 함수
-  const handleSelectItem = (item: PQItem) => {
-    // 이미 선택된 아이템인지 확인
-    const isAlreadySelected = selectedItems.some(selectedItem => 
-      selectedItem.itemCode === item.itemCode
-    )
-    
-    if (!isAlreadySelected) {
-      setSelectedItems(prev => [...prev, item])
-    }
-    
-    // 검색 초기화
-    setItemSearchQuery("")
-    setFilteredItems([])
-    setShowItemDropdown(false)
-  }
-
-  // 아이템 제거 함수
-  const handleRemoveItem = (itemCode: string) => {
-    setSelectedItems(prev => prev.filter(item => item.itemCode !== itemCode))
-  }
-
   const handleSave = async () => {
     if (!registrationId) {
       toast.error("등록 ID가 없습니다.")
@@ -123,9 +71,16 @@ export function MajorItemsUpdateDialog({
 
     setIsLoading(true)
     try {
+      // MaterialSearchItem을 DB 저장 형식으로 변환
+      const itemsToSave = selectedMaterials.map(material => ({
+        materialGroupCode: material.materialGroupCode,
+        materialGroupDescription: material.materialGroupDescription,
+        materialGroupUom: material.materialGroupUom,
+      }))
+
       const result = await updateMajorItems(
         registrationId,
-        JSON.stringify(selectedItems)
+        JSON.stringify(itemsToSave)
       )
 
       if (result.success) {
@@ -153,72 +108,20 @@ export function MajorItemsUpdateDialog({
           </DialogDescription>
         </DialogHeader>
 
-        <div className="space-y-6 mt-6">
-          {/* 선택된 아이템들 표시 */}
-          {selectedItems.length > 0 && (
-            <div className="space-y-2">
-              <Label>선택된 주요품목 ({selectedItems.length}개)</Label>
-              <div className="flex flex-wrap gap-2 max-h-40 overflow-y-auto border rounded-md p-3">
-                {selectedItems.map((item) => (
-                  <Badge key={item.itemCode} variant="secondary" className="flex items-center gap-1">
-                    <span className="text-xs">
-                      {item.itemCode} - {item.itemName}
-                    </span>
-                    <Button
-                      type="button"
-                      variant="ghost"
-                      size="sm"
-                      className="h-4 w-4 p-0 hover:bg-destructive hover:text-destructive-foreground"
-                      onClick={() => handleRemoveItem(item.itemCode)}
-                    >
-                      <X className="h-3 w-3" />
-                    </Button>
-                  </Badge>
-                ))}
-              </div>
-            </div>
-          )}
-          
-          {/* 검색 입력 */}
+        <div className="space-y-4 mt-6">
           <div className="space-y-2">
-            <Label>품목 검색 및 추가</Label>
-            <div className="relative">
-              <div className="relative">
-                <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-muted-foreground" />
-                <Input
-                  placeholder="아이템 코드 또는 이름으로 검색하세요"
-                  value={itemSearchQuery}
-                  onChange={(e) => setItemSearchQuery(e.target.value)}
-                  className="pl-9"
-                />
-              </div>
-              
-              {/* 검색 결과 드롭다운 */}
-              {showItemDropdown && (
-                <div className="absolute top-full left-0 right-0 z-50 mt-1 max-h-48 overflow-y-auto bg-background border rounded-md shadow-lg">
-                  {filteredItems.length > 0 ? (
-                    filteredItems.map((item) => (
-                      <button
-                        key={item.itemCode}
-                        type="button"
-                        className="w-full px-3 py-2 text-left text-sm hover:bg-muted focus:bg-muted focus:outline-none"
-                        onClick={() => handleSelectItem(item)}
-                      >
-                        <div className="font-medium">{item.itemCode}</div>
-                        <div className="text-muted-foreground text-xs">{item.itemName}</div>
-                      </button>
-                    ))
-                  ) : (
-                    <div className="px-3 py-2 text-sm text-muted-foreground">
-                      검색 결과가 없습니다.
-                    </div>
-                  )}
-                </div>
-              )}
-            </div>
-            
+            <Label>자재그룹 검색 및 선택</Label>
+            <MaterialGroupSelector
+              selectedMaterials={selectedMaterials}
+              onMaterialsChange={setSelectedMaterials}
+              singleSelect={false}
+              placeholder="자재그룹을 검색하세요..."
+              noValuePlaceHolder="자재그룹을 선택해주세요"
+              closeOnSelect={false}
+              showInitialData={true}
+            />
             <div className="text-xs text-muted-foreground">
-              아이템 코드나 이름을 입력하여 검색하고 선택하세요.
+              선택됨: {selectedMaterials.length}개
             </div>
           </div>
         </div>
-- 
cgit v1.2.3

