From 39f21a1e0f7491e9e70a2e41f07d691d179b3126 Mon Sep 17 00:00:00 2001
From: joonhoekim <26rote@gmail.com>
Date: Thu, 4 Sep 2025 02:24:27 +0000
Subject: (김준회) material-selector(자재그룹선택기) 공용컴포넌트 구현
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 components/common/material/material-selector.tsx | 36 ++++++++++++++++++------
 1 file changed, 27 insertions(+), 9 deletions(-)

(limited to 'components/common/material/material-selector.tsx')

diff --git a/components/common/material/material-selector.tsx b/components/common/material/material-selector.tsx
index b24a2f4f..67b8c25c 100644
--- a/components/common/material/material-selector.tsx
+++ b/components/common/material/material-selector.tsx
@@ -4,7 +4,6 @@ import React, { useState, useCallback } from "react";
 import { Button } from "@/components/ui/button";
 import { Input } from "@/components/ui/input";
 import { Badge } from "@/components/ui/badge";
-import { ScrollArea } from "@/components/ui/scroll-area";
 import {
   Popover,
   PopoverContent,
@@ -33,6 +32,7 @@ interface MaterialSelectorProps {
   className?: string;
   closeOnSelect?: boolean;
   excludeMaterialCodes?: Set<string>; // 제외할 자재그룹코드들
+  showInitialData?: boolean; // 초기 클릭시 자재그룹들을 로드할지 여부
 }
 
 export function MaterialSelector({
@@ -45,7 +45,8 @@ export function MaterialSelector({
   maxSelections,
   className,
   closeOnSelect = true,
-  excludeMaterialCodes
+  excludeMaterialCodes,
+  showInitialData = true
 }: MaterialSelectorProps) {
   
   const [open, setOpen] = useState(false);
@@ -54,6 +55,7 @@ export function MaterialSelector({
   const [isSearching, setIsSearching] = useState(false);
   const [searchError, setSearchError] = useState<string | null>(null);
   const [currentPage, setCurrentPage] = useState(1);
+  const [initialDataLoaded, setInitialDataLoaded] = useState(false);
   const [pagination, setPagination] = useState({
     page: 1,
     perPage: 10,
@@ -107,11 +109,22 @@ export function MaterialSelector({
     }
   }, []);
 
+  // Popover 열림시 초기 데이터 로드
+  React.useEffect(() => {
+    if (open && showInitialData && !initialDataLoaded && !searchQuery.trim()) {
+      setInitialDataLoaded(true);
+      performSearch("", 1); // 빈 쿼리로 초기 데이터 로드
+    }
+  }, [open, showInitialData, initialDataLoaded, searchQuery, performSearch]);
+
   // Debounced 검색어 변경 시 검색 실행 (검색어가 있을 때만)
   React.useEffect(() => {
     if (debouncedSearchQuery.trim()) {
       setCurrentPage(1);
       performSearch(debouncedSearchQuery, 1);
+    } else if (showInitialData && initialDataLoaded) {
+      // 검색어가 없고 초기 데이터를 보여주는 경우 초기 데이터 유지
+      // 아무것도 하지 않음 (기존 데이터 유지)
     } else {
       // 검색어가 없으면 결과 초기화
       setSearchResults([]);
@@ -124,14 +137,15 @@ export function MaterialSelector({
         hasPrevPage: false,
       });
     }
-  }, [debouncedSearchQuery, performSearch]);
+  }, [debouncedSearchQuery, performSearch, showInitialData, initialDataLoaded]);
 
   // 페이지 변경 처리 - useCallback으로 메모이제이션
   const handlePageChange = useCallback((newPage: number) => {
     if (newPage >= 1 && newPage <= pagination.pageCount) {
-      performSearch(debouncedSearchQuery, newPage);
+      const query = debouncedSearchQuery.trim() || (showInitialData && initialDataLoaded ? "" : debouncedSearchQuery);
+      performSearch(query, newPage);
     }
-  }, [pagination.pageCount, performSearch, debouncedSearchQuery]);
+  }, [pagination.pageCount, performSearch, debouncedSearchQuery, showInitialData, initialDataLoaded]);
 
   // 자재 선택 처리 - useCallback으로 메모이제이션
   const handleMaterialSelect = useCallback((material: MaterialSearchItem) => {
@@ -244,11 +258,15 @@ export function MaterialSelector({
             </div>
 
             <CommandList>
-              <ScrollArea className="h-64">
-                {!searchQuery.trim() ? (
+              <div className="h-64 overflow-y-auto">
+                {!searchQuery.trim() && !showInitialData ? (
                   <div className="p-4 text-center text-sm text-muted-foreground">
                     자재를 검색하려면 검색어를 입력해주세요.
                   </div>
+                ) : !searchQuery.trim() && showInitialData && !initialDataLoaded ? (
+                  <div className="p-4 text-center text-sm text-muted-foreground">
+                    자재 목록을 로드하려면 클릭해주세요.
+                  </div>
                 ) : isSearching ? (
                   <div className="p-4 text-center text-sm text-muted-foreground">
                     검색 중...
@@ -303,7 +321,7 @@ export function MaterialSelector({
                               )}
                             </div>
                             <div className="text-xs text-muted-foreground">
-                              코드: {material.materialGroupCode}
+                              자재그룹코드: {material.materialGroupCode}
                             </div>
                           </div>
                         </CommandItem>
@@ -311,7 +329,7 @@ export function MaterialSelector({
                     })}
                   </CommandGroup>
                 )}
-              </ScrollArea>
+              </div>
 
               {/* 페이지네이션 */}
               {searchResults.length > 0 && pagination.pageCount > 1 && (
-- 
cgit v1.2.3

