1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
"use client"
import * as React from "react"
import { cn } from "@/lib/utils"
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
interface ContractInfo {
contractId: number
contractName: string
}
interface ProjectInfo {
projectId: number
projectCode: string
projectName: string
contracts: ContractInfo[]
}
interface ProjectSwitcherProps {
isCollapsed: boolean
projects: ProjectInfo[]
// 상위가 관리하는 "현재 선택된 contractId"
selectedContractId: number | null
// 콜백: 사용자가 "어떤 contract"를 골랐는지
// => 우리가 projectId도 찾아서 상위 state를 같이 갱신해야 함
onSelectContract: (projectId: number, contractId: number) => void
}
export function ProjectSwitcher({
isCollapsed,
projects,
selectedContractId,
onSelectContract,
}: ProjectSwitcherProps) {
// Select value = stringified contractId
const selectValue = selectedContractId ? String(selectedContractId) : ""
// 현재 선택된 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 }
}
}
return null
}, [projects, selectedContractId])
// Trigger label => 계약 이름 or placeholder
const triggerLabel = selectedContract?.contractName ?? "Select a contract"
// onValueChange: val = String(contractId)
// => 찾으면 projectId, contractId 모두 상위로 전달
function handleValueChange(val: string) {
const contractId = Number(val)
// Find which project has this contract
let foundProjectId = 0
let foundContractName = ""
for (const proj of projects) {
const found = proj.contracts.find((c) => c.contractId === contractId)
if (found) {
foundProjectId = proj.projectId
foundContractName = found.contractName
break
}
}
// 상위로 알림
onSelectContract(foundProjectId, contractId)
}
return (
<Select value={selectValue} onValueChange={handleValueChange}>
<SelectTrigger
className={cn(
"flex items-center gap-2",
isCollapsed && "flex h-9 w-9 shrink-0 items-center justify-center p-0"
)}
aria-label="Select Contract"
>
<SelectValue placeholder="Select a contract">
<span className={cn("ml-2", isCollapsed && "hidden")}>
{triggerLabel}
</span>
</SelectValue>
</SelectTrigger>
<SelectContent>
{projects.map((project) => (
<SelectGroup key={project.projectCode}>
<SelectLabel>{project.projectName}</SelectLabel>
{project.contracts.map((contract) => (
<SelectItem
key={contract.contractId}
value={String(contract.contractId)}
>
{contract.contractName}
</SelectItem>
))}
</SelectGroup>
))}
</SelectContent>
</Select>
)
}
|