@@ -24,12 +24,33 @@ interface Channel {
2424 threads : Thread [ ] ;
2525}
2626
27+ interface RepositoryRef {
28+ id : string ;
29+ name : string ;
30+ }
31+
2732interface ChannelPanelProps {
33+ repositories ?: RepositoryRef [ ] ;
2834 onOpenThread ?: ( message : any ) => void ;
2935 onOpenInvite ?: ( ) => void ;
3036}
3137
32- export function ChannelPanel ( { onOpenThread, onOpenInvite } : ChannelPanelProps ) {
38+ const REPO_SEED_THREADS : Record < string , Thread [ ] > = {
39+ 'secureflow' : [
40+ { id : 101 , user : '김진현' , avatar : '🎨' , message : '로그인 페이지 채팅형 전환 애니메이션 확인 부탁드려요.' , time : '오늘 10:42' , replies : 2 , lastReply : '안현' } ,
41+ { id : 102 , user : '안현' , avatar : '👩💻' , message : '크게 보기 모드에서 헤더 덮는 부분까지 맞췄습니다.' , time : '오늘 10:48' , replies : 0 }
42+ ] ,
43+ 'aichat' : [
44+ { id : 201 , user : '김진필' , avatar : '👨💻' , message : '회원 탈퇴와 워크스페이스 삭제 API 명세 추가 예정입니다.' , time : '오늘 09:55' , replies : 1 , lastReply : 'CodeDock' } ,
45+ { id : 202 , user : 'CodeDock' , avatar : 'CD' , message : '리포지토리 연동 해제 정책도 문서 목록에 연결해둘게요.' , time : '오늘 09:58' , replies : 0 }
46+ ] ,
47+ 'dashboard' : [
48+ { id : 301 , user : '김재준' , avatar : '👨💼' , message : '새로운 디자인 토큰 추가했습니다. 색상 조합이 정말 좋네요!' , time : '오늘 14:20' , replies : 2 , lastReply : '김진현' } ,
49+ { id : 302 , user : '김진현' , avatar : '🎨' , message : 'UI 컴포넌트 라이브러리 마이그레이션 완료했습니다.' , time : '오늘 14:35' , replies : 0 }
50+ ]
51+ } ;
52+
53+ export function ChannelPanel ( { repositories = [ ] , onOpenThread, onOpenInvite } : ChannelPanelProps ) {
3354 const [ selectedChannel , setSelectedChannel ] = useState < string > ( 'general' ) ;
3455 const [ teamChannelsOpen , setTeamChannelsOpen ] = useState ( true ) ;
3556 const [ editingChannelId , setEditingChannelId ] = useState < string | null > ( null ) ;
@@ -50,114 +71,35 @@ export function ChannelPanel({ onOpenThread, onOpenInvite }: ChannelPanelProps)
5071 const responderTypingTimerRef = useRef < number | null > ( null ) ;
5172 const fileInputRef = useRef < HTMLInputElement | null > ( null ) ;
5273 const imageInputRef = useRef < HTMLInputElement | null > ( null ) ;
53- const [ channelList , setChannelList ] = useState < Channel [ ] > ( [
54- {
55- id : 'general' ,
56- name : '일반' ,
57- unread : 3 ,
58- threads : [
59- {
60- id : 1 ,
61- user : '김재준' ,
62- avatar : '👨💼' ,
63- message : '이번 주 스프린트 계획 공유드립니다' ,
64- time : '10:23 AM' ,
65- replies : 3 ,
66- lastReply : '안현'
67- } ,
68- {
69- id : 2 ,
70- user : '김진필' ,
71- avatar : '👨💻' ,
72- message : '새로운 API 엔드포인트 추가했습니다. /api/v2/users 확인해주세요' ,
73- time : '11:45 AM' ,
74- replies : 5 ,
75- lastReply : '김재준'
76- }
77- ]
78- } ,
79- {
80- id : 'review-room' ,
81- name : '리뷰 룸' ,
82- unread : 2 ,
83- threads : [
84- {
85- id : 7 ,
86- user : 'CodeDock' ,
87- avatar : 'CD' ,
88- message : 'PR #234 인증 변경 파일을 먼저 묶었어요. 위험 신호 3건을 확인해 주세요.' ,
89- time : '11:12 AM' ,
90- replies : 4 ,
91- lastReply : '김준우'
92- } ,
93- {
94- id : 8 ,
95- user : '김준우' ,
96- avatar : 'PR' ,
97- message : 'rate limit 빠진 부분만 체크리스트로 빼줘.' ,
98- time : '11:15 AM' ,
99- replies : 2 ,
100- lastReply : 'CodeDock'
101- }
102- ]
103- } ,
104- {
105- id : 'frontend' ,
106- name : '프론트엔드' ,
107- unread : 0 ,
108- threads : [
109- {
110- id : 3 ,
111- user : '김진현' ,
112- avatar : '🎨' ,
113- message : '새로운 컴포넌트 라이브러리 도입을 고려해보면 어떨까요?' ,
114- time : '2:15 PM' ,
115- replies : 8 ,
116- lastReply : '김진필'
117- } ,
118- {
119- id : 4 ,
120- user : '안현' ,
121- avatar : '👩💻' ,
122- message : '다크모드 구현 완료했습니다' ,
123- time : '3:30 PM' ,
124- replies : 2 ,
125- lastReply : '김진현'
126- }
127- ]
128- } ,
129- {
130- id : 'backend' ,
131- name : '백엔드' ,
132- unread : 1 ,
133- threads : [
134- {
135- id : 5 ,
136- user : '김진필' ,
137- avatar : '👨💻' ,
138- message : 'DB 최적화 작업 진행 중입니다' ,
139- time : '4:00 PM' ,
140- replies : 1 ,
141- lastReply : '김재준'
142- }
143- ]
144- } ,
145- {
146- id : 'design' ,
147- name : '디자인' ,
148- unread : 0 ,
149- threads : [
150- {
151- id : 6 ,
152- user : '김진현' ,
153- avatar : '🎨' ,
154- message : '새로운 디자인 토큰 추가했습니다' ,
155- time : '5:00 PM' ,
156- replies : 0
157- }
158- ]
159- }
160- ] ) ;
74+ const [ channelList , setChannelList ] = useState < Channel [ ] > ( ( ) => {
75+ const fixedChannels : Channel [ ] = [
76+ {
77+ id : 'general' ,
78+ name : '일반' ,
79+ unread : 3 ,
80+ threads : [
81+ { id : 1 , user : '김재준' , avatar : '👨💼' , message : '이번 주 스프린트 계획 공유드립니다' , time : '10:23 AM' , replies : 3 , lastReply : '안현' } ,
82+ { id : 2 , user : '김진필' , avatar : '👨💻' , message : '새로운 API 엔드포인트 추가했습니다. /api/v2/users 확인해주세요' , time : '11:45 AM' , replies : 5 , lastReply : '김재준' }
83+ ]
84+ } ,
85+ {
86+ id : 'review-room' ,
87+ name : '리뷰 룸' ,
88+ unread : 2 ,
89+ threads : [
90+ { id : 7 , user : 'CodeDock' , avatar : 'CD' , message : 'PR #234 인증 변경 파일을 먼저 묶었어요. 위험 신호 3건을 확인해 주세요.' , time : '11:12 AM' , replies : 4 , lastReply : '김준우' } ,
91+ { id : 8 , user : '김준우' , avatar : 'PR' , message : 'rate limit 빠진 부분만 체크리스트로 빼줘.' , time : '11:15 AM' , replies : 2 , lastReply : 'CodeDock' }
92+ ]
93+ }
94+ ] ;
95+ const repoChannels : Channel [ ] = repositories . map ( repo => ( {
96+ id : repo . id ,
97+ name : repo . name ,
98+ unread : REPO_SEED_THREADS [ repo . id ] ? 1 : 0 ,
99+ threads : REPO_SEED_THREADS [ repo . id ] ?? [ ]
100+ } ) ) ;
101+ return [ ...fixedChannels , ...repoChannels ] ;
102+ } ) ;
161103
162104 const handleDeleteChannelClick = ( channelId : string ) => {
163105 if ( channelId === 'general' ) return ;
@@ -257,6 +199,24 @@ export function ChannelPanel({ onOpenThread, onOpenInvite }: ChannelPanelProps)
257199 } ;
258200 } , [ ] ) ;
259201
202+ useEffect ( ( ) => {
203+ const repoIds = new Set ( repositories . map ( r => r . id ) ) ;
204+ setChannelList ( prev => {
205+ const fixed = prev . filter ( ch => ch . id === 'general' || ch . id === 'review-room' ) ;
206+ const repoChannels = repositories . map ( repo => {
207+ const existing = prev . find ( ch => ch . id === repo . id ) ;
208+ if ( existing ) return { ...existing , name : repo . name } ;
209+ return { id : repo . id , name : repo . name , unread : 0 , threads : [ ] } ;
210+ } ) ;
211+ return [ ...fixed , ...repoChannels ] ;
212+ } ) ;
213+ setSelectedChannel ( prev => {
214+ if ( prev === 'general' || prev === 'review-room' ) return prev ;
215+ if ( ! repoIds . has ( prev ) ) return 'general' ;
216+ return prev ;
217+ } ) ;
218+ } , [ repositories ] ) ;
219+
260220 const triggerResponderTyping = ( ) => {
261221 if ( responderTypingTimerRef . current ) {
262222 window . clearTimeout ( responderTypingTimerRef . current ) ;
@@ -379,8 +339,6 @@ export function ChannelPanel({ onOpenThread, onOpenInvite }: ChannelPanelProps)
379339
380340 const getChannelIcon = ( channelId : string ) => {
381341 if ( channelId === 'review-room' ) return GitPullRequest ;
382- if ( channelId === 'frontend' ) return Code2 ;
383- if ( channelId === 'backend' ) return Database ;
384342 return Hash ;
385343 } ;
386344
0 commit comments