Skip to content

Conversation

@wooktori
Copy link
Contributor

@wooktori wooktori commented Dec 23, 2025

📝 변경 사항

  • 채팅 관련 컴포넌트 생성

    • ChatHeader
    • ChatInput
    • MyChat
    • OtherChat
  • ChatInput 컴포넌트에서 textarea를 사용하고 있는데,
    Shift + Enter 를 입력시 줄바꿈이 가능하고, Enter만 입력시 메세지 전송이 가능

image

관련 코드

  • ref를 마지막 메세지의 끝부분에 걸어 포커스
image

관련 코드


🔗 관련 이슈

Closes #228


🧪 테스트 방법

  • 수동 테스트 검증(로컬 환경)
  • 유닛 테스트 검증
  • 통합 테스트 검증

📸 스크린샷 (선택)

image

📋 체크리스트

  • 관련 문서를 업데이트했습니다 (필요한 경우)
  • 테스트를 추가/수정했습니다 (필요한 경우)
  • Breaking change가 있다면 명시했습니다

💬 추가 코멘트

  • 데이터 형식과 같은 부가요소 고려 없이 UI만 먼저 만들었습니다!

CodeRabbit Review는 자동으로 실행되지 않습니다.

Review를 실행하려면 comment에 아래와 같이 작성해주세요

@coderabbitai review

Summary by CodeRabbit

릴리스 노트

  • 새 기능
    • 채팅 룸 페이지 추가: 메시지 목록 및 자동 스크롤 기능 포함
    • 메시지 입력 기능 추가: Enter 키로 전송, Shift+Enter로 줄바꿈 지원
    • 사용자 메시지와 타 사용자 메시지를 구분하여 표시
    • 채팅 목록에서 클라이언트 사이드 네비게이션 기능 추가
    • 뒤로가기 버튼을 포함한 채팅 헤더 추가

✏️ Tip: You can customize this high-level summary in your review settings.

@wooktori wooktori self-assigned this Dec 23, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 23, 2025

Important

Review skipped

Auto reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

새로운 채팅 페이지 UI 구현을 추가합니다. 채팅방 페이지, 헤더, 입력창, 메시지 표시 컴포넌트들을 도입하고, Chat 컴포넌트를 메시지 페이지에서 채팅 페이지로 이동시킵니다. 라우터 네비게이션과 상태 관리 로직이 포함됩니다.

Changes

Cohort / File(s) Summary
Chat Room Page
src/app/chat/[roomId]/page.tsx
채팅방 페이지 컴포넌트 신규 추가. 모의 메시지 초기화, 메시지 제출 핸들러, 자동 스크롤 기능 포함. 헤더, 메시지 목록(내 메시지/타인 메시지 구분), 입력 영역 렌더링
Chat Header Component
src/components/pages/chat/chat-header/index.tsx
채팅 헤더 컴포넌트 신규 추가. 라우터 네비게이션(뒤로 가기), 제목 표시, 레이아웃 정렬 기능
Chat Input Component
src/components/pages/chat/chat-input/index.tsx
채팅 입력 컴포넌트 신규 추가. 제어된 상태의 텍스트영역, Enter/Shift+Enter 키 처리, 메시지 제출 콜백, 포커스 관리
Chat Message Components
src/components/pages/chat/chat-my-chat/index.tsx,
src/components/pages/chat/chat-other-chat/index.tsx
채팅 메시지 버블 컴포넌트 신규 추가. 내 메시지와 타인 메시지를 우측/좌측으로 구분하여 렌더링, 프로필 이미지, 닉네임, 시간 표시
Chat Navigation
src/components/pages/chat/chat/index.tsx
Chat 컴포넌트에 라우터 네비게이션 기능 추가. 채팅 목록 아이템 클릭 시 /chat/1 경로로 이동
Component Export Organization
src/components/pages/chat/index.ts
채팅 컴포넌트 중앙 재내보내기 인덱스 신규 추가. Chat, ChatHeader, ChatInput, MyChat, OtherChat을 단일 진입점으로 제공
Import Source Migration
src/app/message/page.tsx,
src/components/pages/message/index.ts
Chat 컴포넌트 임포트 소스를 메시지 페이지에서 채팅 페이지로 이동. 메시지 인덱스에서 Chat 내보내기 제거

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant ChatRoomPage as Chat Room<br/>Page
    participant ChatInput
    participant MessageList as Message List<br/>(MyChat/OtherChat)
    participant State as Component<br/>State
    
    User->>ChatRoomPage: 채팅방 진입
    ChatRoomPage->>State: 모의 메시지로 초기화
    ChatRoomPage->>MessageList: 메시지 목록 렌더링
    
    User->>ChatInput: 메시지 입력
    Note over ChatInput: Enter/Shift+Enter 감지
    User->>ChatInput: 메시지 제출
    ChatInput->>ChatRoomPage: onSubmit(text) 콜백
    ChatRoomPage->>State: 새 메시지 추가 (current user)
    State->>MessageList: 업데이트된 메시지 렌더링
    ChatRoomPage->>ChatRoomPage: 최신 메시지로 자동 스크롤
    ChatInput->>ChatInput: 입력 필드 초기화 및 포커스
    
    rect rgb(200, 220, 240)
        Note over ChatRoomPage,MessageList: MyChat은 우측, OtherChat은 좌측으로 구분 렌더링
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 새로운 채팅방이 탄생했네요!
메시지가 오가고 입력창이 준비되고,
헤더는 뒤로 가고 버블은 춤을 추네요.
내 메시지와 타인의 말이 아름답게 만나
UI 컴포넌트들이 한데 어울리네! ✨💬

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목은 채팅 UI 작업이라는 변경사항의 핵심을 명확하게 반영하고 있습니다.
Description check ✅ Passed PR 설명이 요구되는 템플릿 대부분의 섹션을 포함하고 있으며, 구체적인 변경사항과 스크린샷을 제공합니다.
Linked Issues check ✅ Passed PR의 코드 변경사항이 이슈 #228의 채팅 페이지 UI 작업 요구사항을 충족하고 있습니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 채팅 UI 구현과 관련되어 있으며, 범위 밖의 변경사항이 없습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot requested a review from yoorli December 23, 2025 09:29
@github-actions
Copy link

github-actions bot commented Dec 23, 2025

🎭 Playwright Report

E2E Test가 성공적으로 완료되었습니다.

Test 요약 내용을 확인해주세요.

Status Build Log Updated (UTC)
✅ Ready View Build 2025-12-24 00:21:47

📊 Test Summary

  • ✅ Passed: 3
  • ❌ Failed: 0
  • ⏱️ Duration: 26.7s

📜 Test Details

✅ Passed Tests (3)
  • profile.test.ts (3)
    • [chromium] 존재하지 않는 프로필 페이지로 접속 시 404 redirect 되는 지 테스트
    • [firefox] 존재하지 않는 프로필 페이지로 접속 시 404 redirect 되는 지 테스트
    • [webkit] 존재하지 않는 프로필 페이지로 접속 시 404 redirect 되는 지 테스트

@github-actions
Copy link

github-actions bot commented Dec 23, 2025

🎨 Storybook Report

변경 사항이 없습니다

모든 Story가 이전 빌드와 동일합니다.

Status Storybook Build Log Updated (UTC)
✅ Unchanged View Storybook View Build 2025-12-24 00:22:23

@github-actions
Copy link

github-actions bot commented Dec 23, 2025

📊 Coverage Report

Status Build Log Updated (UTC)
✅ Ready View Build 2025-12-24 00:20:36

📉 #232main에 병합하면 coverage가 0.12% 감소합니다.

Coverage 요약

@@             Coverage Diff             @@
##             main     #232       +/-   ##
===========================================
- Coverage   38.92%   38.80%    -0.12%     
===========================================
  Files         165      170        +5     
  Lines        7357     7496      +139     
  Branches      325      325         0     
===========================================
+ Hits         2864     2909       +45     
+ Misses       4493     4587       +94     

영향받은 파일

파일 Coverage 변화
/home/runner/work/WeGo_FrontEnd/WeGo_FrontEnd/src/components/pages/chat/index.ts 100.00% (+100.00%) ⬆️
/home/runner/work/WeGo_FrontEnd/WeGo_FrontEnd/src/components/pages/chat/chat/index.tsx 47.67% (+47.67%) ⬆️
/home/runner/work/WeGo_FrontEnd/WeGo_FrontEnd/src/components/pages/chat/chat-header/index.tsx 35.00% (+35.00%) ⬆️
/home/runner/work/WeGo_FrontEnd/WeGo_FrontEnd/src/components/pages/chat/chat-input/index.tsx 18.51% (+18.51%) ⬆️
/home/runner/work/WeGo_FrontEnd/WeGo_FrontEnd/src/components/pages/chat/chat-my-chat/index.tsx 47.82% (+47.82%) ⬆️
/home/runner/work/WeGo_FrontEnd/WeGo_FrontEnd/src/components/pages/chat/chat-other-chat/index.tsx 39.39% (+39.39%) ⬆️

@github-actions
Copy link

github-actions bot commented Dec 23, 2025

🚀 PR Preview Report

Build가 성공적으로 완료되었습니다.

Preview에서 변경사항을 확인하세요.

Status Preview Build Log Updated (UTC)
✅ Ready Visit Preview View Logs 2025-12-24 00:21:45

@wooktori wooktori added the Ready For Review! 리뷰 받을 준비가 되었습니다. label Dec 23, 2025
Copy link
Member

@yoorli yoorli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다~

@@ -0,0 +1,54 @@
' use client';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

앞에 공백 있어요

onChange={(e) => setMessage(e.target.value)}
onKeyDown={handleKeyDown}
/>
<button className='absolute top-4 right-5 h-6 w-6' aria-label='검색 실행' type='button'>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

검색 실행이 아니라 메시지 전송같아요

@claudia99503
Copy link
Member

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 23, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
src/components/pages/chat/chat-input/index.tsx (2)

1-1: 치명적인 문법 오류: 'use client' 지시어 앞에 공백이 있습니다.

Line 1에서 ' use client';의 여는 따옴표 뒤에 공백이 있어 'use client' 지시어가 제대로 인식되지 않습니다. 이는 클라이언트 컴포넌트로 동작하지 않게 만들 수 있는 치명적인 오류입니다.

🔎 수정 사항
-' use client';
+'use client';

48-48: aria-label이 부정확합니다.

전송 버튼의 aria-label이 "검색 실행"으로 되어 있는데, 이는 메시지 전송 버튼이므로 "메시지 전송"과 같은 적절한 레이블로 변경해야 합니다.

🔎 수정 사항
-        <button className='absolute top-4 right-5 h-6 w-6' aria-label='검색 실행' type='button'>
+        <button className='absolute top-4 right-5 h-6 w-6' aria-label='메시지 전송' type='button'>
           <Icon id='send' className='cursor-pointer text-gray-500' onClick={handleSubmit} />
         </button>
🧹 Nitpick comments (1)
src/components/pages/chat/chat-header/index.tsx (1)

7-19: 채팅방 제목을 props로 받는 것을 권장합니다.

현재 채팅방 제목이 "분당 보드게임 동아리"로 하드코딩되어 있습니다. 컴포넌트의 재사용성을 위해 제목을 props로 받는 것이 좋습니다.

🔎 제안하는 수정 사항
+interface ChatHeaderProps {
+  title: string;
+}
+
-export const ChatHeader = () => {
+export const ChatHeader = ({ title }: ChatHeaderProps) => {
   const router = useRouter();
   return (
     <div className='bg-mono-white flex w-full items-center justify-between border-b border-gray-200 px-5 py-3'>
       <Icon
         id='chevron-left-2'
         className='w-6 cursor-pointer text-gray-500'
         onClick={() => router.back()}
       />
-      <span className='text-text-md-bold text-gray-800'>분당 보드게임 동아리</span>
+      <span className='text-text-md-bold text-gray-800'>{title}</span>
       <div className='w-6' />
     </div>
   );
 };
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c47b196 and 9332687.

📒 Files selected for processing (9)
  • src/app/chat/[roomId]/page.tsx
  • src/app/message/page.tsx
  • src/components/pages/chat/chat-header/index.tsx
  • src/components/pages/chat/chat-input/index.tsx
  • src/components/pages/chat/chat-my-chat/index.tsx
  • src/components/pages/chat/chat-other-chat/index.tsx
  • src/components/pages/chat/chat/index.tsx
  • src/components/pages/chat/index.ts
  • src/components/pages/message/index.ts
💤 Files with no reviewable changes (1)
  • src/components/pages/message/index.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-17T09:40:37.733Z
Learnt from: HopeFullee
Repo: WeGo-Together/WeGo_FrontEnd PR: 205
File: src/components/pages/post-meetup/fields/cap-field/index.tsx:47-47
Timestamp: 2025-12-17T09:40:37.733Z
Learning: In TanStack Form with Zod validation, when field.state.meta.isValid is false, field.state.meta.errors is guaranteed to have at least one entry. Therefore, in an isInvalid check defined as field.state.meta.isTouched && !field.state.meta.isValid, safely access field.state.meta.errors[0] without extra null/empty checks. This guideline applies to TSX form fields under src/components/pages (and similar forms using the same pattern).

Applied to files:

  • src/components/pages/chat/chat-other-chat/index.tsx
  • src/components/pages/chat/chat-my-chat/index.tsx
  • src/components/pages/chat/chat-input/index.tsx
  • src/components/pages/chat/chat/index.tsx
  • src/components/pages/chat/chat-header/index.tsx
🧬 Code graph analysis (5)
src/components/pages/chat/chat-other-chat/index.tsx (1)
src/components/pages/chat/index.ts (1)
  • OtherChat (5-5)
src/components/pages/chat/chat-my-chat/index.tsx (1)
src/components/pages/chat/index.ts (1)
  • MyChat (4-4)
src/components/pages/chat/chat-input/index.tsx (2)
src/components/pages/chat/index.ts (1)
  • ChatInput (3-3)
src/components/icon/index.tsx (1)
  • Icon (53-59)
src/app/chat/[roomId]/page.tsx (5)
constants/default-images.ts (1)
  • DEFAULT_PROFILE_IMAGE (2-3)
src/components/pages/chat/chat-header/index.tsx (1)
  • ChatHeader (7-20)
src/components/pages/chat/chat-my-chat/index.tsx (1)
  • MyChat (11-23)
src/components/pages/chat/chat-other-chat/index.tsx (1)
  • OtherChat (13-33)
src/components/pages/chat/chat-input/index.tsx (1)
  • ChatInput (10-54)
src/components/pages/chat/chat-header/index.tsx (2)
src/components/pages/chat/index.ts (1)
  • ChatHeader (2-2)
src/components/icon/index.tsx (1)
  • Icon (53-59)
🔇 Additional comments (8)
src/components/pages/chat/chat-my-chat/index.tsx (1)

1-23: 컴포넌트 구현이 잘 되어 있습니다!

내 메시지를 표시하는 컴포넌트로서 적절하게 구현되었습니다. 오른쪽 정렬과 스타일링이 올바르게 적용되어 있습니다.

src/app/message/page.tsx (1)

10-11: import 경로 변경이 적절합니다!

Chat 컴포넌트를 chat 모듈로 이동시키고, 메시지 관련 컴포넌트들을 분리한 것이 코드 구조 개선에 도움이 됩니다.

src/app/chat/[roomId]/page.tsx (2)

20-20: 라우트 파라미터 roomId가 사용되지 않고 있습니다.

현재 /chat/[roomId] 경로이지만 roomId 파라미터를 사용하지 않고 있습니다. UI 작업 단계이므로 현재는 문제없지만, 추후 실제 데이터 연동 시 roomId를 사용하여 해당 채팅방의 데이터를 가져와야 합니다.

Next.js 15에서는 params가 비동기로 변경되었으므로, 추후 다음과 같이 사용해야 합니다:

const ChatRoomPage = async ({ params }: { params: Promise<{ roomId: string }> }) => {
  const { roomId } = await params;
  // roomId를 사용하여 채팅방 데이터 fetch
};

36-41: 자동 스크롤 구현이 잘 되어 있습니다!

새 메시지가 추가될 때 자동으로 하단으로 스크롤되도록 useEffectref를 활용한 구현이 적절합니다.

src/components/pages/chat/chat-other-chat/index.tsx (1)

1-33: 컴포넌트 구현이 적절합니다!

상대방 메시지를 표시하는 컴포넌트로서 프로필 이미지, 닉네임, 메시지 내용을 올바르게 렌더링하고 있습니다. Next.js Image 컴포넌트 사용도 적절합니다.

src/components/pages/chat/index.ts (1)

1-5: 중앙 export 구조가 잘 되어 있습니다!

채팅 관련 컴포넌트들을 한 곳에서 export하여 import 경로를 단순화하고 모듈 구조를 개선했습니다.

src/components/pages/chat/chat-input/index.tsx (2)

15-20: 키보드 입력 처리가 올바르게 구현되어 있습니다!

Enter 키로 전송하고 Shift+Enter로 줄바꿈하는 로직이 적절하게 구현되었습니다. preventDefault()를 사용하여 기본 동작을 막는 것도 좋습니다.


22-34: 메시지 전송 로직이 잘 구현되어 있습니다!

빈 메시지 검증, trim 처리, 포커스 관리가 모두 적절하게 처리되어 있습니다. 사용자 경험을 고려한 구현입니다.

Comment on lines +43 to +45
const handleClick = () => {
router.push('/chat/1');
};
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

채팅방 ID를 동적으로 사용해야 합니다.

현재 모든 채팅 아이템을 클릭하면 /chat/1로 이동하도록 하드코딩되어 있습니다. 클릭한 아이템의 id를 사용하여 해당 채팅방으로 이동해야 합니다.

🔎 제안하는 수정 사항
-  const handleClick = () => {
-    router.push('/chat/1');
+  const handleClick = (id: number) => {
+    router.push(`/chat/${id}`);
  };

그리고 Line 52의 onClick도 수정이 필요합니다:

-          onClick={handleClick}
+          onClick={() => handleClick(item.id)}

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/components/pages/chat/chat/index.tsx around lines 43-45 (and update the
onClick at line 52), the click handler is hardcoded to navigate to '/chat/1';
change it to accept the clicked chat item's id and navigate dynamically. Modify
handleClick to take an id parameter and call router.push(`/chat/${id}`) (or
router.push({ pathname: '/chat/[id]', query: { id } }) if using dynamic route
patterns), and update the onClick at line 52 to call handleClick(item.id)
(ensure item.id is typed/defined and handleClick's signature matches). Ensure
imports/types are adjusted if needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

나중에 수정할 예정입니다 임시 테스트에요ㅜㅜ

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wooktori 네, 알겠습니다! 임시 테스트 코드라면 나중에 수정하셔도 괜찮습니다. 😊

나중에 놓치지 않도록 이 내용으로 후속 이슈를 생성해 드릴까요? 원하시면 말씀해 주세요!

@wooktori wooktori merged commit 6d7fe61 into main Dec 24, 2025
7 checks passed
@wooktori wooktori deleted the hwanwook-feat/chat-ui branch December 24, 2025 00:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Ready For Review! 리뷰 받을 준비가 되었습니다.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[채팅 페이지] 채팅 페이지 UI 작업

4 participants