From ef4c533ebacc2cdc97e518f30e9a9350004fcdfb Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Mon, 28 Apr 2025 02:13:30 +0000
Subject: ~20250428 작업사항
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 components/vendor-data/vendor-data-container.tsx | 265 ++++++++++++++++++-----
 1 file changed, 216 insertions(+), 49 deletions(-)

(limited to 'components/vendor-data/vendor-data-container.tsx')

diff --git a/components/vendor-data/vendor-data-container.tsx b/components/vendor-data/vendor-data-container.tsx
index 11aa6f9d..77b36abf 100644
--- a/components/vendor-data/vendor-data-container.tsx
+++ b/components/vendor-data/vendor-data-container.tsx
@@ -6,9 +6,14 @@ import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "@/componen
 import { cn } from "@/lib/utils"
 import { ProjectSwitcher } from "./project-swicher"
 import { Sidebar } from "./sidebar"
-import {  usePathname, useRouter } from "next/navigation"
+import { usePathname, useRouter, useSearchParams } from "next/navigation"
 import { getFormsByContractItemId, type FormInfo } from "@/lib/forms/services"
 import { Separator } from "@/components/ui/separator"
+import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs"
+import { ScrollArea } from "@/components/ui/scroll-area"
+import { Button } from "@/components/ui/button"
+import { FormInput } from "lucide-react"
+import { Skeleton } from "@/components/ui/skeleton"
 
 interface PackageData {
   itemId: number
@@ -25,6 +30,7 @@ interface ProjectData {
   projectId: number
   projectCode: string
   projectName: string
+  projectType: string
   contracts: ContractData[]
 }
 
@@ -58,45 +64,86 @@ export function VendorDataContainer({
   children
 }: VendorDataContainerProps) {
   const pathname = usePathname()
+  const router = useRouter()
+  const searchParams = useSearchParams()
 
   const tagIdNumber = getTagIdFromPathname(pathname)
 
-
-  const [isCollapsed, setIsCollapsed] = React.useState(defaultCollapsed)
-  // 폼 로드 요청 추적
-  const lastRequestIdRef = React.useRef(0)
-
   // 기본 상태
   const [selectedProjectId, setSelectedProjectId] = React.useState(projects[0]?.projectId || 0)
+  const [isCollapsed, setIsCollapsed] = React.useState(defaultCollapsed)
   const [selectedContractId, setSelectedContractId] = React.useState(
     projects[0]?.contracts[0]?.contractId || 0
   )
-  // URL에서 들어온 tagIdNumber를 우선으로 설정하기 위해 초기에 null로 두고, 뒤에서 useEffect로 세팅
   const [selectedPackageId, setSelectedPackageId] = React.useState<number | null>(null)
-
-
   const [formList, setFormList] = React.useState<FormInfo[]>([])
   const [selectedFormCode, setSelectedFormCode] = React.useState<string | null>(null)
   const [isLoadingForms, setIsLoadingForms] = React.useState(false)
 
-
   // 현재 선택된 프로젝트/계약/패키지
   const currentProject = projects.find((p) => p.projectId === selectedProjectId) ?? projects[0]
   const currentContract = currentProject?.contracts.find((c) => c.contractId === selectedContractId)
     ?? currentProject?.contracts[0]
 
-    const isTagOrFormRoute = pathname ? (pathname.includes("/tag/") || pathname.includes("/form/")) : false
-    const currentPackageName = isTagOrFormRoute
-      ? currentContract?.packages.find((pkg) => pkg.itemId === selectedPackageId)?.itemName || "None"
-      : "None"
+  // 프로젝트 타입 확인 - ship인 경우 항상 ENG 모드
+  const isShipProject = currentProject?.projectType === "ship"
+  
+  // URL에서 모드 추출 (ship 프로젝트면 무조건 ENG로, 아니면 URL 또는 기본값)
+  const modeFromUrl = searchParams?.get('mode')
+  const initialMode = isShipProject 
+    ? "ENG" 
+    : (modeFromUrl === "ENG" || modeFromUrl === "IM") ? modeFromUrl : "IM"
+
+  // 모드 선택 상태 - 프로젝트 타입에 따라 초기값 결정
+  const [selectedMode, setSelectedMode] = React.useState<"IM" | "ENG">(initialMode)
+
+  const isTagOrFormRoute = pathname ? (pathname.includes("/tag/") || pathname.includes("/form/")) : false
+  const currentPackageName = isTagOrFormRoute
+    ? currentContract?.packages.find((pkg) => pkg.itemId === selectedPackageId)?.itemName || "None"
+    : "None"
   
   // 폼 목록에서 고유한 폼 이름만 추출
   const formNames = React.useMemo(() => {
     return [...new Set(formList.map((form) => form.formName))]
   }, [formList])
 
+  // URL에서 현재 폼 코드 추출
+  const getCurrentFormCode = (path: string): string | null => {
+    const segments = path.split("/").filter(Boolean)
+    const formIndex = segments.indexOf("form")
+    if (formIndex !== -1 && segments[formIndex + 2]) {
+      return segments[formIndex + 2]
+    }
+    return null
+  }
+
+  const currentFormCode = React.useMemo(() => {
+    return pathname ? getCurrentFormCode(pathname) : null
+  }, [pathname])
+
+  // URL에서 모드가 변경되면 상태도 업데이트 (ship 프로젝트가 아닐 때만)
+  React.useEffect(() => {
+    if (!isShipProject) {
+      const modeFromUrl = searchParams?.get('mode')
+      if (modeFromUrl === "ENG" || modeFromUrl === "IM") {
+        setSelectedMode(modeFromUrl)
+      }
+    }
+  }, [searchParams, isShipProject])
+
+  // 프로젝트 타입이 변경될 때 모드 업데이트
+  React.useEffect(() => {
+    if (isShipProject) {
+      setSelectedMode("ENG")
+      
+      // URL 모드 파라미터도 업데이트
+      const url = new URL(window.location.href);
+      url.searchParams.set('mode', 'ENG');
+      router.replace(url.pathname + url.search);
+    }
+  }, [isShipProject, router])
+
   // (1) 새로고침 시 URL 파라미터(tagIdNumber) → selectedPackageId 세팅
-  //     URL에 tagIdNumber가 있으면 그걸 우선으로, 아니면 기존 로직대로 '첫 번째 패키지' 사용
   React.useEffect(() => {
     if (!currentContract) return
 
@@ -121,17 +168,7 @@ export function VendorDataContainer({
     }
   }, [currentProject])
 
-  // // (3) selectedPackageId 바뀔 때 URL도 같이 업데이트
-  // React.useEffect(() => {
-  //   if (!selectedPackageId) return
-  //   const basePath = pathname.includes("/partners/")
-  //     ? "/partners/vendor-data/tag/"
-  //     : "/vendor-data/tag/"
-
-  //   router.push(`${basePath}${selectedPackageId}`)
-  // }, [selectedPackageId, router, pathname])
-
-  // (4) 패키지 ID가 정해질 때마다 폼 로딩
+  // (3) 패키지 ID와 모드가 변경될 때마다 폼 로딩
   React.useEffect(() => {
     const packageId = getTagIdFromPathname(pathname)
     
@@ -139,27 +176,30 @@ export function VendorDataContainer({
       setSelectedPackageId(packageId)
       
       // URL에서 패키지 ID를 얻었을 때 즉시 폼 로드
-      loadFormsList(packageId);
+      loadFormsList(packageId, selectedMode);
     } else if (currentContract?.packages?.length) {
-      setSelectedPackageId(currentContract.packages[0].itemId)
+      const firstPackageId = currentContract.packages[0].itemId;
+      setSelectedPackageId(firstPackageId);
+      loadFormsList(firstPackageId, selectedMode);
     }
-  }, [pathname, currentContract])
+  }, [pathname, currentContract, selectedMode])
   
-  // 폼 로드 함수를 컴포넌트 내부에 정의하고 재사용
-  const loadFormsList = async (packageId: number) => {
+  // 모드에 따른 폼 로드 함수
+  const loadFormsList = async (packageId: number, mode: "IM" | "ENG") => {
     if (!packageId) return;
     
     setIsLoadingForms(true);
     try {
-      const result = await getFormsByContractItemId(packageId);
+      const result = await getFormsByContractItemId(packageId, mode);
       setFormList(result.forms || []);
     } catch (error) {
-      console.error("폼 로딩 오류:", error);
+      console.error(`폼 로딩 오류 (${mode} 모드):`, error);
       setFormList([]);
     } finally {
       setIsLoadingForms(false);
     }
   };
+
   // 핸들러들
   function handleSelectContract(projId: number, cId: number) {
     setSelectedProjectId(projId)
@@ -177,6 +217,27 @@ export function VendorDataContainer({
     }
   }
 
+  // 모드 변경 핸들러
+  const handleModeChange = (mode: "IM" | "ENG") => {
+    // ship 프로젝트인 경우 모드 변경 금지
+    if (isShipProject && mode !== "ENG") return;
+    
+    setSelectedMode(mode);
+    
+    // 현재 URL에서 mode 파라미터 업데이트 (현재 경로 유지)
+    const url = new URL(window.location.href);
+    url.searchParams.set('mode', mode);
+    router.replace(url.pathname + url.search);
+    
+    // 모드가 변경되면 현재 패키지의 폼 다시 로드
+    if (selectedPackageId) {
+      loadFormsList(selectedPackageId, mode);
+    } else if (currentContract?.packages?.length) {
+      const firstPackageId = currentContract.packages[0].itemId;
+      loadFormsList(firstPackageId, mode);
+    }
+  };
+
   return (
     <TooltipProvider delayDuration={0}>
       <ResizablePanelGroup direction="horizontal" className="h-full">
@@ -204,21 +265,123 @@ export function VendorDataContainer({
             />
           </div>
           <Separator />
-          <Sidebar
-            isCollapsed={isCollapsed}
-            packages={currentContract?.packages || []}
-            selectedPackageId={selectedPackageId}
-            onSelectPackage={handleSelectPackage}
-            forms={formList}
-            selectedForm={
-              selectedFormCode
-                ? formList.find((f) => f.formCode === selectedFormCode)?.formName || null
-                : null
-            }
-            onSelectForm={handleSelectForm}
-            isLoadingForms={isLoadingForms}
-            className="hidden lg:block"
-          />
+          
+          {!isCollapsed ? (
+            isShipProject ? (
+              // 프로젝트 타입이 ship인 경우: 탭 없이 ENG 모드 사이드바만 바로 표시
+              <div className="mt-0">
+                <Sidebar
+                  isCollapsed={isCollapsed}
+                  packages={currentContract?.packages || []}
+                  selectedPackageId={selectedPackageId}
+                  onSelectPackage={handleSelectPackage}
+                  forms={formList}
+                  selectedForm={
+                    selectedFormCode
+                      ? formList.find((f) => f.formCode === selectedFormCode)?.formName || null
+                      : null
+                  }
+                  onSelectForm={handleSelectForm}
+                  isLoadingForms={isLoadingForms}
+                  mode="ENG"
+                  className="hidden lg:block"
+                />
+              </div>
+            ) : (
+              // 프로젝트 타입이 ship이 아닌 경우: 기존 탭 UI 표시
+              <Tabs
+                defaultValue={initialMode}
+                value={selectedMode}
+                onValueChange={(value) => handleModeChange(value as "IM" | "ENG")}
+                className="w-full"
+              >
+                <TabsList className="w-full">
+                  <TabsTrigger value="IM" className="flex-1">IM</TabsTrigger>
+                  <TabsTrigger value="ENG" className="flex-1">ENG</TabsTrigger>
+                </TabsList>
+                
+                <TabsContent value="IM" className="mt-0">
+                  <Sidebar
+                    isCollapsed={isCollapsed}
+                    packages={currentContract?.packages || []}
+                    selectedPackageId={selectedPackageId}
+                    onSelectPackage={handleSelectPackage}
+                    forms={formList}
+                    selectedForm={
+                      selectedFormCode
+                        ? formList.find((f) => f.formCode === selectedFormCode)?.formName || null
+                        : null
+                    }
+                    onSelectForm={handleSelectForm}
+                    isLoadingForms={isLoadingForms}
+                    mode="IM"
+                    className="hidden lg:block"
+                  />
+                </TabsContent>
+                
+                <TabsContent value="ENG" className="mt-0">
+                  <Sidebar
+                    isCollapsed={isCollapsed}
+                    packages={currentContract?.packages || []}
+                    selectedPackageId={selectedPackageId}
+                    onSelectPackage={handleSelectPackage}
+                    forms={formList}
+                    selectedForm={
+                      selectedFormCode
+                        ? formList.find((f) => f.formCode === selectedFormCode)?.formName || null
+                        : null
+                    }
+                    onSelectForm={handleSelectForm}
+                    isLoadingForms={isLoadingForms}
+                    mode="ENG"
+                    className="hidden lg:block"
+                  />
+                </TabsContent>
+              </Tabs>
+            )
+          ) : (
+            // 접혀있을 때 UI
+            <>
+              {!isShipProject && (
+                // ship 프로젝트가 아닐 때만 모드 선택 버튼 표시
+                <div className="flex justify-center space-x-1 my-2">
+                  <Button 
+                    variant={selectedMode === "IM" ? "default" : "ghost"} 
+                    size="sm"
+                    className="h-8 px-2"
+                    onClick={() => handleModeChange("IM")}
+                  >
+                    IM
+                  </Button>
+                  <Button 
+                    variant={selectedMode === "ENG" ? "default" : "ghost"} 
+                    size="sm"
+                    className="h-8 px-2"
+                    onClick={() => handleModeChange("ENG")}
+                  >
+                    ENG
+                  </Button>
+                </div>
+              )}
+              
+              <Sidebar
+                isCollapsed={isCollapsed}
+                packages={currentContract?.packages || []}
+                selectedPackageId={selectedPackageId}
+                onSelectPackage={handleSelectPackage}
+                forms={formList}
+                selectedForm={
+                  selectedFormCode
+                    ? formList.find((f) => f.formCode === selectedFormCode)?.formName || null
+                    : null
+                }
+                onSelectForm={handleSelectForm}
+                isLoadingForms={isLoadingForms}
+                mode={isShipProject ? "ENG" : selectedMode}
+                className="hidden lg:block"
+              />
+            </>
+          )}
         </ResizablePanel>
 
         <ResizableHandle withHandle />
@@ -226,7 +389,11 @@ export function VendorDataContainer({
         <ResizablePanel defaultSize={defaultLayout[1]} minSize={40}>
           <div className="p-4 h-full overflow-auto flex flex-col">
             <div className="flex items-center justify-between mb-4">
-              <h2 className="text-lg font-bold">Package: {currentPackageName}</h2>
+              <h2 className="text-lg font-bold">
+                {isShipProject || selectedMode === "ENG" 
+                  ? "Engineering Mode" 
+                  : `Package: ${currentPackageName}`}
+              </h2>
             </div>
             {children}
           </div>
-- 
cgit v1.2.3

