From cf77558c0ccc5c0c1bc3cdd6edd9a0475e1970c8 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Tue, 21 Oct 2025 09:05:52 +0000
Subject: (대표님) 설계측 오류 및 스타일 등 수정
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 components/vendor-data/sidebar.tsx | 211 +++++++++++++++++++++++++------------
 1 file changed, 144 insertions(+), 67 deletions(-)

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

diff --git a/components/vendor-data/sidebar.tsx b/components/vendor-data/sidebar.tsx
index a6b35a9d..2e633442 100644
--- a/components/vendor-data/sidebar.tsx
+++ b/components/vendor-data/sidebar.tsx
@@ -10,7 +10,7 @@ import {
   TooltipTrigger,
   TooltipContent,
 } from "@/components/ui/tooltip"
-import { Package2, FormInput } from "lucide-react"
+import { Package2, FormInput, ChevronRight, ChevronDown } from "lucide-react"
 import { useRouter, usePathname } from "next/navigation"
 import { Skeleton } from "@/components/ui/skeleton"
 import { type FormInfo } from "@/lib/forms/services"
@@ -27,10 +27,10 @@ interface SidebarProps extends React.HTMLAttributes<HTMLDivElement> {
   selectedProjectId: number | null
   selectedContractId: number | null
   onSelectPackage: (itemId: number) => void
-  forms?: FormInfo[]  // 선택적 속성으로 변경
+  forms?: FormInfo[]
   onSelectForm: (formName: string) => void
   isLoadingForms?: boolean
-  mode: "IM" | "ENG" // 새로 추가: 현재 선택된 모드
+  mode: "IM" | "ENG"
 }
 
 export function Sidebar({
@@ -42,36 +42,34 @@ export function Sidebar({
   selectedContractId,
   onSelectPackage,
   forms,
-  // selectedForm, // 사용되지 않음
   onSelectForm,
   isLoadingForms = false,
-  mode = "IM", // 기본값 설정
+  mode = "IM",
 }: SidebarProps) {
   const router = useRouter()
   const rawPathname = usePathname()
   const pathname = rawPathname ?? ""
+  
+  // ENG 모드에서 각 폼의 확장/축소 상태 관리
+  const [expandedForms, setExpandedForms] = React.useState<Set<string>>(new Set())
 
- 
   /**
    * ---------------------------
    * 1) URL에서 현재 패키지 / 폼 코드 추출
    * ---------------------------
    */
-  const segments = pathname.split("/").filter(Boolean) 
-  // 예) "/partners/vendor-data/tag/123" => ["partners","vendor-data","tag","123"]
+  const segments = pathname.split("/").filter(Boolean)
 
   let currentItemId: number | null = null
   let currentFormCode: string | null = null
 
   const tagIndex = segments.indexOf("tag")
   if (tagIndex !== -1 && segments[tagIndex + 1]) {
-    // tag 뒤에 오는 값이 패키지 itemId
     currentItemId = parseInt(segments[tagIndex + 1], 10)
   }
 
   const formIndex = segments.indexOf("form")
   if (formIndex !== -1) {
-    // form 뒤 첫 파라미터 => itemId, 그 다음 파라미터 => formCode
     const itemSegment = segments[formIndex + 1]
     const codeSegment = segments[formIndex + 2]
 
@@ -85,41 +83,50 @@ export function Sidebar({
 
   /**
    * ---------------------------
-   * 2) 패키지 클릭 핸들러
+   * 2) 패키지 클릭 핸들러 (IM 모드)
    * ---------------------------
    */
   const handlePackageClick = (itemId: number) => {
-    // 상위 컴포넌트 상태 업데이트만 수행
-    // 라우팅은 하지 않음 (프로젝트 선택 상태 유지)
     onSelectPackage(itemId)
   }
 
   /**
    * ---------------------------
-   * 3) 폼 클릭 핸들러 (mode 추가)
+   * 3) 폼 클릭 핸들러 (IM 모드)
    * ---------------------------
    */
   const handleFormClick = (form: FormInfo) => {
-    // 패키지 ID 선택 전략
-    let packageId: number;
-
-    if (mode === "ENG") {
-      // ENG 모드에서는 첫 번째 패키지 ID 또는 현재 URL에서 추출한 ID 사용
-      packageId = 0;
-    } else {
+    if (mode === "IM") {
       // IM 모드에서는 반드시 선택된 패키지 ID 필요
       if (selectedPackageId === null) return;
-      packageId = selectedPackageId;
+      
+      onSelectForm(form.formName)
+      
+      const baseSegments = segments.slice(0, segments.indexOf("vendor-data") + 1).join("/")
+      router.push(`/${baseSegments}/form/${selectedPackageId}/${form.formCode}/${selectedProjectId}/${selectedContractId}?mode=${mode}`)
+    } else {
+      // ENG 모드에서는 폼을 클릭하면 확장/축소만 토글
+      const newExpanded = new Set(expandedForms)
+      if (newExpanded.has(form.formCode)) {
+        newExpanded.delete(form.formCode)
+      } else {
+        newExpanded.add(form.formCode)
+      }
+      setExpandedForms(newExpanded)
     }
+  }
 
-    // 상위 컴포넌트 상태 업데이트
+  /**
+   * ---------------------------
+   * 4) 패키지 클릭 핸들러 (ENG 모드)
+   * ---------------------------
+   */
+  const handlePackageUnderFormClick = (form: FormInfo, pkg: PackageData) => {
     onSelectForm(form.formName)
-
-    // 해당 폼 페이지로 라우팅
-    // 예: /vendor-data/form/[packageId]/[formCode]
+    onSelectPackage(pkg.itemId)
+    
     const baseSegments = segments.slice(0, segments.indexOf("vendor-data") + 1).join("/")
-    // 모드 정보를 쿼리 파라미터로 추가
-    router.push(`/${baseSegments}/form/${packageId}/${form.formCode}/${selectedProjectId}/${selectedContractId}?mode=${mode}`)
+    router.push(`/${baseSegments}/form/${pkg.itemId}/${form.formCode}/${selectedProjectId}/${selectedContractId}?mode=${mode}`)
   }
 
   return (
@@ -135,7 +142,6 @@ export function Sidebar({
               <ScrollArea className="h-[150px] px-1">
                 <div className="space-y-1 p-2">
                   {packages.map((pkg) => {
-                    // URL 기준으로 active 여부 판단
                     const isActive = pkg.itemId === currentItemId
 
                     return (
@@ -181,19 +187,17 @@ export function Sidebar({
           </>
         )}
 
-        {/* ---------- 폼 목록 ---------- */}
+        {/* ---------- 폼 목록 (IM 모드) / 폼과 패키지 목록 (ENG 모드) ---------- */}
         <div className="py-1">
           <h2 className="relative px-7 text-lg font-semibold tracking-tight">
             {isCollapsed ? "F" : "Form Lists"}
           </h2>
           <ScrollArea className={cn(
             "px-1",
-            // IM 모드는 더 작은 높이, ENG 모드는 더 큰 높이 
             mode === "IM" ? "h-[300px]" : "h-[450px]"
           )}>
             <div className="space-y-1 p-2">
               {isLoadingForms ? (
-                // 로딩 중 스켈레톤 UI 표시
                 Array.from({ length: 3 }).map((_, index) => (
                   <div key={`form-skeleton-${index}`} className="px-2 py-1.5">
                     <Skeleton className="h-8 w-full" />
@@ -205,45 +209,118 @@ export function Sidebar({
                 </p>
               ) : (
                 forms.map((form) => {
-                  // URL 기준으로 active 여부 판단
-                  const isActive = form.formCode === currentFormCode
+                  const isFormActive = form.formCode === currentFormCode
+                  const isExpanded = expandedForms.has(form.formCode)
+                  
+                  // IM 모드
+                  if (mode === "IM") {
+                    const isDisabled = currentItemId === null
 
-                  // IM 모드에서만 패키지 선택 여부에 따라 비활성화
-                  const isDisabled = mode === "IM" && currentItemId === null;
+                    return isCollapsed ? (
+                      <Tooltip key={form.formCode} delayDuration={0}>
+                        <TooltipTrigger asChild>
+                          <Button
+                            variant="ghost"
+                            className={cn(
+                              "w-full justify-start font-normal",
+                              isFormActive && "bg-accent text-accent-foreground"
+                            )}
+                            onClick={() => handleFormClick(form)}
+                            disabled={isDisabled}
+                          >
+                            <FormInput className="mr-2 h-4 w-4" />
+                          </Button>
+                        </TooltipTrigger>
+                        <TooltipContent side="right">
+                          {form.formName}
+                        </TooltipContent>
+                      </Tooltip>
+                    ) : (
+                      <Button
+                        key={form.formCode}
+                        variant="ghost"
+                        className={cn(
+                          "w-full justify-start font-normal",
+                          isFormActive && "bg-accent text-accent-foreground"
+                        )}
+                        onClick={() => handleFormClick(form)}
+                        disabled={isDisabled}
+                      >
+                        <FormInput className="mr-2 h-4 w-4" />
+                        {form.formName}
+                      </Button>
+                    )
+                  }
+                  
+                  // ENG 모드 - 폼과 그 아래 패키지들 표시
+                  return (
+                    <div key={form.formCode}>
+                      {isCollapsed ? (
+                        <Tooltip delayDuration={0}>
+                          <TooltipTrigger asChild>
+                            <Button
+                              variant="ghost"
+                              className="w-full justify-start font-normal"
+                              // onClick={() => handleFormClick(form)}
+                            >
+                              <FormInput className="mr-2 h-4 w-4" />
+                            </Button>
+                          </TooltipTrigger>
+                          <TooltipContent side="right">
+                            {form.formName}
+                          </TooltipContent>
+                        </Tooltip>
+                      ) : (
+                        <>
+                          <Button
+                            variant="ghost"
+                            className="w-full justify-start font-normal"
+                            // onClick={() => handleFormClick(form)}
+                          >
+                            {isExpanded ? (
+                              <ChevronDown className="mr-2 h-4 w-4" />
+                            ) : (
+                              <ChevronRight className="mr-2 h-4 w-4" />
+                            )}
+                            <FormInput className="mr-2 h-4 w-4" />
+                            {form.formName}
+                          </Button>
+                          
+                          {/* 확장된 경우 패키지 목록 표시 */}
+                          {isExpanded && (
+                            <div className="ml-4 space-y-1">
+                              {packages.length === 0 ? (
+                                <p className="text-xs text-muted-foreground px-4 py-1">
+                                  No packages available
+                                </p>
+                              ) : (
+                                packages.map((pkg) => {
+                                  const isPackageActive = 
+                                    pkg.itemId === currentItemId && 
+                                    form.formCode === currentFormCode
 
-                  return isCollapsed ? (
-                    <Tooltip key={form.formCode} delayDuration={0}>
-                      <TooltipTrigger asChild>
-                        <Button
-                          variant="ghost"
-                          className={cn(
-                            "w-full justify-start font-normal",
-                            isActive && "bg-accent text-accent-foreground"
+                                  return (
+                                    <Button
+                                      key={`${form.formCode}-${pkg.itemId}`}
+                                      variant="ghost"
+                                      size="sm"
+                                      className={cn(
+                                        "w-full justify-start font-normal text-sm",
+                                        isPackageActive && "bg-accent text-accent-foreground"
+                                      )}
+                                      onClick={() => handlePackageUnderFormClick(form, pkg)}
+                                    >
+                                      <Package2 className="mr-2 h-3 w-3" />
+                                      {pkg.itemName}
+                                    </Button>
+                                  )
+                                })
+                              )}
+                            </div>
                           )}
-                          onClick={() => handleFormClick(form)}
-                          disabled={isDisabled}
-                        >
-                          <FormInput className="mr-2 h-4 w-4" />
-                        </Button>
-                      </TooltipTrigger>
-                      <TooltipContent side="right">
-                        {form.formName}
-                      </TooltipContent>
-                    </Tooltip>
-                  ) : (
-                    <Button
-                      key={form.formCode}
-                      variant="ghost"
-                      className={cn(
-                        "w-full justify-start font-normal",
-                        isActive && "bg-accent text-accent-foreground"
+                        </>
                       )}
-                      onClick={() => handleFormClick(form)}
-                      disabled={isDisabled}
-                    >
-                      <FormInput className="mr-2 h-4 w-4" />
-                      {form.formName}
-                    </Button>
+                    </div>
                   )
                 })
               )}
-- 
cgit v1.2.3

