From cf77558c0ccc5c0c1bc3cdd6edd9a0475e1970c8 Mon Sep 17 00:00:00 2001 From: dujinkim 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 { 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>(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({
{packages.map((pkg) => { - // URL 기준으로 active 여부 판단 const isActive = pkg.itemId === currentItemId return ( @@ -181,19 +187,17 @@ export function Sidebar({ )} - {/* ---------- 폼 목록 ---------- */} + {/* ---------- 폼 목록 (IM 모드) / 폼과 패키지 목록 (ENG 모드) ---------- */}

{isCollapsed ? "F" : "Form Lists"}

{isLoadingForms ? ( - // 로딩 중 스켈레톤 UI 표시 Array.from({ length: 3 }).map((_, index) => (
@@ -205,45 +209,118 @@ export function Sidebar({

) : ( 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 ? ( + + + + + + {form.formName} + + + ) : ( + + ) + } + + // ENG 모드 - 폼과 그 아래 패키지들 표시 + return ( +
+ {isCollapsed ? ( + + + + + + {form.formName} + + + ) : ( + <> + + + {/* 확장된 경우 패키지 목록 표시 */} + {isExpanded && ( +
+ {packages.length === 0 ? ( +

+ No packages available +

+ ) : ( + packages.map((pkg) => { + const isPackageActive = + pkg.itemId === currentItemId && + form.formCode === currentFormCode - return isCollapsed ? ( - - - + ) + }) + )} +
)} - onClick={() => handleFormClick(form)} - disabled={isDisabled} - > - - - - - {form.formName} - - - ) : ( - +
) }) )} -- cgit v1.2.3