[TIL] Next.js 심화프로젝트!

기성·2024년 10월 17일
0

TIL

목록 보기
71/81

⚽ 구단주주총회

🖥️ 프로젝트 소개

온라인 게임인 FC ONLINE의 API를 활용하여 게임 내 사용자의 전적을 확인하고 유저들과 소통할 수 있는 전적 & 커뮤니티

  • 게임 내 전적을 그래프를 통해 수치화 하여 보여줄 수 있으며,
    기존 다른 FC Online의 전적 검색 사이트와는 다르게 커뮤니티의 기능을 추가한 프로젝트 입니다.

🔗 배포 링크

구단 주주 총회 배포 링크

👨‍👩‍👧‍👦 팀 소개

🧡권다정💛신한별💚이기성💙이석원💜정지형
@kwondajung@star1024cd@Leekee0905@seokwon27@stopbrother
커뮤니티 댓글 CRUD
ZUSTAND로 로그인 정보 전역 상태 관리
플레이 정보를 바탕으로 한 평점 페이지 및 상세 모달 구현로그인/회원가입
유저 검색
전적 검색 카테고리 내 데이터 활용(그래프)
마이페이지 구현(닉네임 변경 및 작성 게시글 확인)TOAST UI EDITOR를 활용한 커뮤니티 게시판 CRUD

🕰️ 개발 기간

총 개발 기간 : 24.10.10 ~ 24.10.16

프로젝트 기획 : 24.10.10 ~ 24.10.10

프로젝트 기본 세팅 : 24.10.11~24.10.11

기능 구현 완료 : 24.10.11 ~ 24.10.15

추가 구현 완료 : 24.10.15 ~ 24.10.16


📊 기술적 의사 결정

요구사항선택지사용 근거
전역상태 라이브러리zustand과도한 props 사용을 방지하고 가벼운 전역 state 관리를 위해 zustand 사용
서버상태 라이브러리tanstack-query서버상태 관리를 쉽게 해주고 복잡한 비동기 로직을 단순화 하기 위해 사용
백엔드 서비스Supabase로그인 및 회원가입 서비스를 도와주는 백엔드 서비스와 게시물 관리를 위해 DB를 사용
글 작성 ToolTOAST UI Editor글 작성 시 편의성을 극대화 하기 위해 TOAST UI Editor 사용
UI 통일성Shadcn전적 검색 시 Accordion이나 버튼, input등의 UI의 통일성/편의성을 위해 사용

📂 폴더 구조

폴더구조
📦9danjuju
┣ 📂public
┃ ┗ 📂img
┃ ┃ ┣ 📜anonPlayerImage.png
┃ ┃ ┣ 📜favicon.png
┃ ┃ ┣ 📜field_img.jpg
┃ ┃ ┗ 📜homeBackgroundImage.jpg
┣ 📂src
┃ ┣ 📂app
┃ ┃ ┣ 📂api
┃ ┃ ┃ ┣ 📂@modal
┃ ┃ ┃ ┃ ┗ 📂(...)detail
┃ ┃ ┃ ┃ ┃ ┗ 📂[nickname]
┃ ┃ ┃ ┣ 📂matchDetail
┃ ┃ ┃ ┃ ┗ 📜route.ts
┃ ┃ ┃ ┣ 📂matchId
┃ ┃ ┃ ┃ ┗ 📜route.ts
┃ ┃ ┃ ┣ 📂playerdata
┃ ┃ ┃ ┃ ┗ 📂detail
┃ ┃ ┃ ┃ ┃ ┗ 📜route.ts
┃ ┃ ┃ ┣ 📂playerposition
┃ ┃ ┃ ┃ ┗ 📂detail
┃ ┃ ┃ ┃ ┃ ┗ 📜route.ts
┃ ┃ ┃ ┣ 📂user
┃ ┃ ┃ ┃ ┗ 📂detail
┃ ┃ ┃ ┃ ┃ ┗ 📜route.ts
┃ ┃ ┃ ┗ 📂usermatch
┃ ┃ ┃ ┃ ┗ 📂detail
┃ ┃ ┃ ┃ ┃ ┗ 📜route.ts
┃ ┃ ┣ 📂community
┃ ┃ ┃ ┣ 📂write
┃ ┃ ┃ ┃ ┗ 📜page.tsx
┃ ┃ ┃ ┣ 📂[id]
┃ ┃ ┃ ┃ ┣ 📂modify
┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx
┃ ┃ ┃ ┃ ┗ 📜page.tsx
┃ ┃ ┃ ┣ 📜loading.tsx
┃ ┃ ┃ ┗ 📜page.tsx
┃ ┃ ┣ 📂detail
┃ ┃ ┃ ┗ 📂[nickname]
┃ ┃ ┃ ┃ ┗ 📜page.tsx
┃ ┃ ┣ 📂fonts
┃ ┃ ┃ ┣ 📜NEXON-Football-Gothic-B.otf
┃ ┃ ┃ ┗ 📜NEXON-Football-Gothic-L.otf
┃ ┃ ┣ 📂login
┃ ┃ ┃ ┣ 📜loading.tsx
┃ ┃ ┃ ┗ 📜page.tsx
┃ ┃ ┣ 📂modal
┃ ┃ ┣ 📂mypage
┃ ┃ ┃ ┣ 📜loading.tsx
┃ ┃ ┃ ┗ 📜page.tsx
┃ ┃ ┣ 📂signup
┃ ┃ ┃ ┣ 📜loading.tsx
┃ ┃ ┃ ┗ 📜page.tsx
┃ ┃ ┣ 📜error.tsx
┃ ┃ ┣ 📜globals.css
┃ ┃ ┣ 📜layout.tsx
┃ ┃ ┗ 📜page.tsx
┃ ┣ 📂components
┃ ┃ ┣ 📂auth
┃ ┃ ┃ ┗ 📜AuthForm.tsx
┃ ┃ ┣ 📂comments
┃ ┃ ┃ ┗ 📜Comment.tsx
┃ ┃ ┣ 📂community
┃ ┃ ┃ ┣ 📜CommunityActionButton.tsx
┃ ┃ ┃ ┣ 📜CommunityList.tsx
┃ ┃ ┃ ┣ 📜HomeCommunityList.tsx
┃ ┃ ┃ ┗ 📜PostEditor.tsx
┃ ┃ ┣ 📂detail
┃ ┃ ┃ ┣ 📜DetailGraph.tsx
┃ ┃ ┃ ┣ 📜MatchAccordion.tsx
┃ ┃ ┃ ┣ 📜MatchContainer.tsx
┃ ┃ ┃ ┣ 📜MatchDetailContents.tsx
┃ ┃ ┃ ┣ 📜MatchRateDetail.tsx
┃ ┃ ┃ ┣ 📜PlayerImage.tsx
┃ ┃ ┃ ┗ 📜UserInfoBox.tsx
┃ ┃ ┣ 📂Field
┃ ┃ ┃ ┗ 📜Field.tsx
┃ ┃ ┣ 📂layout
┃ ┃ ┃ ┗ 📜Header.tsx
┃ ┃ ┣ 📂mypage
┃ ┃ ┃ ┣ 📜MyInfo.tsx
┃ ┃ ┃ ┣ 📜MyPostsList.tsx
┃ ┃ ┃ ┣ 📜Nickname.tsx
┃ ┃ ┃ ┣ 📜Post.tsx
┃ ┃ ┃ ┣ 📜PostsTable.tsx
┃ ┃ ┃ ┗ 📜Selected.tsx
┃ ┃ ┣ 📂ui
┃ ┃ ┃ ┣ 📜accordion.tsx
┃ ┃ ┃ ┣ 📜button.tsx
┃ ┃ ┃ ┗ 📜input.tsx
┃ ┃ ┣ 📜LoadingSpinner.tsx
┃ ┃ ┗ 📜SearchBar.tsx
┃ ┣ 📂hooks
┃ ┃ ┣ 📜useGetMatchIdQuery.ts
┃ ┃ ┣ 📜useGetPlayersNameQuery.ts
┃ ┃ ┣ 📜useGetPositionQuery.ts
┃ ┃ ┗ 📜useMatchDetailDataQuery.ts
┃ ┣ 📂lib
┃ ┃ ┗ 📜utils.ts
┃ ┣ 📂provider
┃ ┃ ┗ 📜QueryProvider.tsx
┃ ┣ 📂types
┃ ┃ ┣ 📂detail
┃ ┃ ┣ 📜matchType.ts
┃ ┃ ┣ 📜maxDivisionType.ts
┃ ┃ ┗ 📜userInfoType.ts
┃ ┣ 📂utils
┃ ┃ ┣ 📂detail
┃ ┃ ┃ ┗ 📜datailApi.ts
┃ ┃ ┣ 📂mypage
┃ ┃ ┃ ┣ 📜api.ts
┃ ┃ ┃ ┗ 📜type.ts
┃ ┃ ┣ 📂services
┃ ┃ ┃ ┣ 📜matchDetailDataConverter.ts
┃ ┃ ┃ ┗ 📜utcTimeToKstConverter.ts
┃ ┃ ┣ 📂supabase
┃ ┃ ┃ ┣ 📜client.ts
┃ ┃ ┃ ┣ 📜middleware.ts
┃ ┃ ┃ ┗ 📜server.ts
┃ ┃ ┣ 📜client-action.ts
┃ ┃ ┗ 📜server-action.ts
┃ ┣ 📜middleware.ts
┃ ┗ 📜userStore.ts
┣ 📜.env.local
┣ 📜.eslintrc.json
┣ 📜.gitignore
┣ 📜.prettierrc
┣ 📜components.json
┣ 📜database.types.ts
┣ 📜next-env.d.ts
┣ 📜next.config.mjs
┣ 📜package.json
┣ 📜postcss.config.mjs
┣ 📜pull_request_template.md
┣ 📜README.md
┣ 📜tailwind.config.ts
┣ 📜tsconfig.json
┗ 📜yarn.lock

🧩 주요 기능

image

1. 회원 가입 및 로그인

SUPABASE를 사용하여 회원가입과 로그인을 구현 후
ZUSTAND를 사용해 로그인 여부를 전역상태로 관리합니다.

1-1. 회원가입

image

1-2. 로그인

image
image

  • 로그인 시 헤더에서 유저 정보 확인

2. 검색

search

  • 닉네임 검색으로 전적을 검색할 수 있습니다.

3. 전적 확인

image
more

3-1-1. 유저 정보

image

  • 검색한 유저의 정보와 전적을 확인할 수 있습니다.

3-2-1. 매치 타입

image
image

  • 매치 타입에 맞는 전적을 확인할 수 있습니다.

3-3-1. 평점

image
image

  • 특정 매치에 따른 선수 정보가 화면에 랜더링 되며, 클릭 시 모달로 선수 정보를 확인할 수 있습니다.

open

3-3-2. 슈팅

image

  • 특정 매치의 슈팅 정보를 그래프로 확인할 수 있습니다.

3-3-3. 패스

image

  • 특정 매치의 패스 정보를 그래프로 확인할 수 있습니다.

3-3-4. 수비

image

  • 특정 매치의 수비 정보를 그래프로 확인할 수 있습니다.

4. 커뮤니티

4-1. 게시글 확인

image

  • 게시글 목록을 확인할 수 있습니다.

muhan345

  • 무한 스크롤을 통해 페이지 이동 없이 전체 게시물을 확인할 수 있습니다.

image

  • 상세 게시물을 확인할 수 있습니다.

4-2. 게시글 CRUD

image
TOAST UI EDITOR를 사용하여 글쓰기를 할 수 있습니다.

image
image
image

  • 게시글을 수정 할 수 있습니다.

5. 댓글

image

  • 댓글을 작성할 수 있습니다.

image
image

  • 댓글을 수정/삭제할 수 있습니다.

6. 마이페이지

image

  • 가입 시 입력한 닉네임이 NEXON OPEN API서버에 존재할 경우 해당 유저의 정보를 받아옵니다.
  • 로그인 후 작성한 게시물을 확인할 수 있습니다.

🚨 트러블 슈팅

1. 랜더링 오류

1-1. 더보기 버튼 클릭 시 로딩 UI가 보이며 페이지가 깜빡 거리는 현상이 발생

  • 기존 : loading.tsx를 통해 loading 상태일 때 loading UI를 보여줘야 함

1-2. 해결 방법

image


해결 : 한 페이지에서 관리하던 loading.tsxSuspense를 통해 로딩 UI를 보여줘야 하는 곳을 세분화,
전적 검색페이지는 예외로 useInfiniteQueryisLoading을 통해 로딩 UI를 넣어주어 매치타입이 변할 때만 로딩 UI가 보이도록 수정

2. TOAST UI Editor 오류

2-1. PostEditor 최상단에 "use client"를 선언하고 Write 페이지로 이동할 시 ReferenceError: navigator is not defined 에러가 발생

기존 : TOAST UI Editor Form이 나타나야 한다.

  • app/community/write/page.tsx - CommunityWritepage (서버 컴포넌트)
    components/community/PostEditor.tsx - (클라이언트 컴포넌트)
    CommunityWritePage 컴포넌트안에 PostEditor 컴포넌트가 있고 PostEditor에서
    Toast ui Editor 라이브러리를 사용하려고 하는 구조이다.

2-2. 해결 방법

image


해결 : dynamic 함수를 사용해서 컴포넌트를 ssr에서 제외 시켜 서버사이드에서 빌드를 무시하게 하였다. const PostEditor = dynamic(() => import('@/components/community/PostEditor'), { ssr: false });


자체 평가 의견

이름점수피드백
권다정8/10팀프로젝트 하면서 CRUD를 온전히 맡아본 적이 없었는데 이번에 맡을 수 있어서 좋았고, 제가 두려워했던 것 중 하나인 zustand도 직접 사용해볼 수 있어서 대체적으로 만족스럽습니다.
신한별7/10좀 더 깔끔한 코드를 작성하고 싶었는데 그러지 못했고, 아직 Next.js에 대한 이해도가 부족해서 장점을 활용하지 못한 것 같아 아쉽습니다!
(ex. 모달을 parallel routes & Intercepting Routes로 구현). 하지만 생각했던 것들은 구현해서 만족스럽습니다.
이기성8/10Next.js의 렌더링 기법을 더 다양하게 사용해보고 싶었는데 그러지 못해서 아쉬운 점이 살짝 남았습니다.
이석원7/10구상했던 기능들을 모두 구현했다는 점에서 많이 만족스럽지만, 서벅액션과 라우팅 핸들러에 대한 이해와 경험이 부족해서 아쉬움이 남는 것 같습니다.
정지형5/10"일단" 기능이 되긴 하기에 50점을 주었고, 코드 간결화가 안되어 있으며 API 함수도 제대로 관리하지 못하고 있습니다.

profile
프론트가 하고싶어요

0개의 댓글