summaryrefslogtreecommitdiff
path: root/components/vendor-data-plant/project-swicher.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'components/vendor-data-plant/project-swicher.tsx')
-rw-r--r--components/vendor-data-plant/project-swicher.tsx163
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>