Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
e8ce3af
chore: 개발 환경 설정
sungahChooo Sep 24, 2025
8a323b9
chore: 불필요한 파일 삭제
sungahChooo Sep 24, 2025
c313efb
chore: 불필요한 파일 삭제
sungahChooo Sep 24, 2025
77a5070
feat: friendList페이지 구현, 사이드바 구현
sungahChooo Sep 26, 2025
7e5fce4
fix: sidebar 버그 수정
sungahChooo Sep 26, 2025
6dab8dc
feat: 채팅방 조회 페이지 스타일링
sungahChooo Sep 26, 2025
e6585b3
feat: 채팅방 스타일링 구현
sungahChooo Sep 26, 2025
9ea3b44
fix: sidebar 스타일링 수정
sungahChooo Sep 26, 2025
515e12d
feat: profile page 구현
sungahChooo Sep 27, 2025
139922f
fix: 친구 프로필 스타일 수정, 채팅방 목록 스타일 보완
sungahChooo Sep 27, 2025
88cb8dc
feat:채팅 기능 구현
sungahChooo Sep 27, 2025
f5c5a5a
fix: 배포 오류 수정
sungahChooo Sep 27, 2025
5ca0494
fix: App.tsx 오타 수정
sungahChooo Sep 27, 2025
a792497
fix: 채팅방 친구 프로필과 이름 추가
sungahChooo Sep 27, 2025
e3c8a3a
fix: 배포 오류 해결
sungahChooo Sep 27, 2025
f33f470
fix: 디자이너 피드백 반영
sungahChooo Sep 28, 2025
9b1a772
fix: 한글 끝글자 중복 입력 버그 해결
sungahChooo Sep 29, 2025
3c85a3e
fix: 한글 끝글자 중복 입력 방지 처리
sungahChooo Sep 29, 2025
806cb9f
fix: 한글 끝글자 중복 입력 방지
sungahChooo Sep 29, 2025
60ac91d
fix: 한글 중복 방지 처리
sungahChooo Sep 29, 2025
2e22f6e
feat: 공감기능 구현
sungahChooo Oct 4, 2025
2856b8b
design: favicon적용
sungahChooo Oct 4, 2025
4277df8
fix: 아이콘 깨짐 해결 및 svg파일 색 변경 가능하도록 수정
sungahChooo Oct 4, 2025
c19d7af
fix: QA 피드백 반영 – 버튼 간격 및 정렬 수정
sungahChooo Oct 6, 2025
30fc2a0
chore: 절대경로 적용
sungahChooo Oct 6, 2025
1ad5f8b
feat: 개발 안할 페이지 스타일링 및 개발
sungahChooo Oct 7, 2025
e8e6f36
feat: 상단바 기능 구현
sungahChooo Oct 7, 2025
cce6a4f
feat: 친구 프로필 조회 기능 구현
sungahChooo Oct 7, 2025
46c991d
fix: 친구 목록 조회 오류 수정
sungahChooo Oct 8, 2025
98ed5e0
fix: 배포를 위한 오류 수정
sungahChooo Oct 8, 2025
2971919
feat: 채팅방 상단 고정, 안읽은 메시지 표시, 채팅 상대 이름 표시
sungahChooo Oct 9, 2025
7c10623
fix: 채팅방 목록 페이지 배열 조절
sungahChooo Oct 9, 2025
4ba4421
fix: status bar 투명도 조절
sungahChooo Oct 10, 2025
ae3cb91
fix: header부분 투명도 조절
sungahChooo Oct 11, 2025
7f6a16a
refact: 컴포넌트화 리팩토링
sungahChooo Oct 11, 2025
7304c97
fix: 채팅 페이지 오류 해결
sungahChooo Oct 11, 2025
f3ed438
fix: 채팅방 스크롤 문제 해결
sungahChooo Oct 11, 2025
c280fcc
fix: 채팅방 시간 띄우기
sungahChooo Oct 11, 2025
3b87af9
fix: layout 오류 해결
sungahChooo Oct 11, 2025
c5ea872
refact: 프로필 페이지 컴포넌트화
sungahChooo Oct 23, 2025
45ad978
refact: 친구 프로필 컴포넌트화
sungahChooo Oct 23, 2025
a35dce7
feat: 채팅방 목록 친구 이름 띄우기 및 채팅 더미데이터 수정
sungahChooo Oct 23, 2025
8a3db48
fix: 채팅방 목록 프로필 이미지 오류 수정
sungahChooo Oct 23, 2025
fd1f1bd
refact: 채팅방 목록 프로필 이미지 컴포넌트화
sungahChooo Oct 24, 2025
ffc76ae
refact: 채팅방 리팩토링
sungahChooo Oct 25, 2025
9abafb3
fixt: 채팅방 이미지 오류 해결
sungahChooo Oct 25, 2025
718048b
fix: 채팅방 시간 형식 수정
sungahChooo Oct 25, 2025
4faf170
feat: 채팅방 날짜 화면 표시 기능
sungahChooo Oct 25, 2025
768d71b
fix: 채팅방 날짜 표시 오류 해결
sungahChooo Oct 25, 2025
9b8bed7
feat: 채팅방 메시지 최근 시간만 표시
sungahChooo Oct 25, 2025
4e9a186
로컬 스토리지 초기화 코드 삭제
sungahChooo Oct 25, 2025
4eaa78f
util함수 오류 해결
sungahChooo Oct 25, 2025
6f6b82d
refact: 컴포넌트 폴더 주소 변경
sungahChooo Oct 27, 2025
2662af5
fix: 채팅방 더미데이터에서 불러온 메시지 시간 안뜸 오류 해결
sungahChooo Oct 27, 2025
0509858
fix: 오류 방지를 위한 채팅버블 key값 수정
sungahChooo Oct 27, 2025
7a38045
style: 채팅방 헤더 참여자 이름 최대 크기 지정
sungahChooo Oct 28, 2025
447e308
refactor: 전체 레이아웃 수정
sungahChooo Nov 7, 2025
f0274b4
Add initial project documentation to README
sungahChooo Nov 12, 2025
c4259fd
Add layout section to README
sungahChooo Nov 12, 2025
edbe3ce
refact: layout 재구성
sungahChooo Nov 12, 2025
71f3481
Merge branch 'sungahChooo' of https://github.com/sungahChooo/react-me…
sungahChooo Nov 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
dist
build
12 changes: 12 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"arrowParens": "always",
"bracketSpacing": true,
"endOfLine": "lf",
"printWidth": 120,
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "all",
"useTabs": false,
"plugins": ["prettier-plugin-tailwindcss"]
}
158 changes: 89 additions & 69 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,69 +1,89 @@
# 3주차 과제: React Messenger

# 서론

안녕하세요 🙌🏻 22기 프론트엔트 운영진 **권동욱**입니다. 이번에는 드디어 투두리스트에서 벗어나 새로운 프로젝트인 **messenger** 만들기를 진행합니다.

이번 주는 특별하게 **디자이너와의 협업**으로 진행되는 과제입니다. 디자이너분께서 열심히 리디자인 한 메신저 프로젝트를 여러분들께서 구현해주시면 됩니다.

동시에, 이번 주부터는 **필수** **TypeScript** 와 **tailwind CSS**를 적용해보려고 합니다.

프로젝트의 규모가 커지게 될수록, 컴포넌트가 가지는 props의 종류 또한 다양해지게 됩니다. 무지성 코딩을 하다 보면 가끔 이 props의 구성과 이름, 어떤 타입이 들어가야 하는지 헷갈리기 마련이죠. 보통 그럴 때 다시 컴포넌트 정의 부분으로 돌아가 props의 구성을 보고 오곤 합니다.

하지만 이럴 때, typescript를 적용한다면 컴포넌트의 구성과 그 이름, 심지어 타입까지 한번에 자동완성으로 편리하게 관리할 수 있고, 생산성이 증대되겠죠.

또한, **React Hooks**에 조금 더 익숙해지는 것을 목표로 합니다. 여러 Hook들이 있지만 그 중에서도 `useState`, `useEffect`, `useRef`를 중점적으로 사용해 보는 과제인데요, React를 사용하면서 굉장히 자주 쓰이는 Hook들이기 때문에 이 부분을 집중적으로 공부해 보아요!

그럼 이번 과제도 파이팅입니다!!🎉

# 과제

## 목표

- TypeScript를 사용해봅시다.
- useState로 컴포넌트의 상태를 관리합니다.
- useEffect와 useRef의 사용법을 이해합니다.
- tailwind CSS의 사용법에 익숙해집니다.

## 기한

- 2025년 9월 27일 토요일 23:59까지

## Review Questions

- 디자이너로부터 전달받은 피그마 링크, 피그마 캡처본, 디자이너와의 소통 tmi 등
- JSX, JS, TSX, TS 각각의 확장자 개념 사용이유와 차이점.
- TypeScript를 사용하는 이유.
- SSR과 CSR 특성 및 차이점.

## 필수 구현 기능

- 피그마를 보고 [결과화면](https://react-messenger-21th-kwondu.vercel.app/)과 같이 구현합니다.
- 디자인 시스템을 구축합니다.
- tailwind CSS를 사용합니다.
- 메세지를 보내면 채팅방 하단으로 스크롤을 이동시킵니다.
- 메세지에 유저 정보(프로필 사진, 이름)를 표시합니다.
- user와 message 데이터를 json 파일에 저장합니다.
- UI는 **반응형을 제외**하고 피그마파일을 따라서 진행합니다.

### 추가 구현 기능

- 채팅방 상단의 프로필을 클릭하면 사용자를 변경할 수 있습니다.
- 더블 클릭 하면 감정표현을 추가합니다.
- 그 외 추가하고 싶은 기능이 있다면 마음껏 추가해 주세요!

참고로 이번 과제는 다음 과제까지 이어지는 과제이므로 **확장성**을 충분히 고려해 주세요. 참고로 **4주차 과제에서는 유저 및 기능 추가와 Routing을** 진행합니다. 이를 위해 [zustand](https://zustand.docs.pmnd.rs/getting-started/introduction)를 이용한 상태관리를 미리 해보시는 것을 추천합니다!!

## 링크 및 참고자료

- [React docs - Hook](https://ko.reactjs.org/docs/hooks-intro.html)
- [React의 Hooks 완벽 정복하기](https://velog.io/@velopert/react-hooks#1-usestate)
- [useEffect 완벽 가이드](https://overreacted.io/ko/a-complete-guide-to-useeffect/)
- [코딩 컨벤션](https://ui.toast.com/fe-guide/ko_CODING-CONVENTION)
- [타입스크립트 핸드북](https://joshua1988.github.io/ts/intro.html)
- [리액트 프로젝트에서 타입스크립트 사용하기 (시리즈)](https://velog.io/@velopert/series/react-with-typescript)
- [디자인 시스템 구축기](https://yozm.wishket.com/magazine/detail/1830/)
- [[영상] : 컴포넌트에 대한 이해](https://www.youtube.com/watch?v=21eiJc90ggo)
- [Styled Component로 디자인 시스템 구축하기](https://zaat.dev/blog/building-a-design-system-in-react-with-styled-components/)
- [Tailwind CSS 장단점, 사용법](https://wonny.space/writing/dev/hello-tailwind-css)
- [ts 절대경로 설정하기](https://tesseractjh.tistory.com/232)
## 소개
- CEOS 22nd 프론트엔드 디자이너 프론트 협업 과제
- 디자이너는 whats app을 리디자인하고 프론트엔드 개발자는 디자인에 따라 개발
- 디자인 링크: https://www.figma.com/design/Wnk0pj12C3VynpknZ05Gxc/%EC%A0%95%ED%95%B4%EC%9D%B8_%EC%99%93%EC%B8%A0%EC%95%B1-%EB%A6%AC%EB%94%94%EC%9E%90%EC%9D%B8?node-id=116-6955&t=rSS0dSvGjjkW7E07-0
- 디자이너: 정해인
- 프론트엔드 개발: 조성아

## Layout
불필요한 렌더링을 줄이기 위해서 layout 구조를 고민해보았습니다.
App.tsx 내에서 모든 라우트를 <Layout /> 컴포넌트로 감싸, 공통 UI(Navbar, Statusbar 등)를 일관되게 유지하도록 구성했습니다.
Layout은 React Router의 <Outlet />을 통해 하위 페이지를 렌더링하며, 공통 컴포넌트는 상태 변경 시에도 재렌더링되지 않도록 분리하여 성능을 최적화했습니다.

## 기술스택
- React
- Typescript
- Tailwind CSS
- Zustand

## 배포링크
- https://react-messenger-22nd-git-sungahchooo-chosungahs-projects.vercel.app/

## 프로젝트 구조
```bash
src
┣ assets
┃ ┣ addFriend.svg
┃ ┣ banner.svg
┃ ┣ battery.svg
┃ ┣ before.svg
┃ ... //아이콘
┣ components
┃ ┣ chat
┃ ┃ ┣ chatRoom
┃ ┃ ┃ ┣ ChatMsgBubble.tsx
┃ ┃ ┃ ┣ ChatRoomInput.tsx
┃ ┃ ┃ ┗ ChattingRoomHeader.tsx
┃ ┃ ┣ ChatBanner.tsx
┃ ┃ ┣ ChatListItem.tsx
┃ ┃ ┣ ChattingHeader.tsx
┃ ┃ ┗ ChattingListImgSection.tsx
┃ ┣ friendList
┃ ┃ ┣ profile
┃ ┃ ┃ ┣ BackgroundLayer.tsx
┃ ┃ ┃ ┣ MyProfilePageButton.tsx
┃ ┃ ┃ ┣ ProfileBox.tsx
┃ ┃ ┃ ┣ ProfilePageButton.tsx
┃ ┃ ┃ ┗ XButton.tsx
┃ ┃ ┣ FriendListHeader.tsx
┃ ┃ ┣ FriendListSection.tsx
┃ ┃ ┗ MyProfileSection.tsx
┃ ┣ Header.tsx
┃ ┣ Navbar.tsx
┃ ┣ Statusbar.tsx
┃ ┗ warning.tsx
┣ data
┃ ┣ chat.json
┃ ┣ profileImages.ts
┃ ┗ user.json
┣ layout
┃ ┗ Layout.tsx
┣ pages
┃ ┣ calls
┃ ┃ ┗ Call.tsx
┃ ┣ chat
┃ ┃ ┣ chattingRoom
┃ ┃ ┃ ┗ ChattingRoom.tsx
┃ ┃ ┗ Chatting.tsx
┃ ┣ community
┃ ┃ ┗ Community.tsx
┃ ┣ friendList
┃ ┃ ┣ profile
┃ ┃ ┃ ┣ FriendProfile.tsx
┃ ┃ ┃ ┗ MyProfile.tsx
┃ ┃ ┗ FriendList.tsx
┃ ┗ settings
┃ ┃ ┣ Setting.tsx
┃ ┃ ┗ SettingHeader.tsx
┣ stores
┃ ┗ chatStore.ts
┣ types
┃ ┣ chat.ts
┃ ┗ user.ts
┣ utils
┃ ┗ chatUtils.ts
┣ App.tsx
┣ index.css
┣ main.tsx
┗ svg.d.ts
```
23 changes: 23 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import { defineConfig, globalIgnores } from 'eslint/config'

export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs['recommended-latest'],
reactRefresh.configs.vite,
],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
},
])
15 changes: 15 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>whats app</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/pretendard/dist/web/static/pretendard.css" />
<link href="/src/index.css" rel="stylesheet" />
<link rel="icon" href="/whatsapp.png" />
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Loading