diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-11-26 10:13:54 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-11-26 10:13:54 +0000 |
| commit | b807f0e8007d297ab282a4329bfbdeb3afcb63a7 (patch) | |
| tree | 46610f3260c1b90ff92462f4828e891b1edc3218 /components/vendor-data-plant/project-swicher.tsx | |
| parent | c775a993930e806f56ea116941574015ee518170 (diff) | |
(대표님) EDP 작업사항
Diffstat (limited to 'components/vendor-data-plant/project-swicher.tsx')
| -rw-r--r-- | components/vendor-data-plant/project-swicher.tsx | 163 |
1 files changed, 59 insertions, 104 deletions
diff --git a/components/vendor-data-plant/project-swicher.tsx b/components/vendor-data-plant/project-swicher.tsx index d3123709..9b8f9bea 100644 --- a/components/vendor-data-plant/project-swicher.tsx +++ b/components/vendor-data-plant/project-swicher.tsx @@ -1,6 +1,7 @@ "use client" import * as React from "react" +import { Check, ChevronsUpDown } from "lucide-react" import { cn } from "@/lib/utils" import { Button } from "@/components/ui/button" import { @@ -16,149 +17,103 @@ import { PopoverContent, PopoverTrigger, } from "@/components/ui/popover" -import { Check, ChevronsUpDown, Loader2 } from "lucide-react" -interface ContractInfo { - contractId: number - contractName: string +interface PackageData { + packageCode: string + packageName: string | null } -interface ProjectInfo { +interface ProjectData { projectId: number projectCode: string projectName: string - contracts: ContractInfo[] + projectType: string + packages: PackageData[] } interface ProjectSwitcherProps { isCollapsed: boolean - projects: ProjectInfo[] - - // 상위가 관리하는 "현재 선택된 contractId" - selectedContractId: number | null - - // 콜백: 사용자가 "어떤 contract"를 골랐는지 - // => 우리가 projectId도 찾아서 상위 state를 같이 갱신해야 함 - onSelectContract: (projectId: number, contractId: number) => void - - // 로딩 상태 (선택사항) - isLoading?: boolean + projects: ProjectData[] + selectedProjectId: number + selectedPackageCode: string | null + onSelectPackage: (projectId: number, packageCode: string) => void } export function ProjectSwitcher({ isCollapsed, projects, - selectedContractId, - onSelectContract, - isLoading = false, + selectedProjectId, + selectedPackageCode, + onSelectPackage, }: ProjectSwitcherProps) { - const [popoverOpen, setPopoverOpen] = React.useState(false) - const [searchTerm, setSearchTerm] = React.useState("") + const [open, setOpen] = React.useState(false) - // 현재 선택된 contract 객체 찾기 - const selectedContract = React.useMemo(() => { - if (!selectedContractId) return null - for (const proj of projects) { - const found = proj.contracts.find((c) => c.contractId === selectedContractId) - if (found) { - return { ...found, projectId: proj.projectId, projectName: proj.projectName } - } - } - return null - }, [projects, selectedContractId]) - - // Trigger label => 계약 이름 or placeholder - const triggerLabel = selectedContract?.contractName ?? "Select a contract" + // 현재 선택된 프로젝트와 패키지 정보 + const selectedProject = projects.find(p => p.projectId === selectedProjectId) + const selectedPackage = selectedProject?.packages.find( + pkg => pkg.packageCode === selectedPackageCode + ) - // 검색어에 따른 필터링된 프로젝트/계약 목록 - const filteredProjects = React.useMemo(() => { - if (!searchTerm) return projects - - return projects.map(project => ({ - ...project, - contracts: project.contracts.filter(contract => - contract.contractName.toLowerCase().includes(searchTerm.toLowerCase()) || - project.projectName.toLowerCase().includes(searchTerm.toLowerCase()) - ) - })).filter(project => project.contracts.length > 0) - }, [projects, searchTerm]) - // 계약 선택 핸들러 - function handleSelectContract(projectId: number, contractId: number) { - onSelectContract(projectId, contractId) - setPopoverOpen(false) - setSearchTerm("") // 검색어 초기화 - } + console.log(projects,"projects") - // 총 계약 수 계산 (빈 상태 표시용) - const totalContracts = filteredProjects.reduce((sum, project) => sum + project.contracts.length, 0) + const displayText = selectedPackage + ? `${selectedProject?.projectCode} - ${selectedPackage.packageCode}` + : selectedProject?.projectCode || "Select Package" return ( - <Popover open={popoverOpen} onOpenChange={setPopoverOpen}> + <Popover open={open} onOpenChange={setOpen}> <PopoverTrigger asChild> <Button - type="button" variant="outline" - className={cn( - "justify-between relative", - isCollapsed ? "h-9 w-9 shrink-0 items-center justify-center p-0" : "w-full h-9" - )} - disabled={isLoading} - aria-label="Select Contract" + role="combobox" + aria-expanded={open} + aria-label="Select a package" + className={cn("w-full justify-between", isCollapsed && "w-[50px]")} > - {isLoading ? ( - <> - <span className={cn(isCollapsed && "hidden")}>Loading...</span> - <Loader2 className={cn("h-4 w-4 animate-spin", !isCollapsed && "ml-2")} /> - </> + {isCollapsed ? ( + <ChevronsUpDown className="h-4 w-4" /> ) : ( <> - <span className={cn("truncate flex-grow text-left", isCollapsed && "hidden")}> - {triggerLabel} - </span> - <ChevronsUpDown className={cn("h-4 w-4 opacity-50 flex-shrink-0", isCollapsed && "hidden")} /> + <span className="truncate">{displayText}</span> + <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" /> </> )} </Button> </PopoverTrigger> - - <PopoverContent className="w-[320px] p-0" align="start"> + <PopoverContent className="w-[300px] p-0"> <Command> - <CommandInput - placeholder="Search contracts..." - value={searchTerm} - onValueChange={setSearchTerm} - /> - - <CommandList - className="max-h-[320px]" - onWheel={(e) => { - e.stopPropagation() // 이벤트 전파 차단 - const target = e.currentTarget - target.scrollTop += e.deltaY // 직접 스크롤 처리 - }} - > - <CommandEmpty> - {totalContracts === 0 ? "No contracts found." : "No search results."} - </CommandEmpty> - - {filteredProjects.map((project) => ( - <CommandGroup key={project.projectCode} heading={project.projectName}> - {project.contracts.map((contract) => ( + <CommandInput placeholder="Search package..." /> + <CommandList> + <CommandEmpty>No package found.</CommandEmpty> + {projects.map((project) => ( + <CommandGroup key={project.projectId} heading={project.projectName}> + {project.packages.map((pkg) => ( <CommandItem - key={contract.contractId} - onSelect={() => handleSelectContract(project.projectId, contract.contractId)} - value={`${project.projectName} ${contract.contractName}`} - className="truncate" - title={contract.contractName} + key={`${project.projectId}-${pkg.packageCode}`} + onSelect={() => { + onSelectPackage(project.projectId, pkg.packageCode) + setOpen(false) + }} + className="text-sm" > - <span className="truncate">{contract.contractName}</span> <Check className={cn( - "ml-auto h-4 w-4 flex-shrink-0", - selectedContractId === contract.contractId ? "opacity-100" : "opacity-0" + "mr-2 h-4 w-4", + selectedProjectId === project.projectId && + selectedPackageCode === pkg.packageCode + ? "opacity-100" + : "opacity-0" )} /> + <div className="flex flex-col"> + <span className="font-medium">{pkg.packageCode}</span> + {pkg.packageName && ( + <span className="text-xs text-muted-foreground"> + {pkg.packageName} + </span> + )} + </div> </CommandItem> ))} </CommandGroup> |
