1- import { useState } from "react" ;
1+ import { useEffect , useState } from "react" ;
2+
3+ const colors = [ "bg-[#C4B1A2]" , "bg-[#9DD7ED]" , "bg-[#FDD446]" , "bg-[#FFC85A]" ] ;
24
35interface AssigneeSelectProps {
46 value : string ;
57 onChange : ( value : string ) => void ;
6- users : string [ ] ; // users는 string[]이어야 합니다.
8+ users : string [ ] ;
79 label ?: string ;
810 required ?: boolean ;
911}
@@ -17,11 +19,27 @@ export default function AssigneeSelect({
1719} : AssigneeSelectProps ) {
1820 const [ isOpen , setIsOpen ] = useState ( false ) ;
1921 const [ filter , setFilter ] = useState ( "" ) ;
22+ const [ userColors , setUserColors ] = useState < Record < string , string > > ( { } ) ;
2023
24+ // 유저 필터링
2125 const filtered = users . filter ( ( name ) =>
2226 name . toLowerCase ( ) . includes ( filter . toLowerCase ( ) || "" )
2327 ) ;
2428
29+ // 유저별 색상 매핑 (한 번만 부여)
30+ useEffect ( ( ) => {
31+ setUserColors ( ( prev ) => {
32+ const updated = { ...prev } ;
33+ users . forEach ( ( user ) => {
34+ if ( ! updated [ user ] ) {
35+ const color = colors [ Math . floor ( Math . random ( ) * colors . length ) ] ;
36+ updated [ user ] = color ;
37+ }
38+ } ) ;
39+ return updated ;
40+ } ) ;
41+ } , [ users ] ) ;
42+
2543 return (
2644 < div className = "inline-flex flex-col items-start gap-2.5 w-full max-w-[520px]" >
2745 { label && (
@@ -32,14 +50,19 @@ export default function AssigneeSelect({
3250 ) }
3351
3452 < div className = "relative w-full" >
53+ { /* 선택된 담당자 */ }
3554 < div
3655 className = "flex items-center justify-between h-[48px] px-4 border border-[var(--color-gray3)] rounded-md cursor-pointer focus-within:border-[var(--primary)]"
3756 onClick = { ( ) => setIsOpen ( ! isOpen ) }
3857 >
3958 < div className = "flex items-center gap-2" >
4059 { value ? (
4160 < >
42- < span className = "w-6 h-6 rounded-full text-xs text-white flex items-center justify-center bg-[#A0E6FF]" >
61+ < span
62+ className = { `w-6 h-6 rounded-full text-xs text-white flex items-center justify-center ${
63+ userColors [ value ] || "bg-[#A0E6FF]"
64+ } `}
65+ >
4366 { value . charAt ( 0 ) . toUpperCase ( ) }
4467 </ span >
4568 < span className = "font-18r" > { value } </ span >
@@ -52,8 +75,9 @@ export default function AssigneeSelect({
5275 </ div >
5376 </ div >
5477
78+ { /* 드롭다운 */ }
5579 { isOpen && (
56- < ul className = "absolute top-full left-0 mt-1 w-full bg-white border border-[var(--color-gray3)] rounded-md shadow-lg z-10" >
80+ < ul className = "absolute top-full left-0 mt-1 w-full bg-white border border-[var(--color-gray3)] rounded-md shadow-lg z-10 max-h-[200px] overflow-y-auto " >
5781 { filtered . map ( ( name , idx ) => (
5882 < li
5983 key = { idx }
@@ -64,7 +88,16 @@ export default function AssigneeSelect({
6488 } }
6589 className = "px-4 py-2 cursor-pointer hover:bg-[var(--color-gray1)] flex items-center justify-between"
6690 >
67- < span className = "text-sm" > { name } </ span >
91+ < div className = "flex items-center gap-2" >
92+ < span
93+ className = { `w-6 h-6 rounded-full text-xs text-white flex items-center justify-center ${
94+ userColors [ name ] || "bg-[#A0E6FF]"
95+ } `}
96+ >
97+ { name . charAt ( 0 ) . toUpperCase ( ) }
98+ </ span >
99+ < span className = "text-sm" > { name } </ span >
100+ </ div >
68101 { value === name && (
69102 < span className = "text-[var(--primary)]" > ✔</ span >
70103 ) }
0 commit comments