Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[7주차] TIG 미션 제출합니다. #6

Open
wants to merge 64 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
c501141
[Docs] ; 기본 프로젝트 설정 및 리드미 작성
Programming-Seungwan Jun 17, 2024
19180ae
[Feat] : 프로젝트 디렉터리 구조 확정 및 파트 분배 by 주석
Programming-Seungwan Jun 22, 2024
a799e0a
style: theme 색상 설정
songess Jun 23, 2024
cee9e0c
[Feat]: Header 컴포넌트 추가
songess Jun 23, 2024
d0af153
[Feat]: layout 설정
songess Jun 23, 2024
837238a
Merge pull request #1 from ceos-tig/feat/header
Programming-Seungwan Jun 23, 2024
b89d2bc
[FIX]: Header position 설정
songess Jun 23, 2024
601a878
[FEAT]: landing 페이지 구현
songess Jun 23, 2024
0828c27
[CHORE]: @svgr/webpack 설치
songess Jun 23, 2024
f365b2a
[FEAT]: 파트장 투표페이지 구현
songess Jun 23, 2024
d3e8b26
[STYLE]: globalCss 설정
songess Jun 23, 2024
e42d610
[FIX]: Header 수정
songess Jun 23, 2024
5aab25b
[FEAT]: be-result 페이지 구현
songess Jun 23, 2024
67ad4b3
[FEAT]: fe-result 페이지 구현
songess Jun 23, 2024
6f95f47
[FIX]: 랜딩페이지 카드 크기수정
songess Jun 23, 2024
40149d8
Merge pull request #2 from ceos-tig/feat/voteResult
Programming-Seungwan Jun 24, 2024
eefe357
Feat : login 페이지 기본 퍼블리싱 작업
Programming-Seungwan Jun 24, 2024
08a8c3a
[Feat] : make signup UI
Programming-Seungwan Jun 24, 2024
8ac126c
[Feat] : 로그인 & 회원가입 데이터 전송 로직 작성
Programming-Seungwan Jun 24, 2024
e00e5be
Fix : revise gitignore
Programming-Seungwan Jun 24, 2024
2f806f5
Merge pull request #3 from ceos-tig/feat/login-signup
songess Jun 24, 2024
3096d69
[FIX]: 명세서에 맞게 수정
songess Jun 24, 2024
293dd7a
[FEAT]: fetchapi 구현
songess Jun 25, 2024
267d432
[FEAT]: 파트장투표페이지에서 api 호출 러프하게 구현
songess Jun 25, 2024
fd9beae
[Feat] : 회원 가입 및 로그인에 대한 api 요청을 nextJS api를 이용하여 프록시
Programming-Seungwan Jun 25, 2024
e5cefca
[Feat] : Team 투표 및 결과 UI 퍼블리싱
Programming-Seungwan Jun 25, 2024
84ee1c1
[Feat] : team 투표 페이지 cors 연결 이전까지 모든 작업 완료
Programming-Seungwan Jun 25, 2024
7a4d1c5
[Feat] : team result 페에지 상태 설정
Programming-Seungwan Jun 25, 2024
db7ec70
[Feat]: 로그인 요청 처리 완료
Programming-Seungwan Jun 25, 2024
1482fb1
[Fix] : signup 회원가입 로직 수정 및 팀 투표 결과 반영 후 투표 결과 페이지로 이동
Programming-Seungwan Jun 25, 2024
c8574b7
[Fix] : 팀 투표 엣지 케이스 수정
Programming-Seungwan Jun 25, 2024
7794e54
Merge pull request #5 from ceos-tig/feat/auth-team
songess Jun 26, 2024
94e4d77
[Feat]: 로고 추가
songess Jun 26, 2024
697dc02
[Style]: header 스타일 변경
songess Jun 26, 2024
314b6f0
[Feat]: fe/be 페이지 api 및 로직 구현
songess Jun 26, 2024
1aec400
[Style]: landing 페이지 스타일 변경
songess Jun 26, 2024
4224b8a
[Feat]: be/fe-result 페이지 api 및 로직 구현
songess Jun 26, 2024
2bbef3a
[Fix]: be페이지 라우팅 수정
songess Jun 26, 2024
40bad2f
Merge pull request #6 from ceos-tig/feat/eunsu
Programming-Seungwan Jun 26, 2024
6d68795
vote 페이지 모달 구현
songess Jun 26, 2024
e7d593b
[Feat]: login 모달 구현
songess Jun 26, 2024
24a9dca
[ReFactor]: 로그인페이지에서 랜딩페이지로 가는 버튼 추가
songess Jun 26, 2024
8bade22
[Chore]: 프리텐다드 폰트 설정
songess Jun 26, 2024
d2dffea
Merge pull request #7 from ceos-tig/feat/eunsu
Programming-Seungwan Jun 26, 2024
1588ab7
[Docs] : readme.md 작성
Programming-Seungwan Jun 26, 2024
175be1d
[Build] : http와 https 간의 mixed content 문제 해결 시도 1
Programming-Seungwan Jun 26, 2024
3557070
[Fix] : make not-found component in root directory
Programming-Seungwan Jun 26, 2024
2b1dbbe
[Fix] : 초기 voted idx NULL이 아니라 ''로 수정
Programming-Seungwan Jun 26, 2024
870fb12
[Fix] : 배포 환경에서 팀 투표 페이지에서 본인팀 투표 금지 모달 뒤에 다시 클릭하면 잠시 선택되는 현상 해결 시도
Programming-Seungwan Jun 27, 2024
17a553f
[Fix] : unexpected modal showing 해결 시도 1
Programming-Seungwan Jun 27, 2024
0f7f03b
[Fix] : 모달 창 닫기 할때 event 버블링 막아줌
Programming-Seungwan Jun 27, 2024
b70cb90
[Refactor]: 파트세팅 값 수정
songess Jun 27, 2024
bc191d8
[Refactor]: 필요없는 코드 제거
songess Jun 27, 2024
deab8c7
[Feat]: 랭킹함수 유틸함수로 작성 및 team-result페이지에도 적용
songess Jun 27, 2024
f01acd2
[Style]: 스타일 수정:
songess Jun 27, 2024
4e025f8
Merge pull request #8 from ceos-tig/feat/eunsu
songess Jun 27, 2024
81f86cc
[Feat]: 투표완료 모달페이지 제작중
songess Jun 27, 2024
385536c
[Feat]: fe/be 페이지 로딩 스피너 구현
songess Jun 27, 2024
03f4492
[Fix]: 로그인페이지 뒤로가기 위치조정
songess Jun 27, 2024
909eef8
[Refactor]: 투표완료 모달제거
songess Jun 27, 2024
d217012
Merge pull request #9 from ceos-tig/feat/eunsu
Programming-Seungwan Jun 27, 2024
d9b9009
[Fix] : 로그인된 사용자가 투표 페이지에 접근할 때 spinning bar만 나타나는 현상 해결
Programming-Seungwan Jun 27, 2024
dd1b2b0
[feat]: result페이지 로딩화면 추가
songess Jun 27, 2024
cb11260
[Fix] : team result 페이지도 첫 데이터를 가져올 시에는 spinning UI 렌더링
Programming-Seungwan Jun 27, 2024
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
3 changes: 3 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
37 changes: 37 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local
.env

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"singleQuote": true
}
46 changes: 46 additions & 0 deletions Assignment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# react-vote-19th

## **서론**

안녕하세요! 프론트엔드 운영진 배성준입니다 👾 어느덧 마지막 스터디입니다.

이번 스터디는 각 팀의 백엔드 팀원들과 함께 진행하는 **합동 과제**입니다.
모던 웹에서 REST API가 주류로 떠오름에 따라 프론트엔드와 백엔드의 구분이 이전보다 명확해졌습니다. 주로 백엔드는 API 서버의 역할을, 프론트엔드는 이를 이용해 사용자에게 UI를 제공하는 역할로 웹이 분화되었습니다. 그 말은 곧, API 없이는 사용자에게 의미있는 서비스를 제공하기 힘들어진다는 것이겠죠. 여러분께서도 차후 팀 프로젝트를 진행하시면서 백엔드 개발자들과 API에 대해 소통할 일이 많아질 것입니다.

따라서 이번 과제는 백엔드 개발자들이 전달해준 `API`를 사용해서 구현해보는 미션입니다. 투표 서비스를 개발해 보는 것인데요. 백엔드 개발자와 함께 클라이언트 사이드에서 API를 조금 더 효율적으로 사용할 수 있는 방법에 대해 고민해 보고, 논의해 보는 시간을 가져 보시기 바랍니다.

이번 미션도 화이팅입니다! 🔥

## **미션**

### **미션 목표**

- REST API를 통한 서버와의 통신 방법을 이해합니다.
- async/await, Promise등 JavaScript의 비동기 처리를 이해합니다.
- API 문서를 통해 백엔드 개발자와 소통하는 방법을 익힙니다.
- 팀 내의 프론트엔드 개발자와 적절한 역할 분담을 통해 개발 효율을 높이는 방법에 대해 고민합니다.


### **기한**

2024년 6월 26일 수요일

### **필수 요건**

- UI/UX에 대한 감각을 최대한 발휘해 디자인을 적용해 봅니다.
- `HTTPS`를 통해 서버와 통신합니다.
- 외의 사항은 [가이드 문서](https://sungjoonbae.notion.site/FE-BE-2d7ad673b78c4f1b8389708762627b7f)를 참고해주세요.

### **선택 사항**

- API Fetch는 어떤 방식을 사용하든 무방합니다 (Fetch API, axios 등)
- `Promise.then()` 보단 `async/await`를 사용해 보세요. 더 최신 스펙이랍니다.

## **링크 및 참고자료**

- [리액트 API 연동의 기본](https://react.vlpt.us/integrate-api/01-basic.html)
- [자바스크립트 - 동기(Synchronous)? 비동기(asynchronous)?](https://ljtaek2.tistory.com/142)
- [async와 await, 비동기를 동기코드 처럼](https://kamang-it.tistory.com/entry/JavaScript11async%EC%99%80-await-%EB%B9%84%EB%8F%99%EA%B8%B0%EB%A5%BC-%EB%8F%99%EA%B8%B0%EC%BD%94%EB%93%9C-%EC%B2%98%EB%9F%BC)
- [REST API 제대로 알고 사용하기](https://meetup.toast.com/posts/92)
- [axios란? (feat. Fetch API)](https://velog.io/@shin6403/React-axios%EB%9E%80-feat.-Fetch-API)
- [Postman, 어렵지 않게 사용하기](https://gngsn.tistory.com/26)
76 changes: 47 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,64 @@
# react-vote-19th
# TEAM TIG vote 과제 frontend by 은수, 승완

## **서론**
## 배포링크

안녕하세요! 프론트엔드 운영진 배성준입니다 👾 어느덧 마지막 스터디입니다.
[배포 링크]()

이번 스터디는 각 팀의 백엔드 팀원들과 함께 진행하는 **합동 과제**입니다.
모던 웹에서 REST API가 주류로 떠오름에 따라 프론트엔드와 백엔드의 구분이 이전보다 명확해졌습니다. 주로 백엔드는 API 서버의 역할을, 프론트엔드는 이를 이용해 사용자에게 UI를 제공하는 역할로 웹이 분화되었습니다. 그 말은 곧, API 없이는 사용자에게 의미있는 서비스를 제공하기 힘들어진다는 것이겠죠. 여러분께서도 차후 팀 프로젝트를 진행하시면서 백엔드 개발자들과 API에 대해 소통할 일이 많아질 것입니다.
## 기술 스택

따라서 이번 과제는 백엔드 개발자들이 전달해준 `API`를 사용해서 구현해보는 미션입니다. 투표 서비스를 개발해 보는 것인데요. 백엔드 개발자와 함께 클라이언트 사이드에서 API를 조금 더 효율적으로 사용할 수 있는 방법에 대해 고민해 보고, 논의해 보는 시간을 가져 보시기 바랍니다.
- nextJS
- tailwindCSS
- typescript
- jwt

이번 미션도 화이팅입니다! 🔥
## 디자인

## **미션**
[피그마 링크](https://www.figma.com/design/pFB3tx3oUGt6JWJKa2TjXL/CEOS-TIG-VOTE?node-id=0-1&t=8Z0hMfBO3U86fYel-0)

### **미션 목표**
## 페이지 별 기능 ⚒️

- REST API를 통한 서버와의 통신 방법을 이해합니다.
- async/await, Promise등 JavaScript의 비동기 처리를 이해합니다.
- API 문서를 통해 백엔드 개발자와 소통하는 방법을 익힙니다.
- 팀 내의 프론트엔드 개발자와 적절한 역할 분담을 통해 개발 효율을 높이는 방법에 대해 고민합니다.
- 반응형으로 구현
- parallel routes & intercepting route를 사용한 모달 구현

1. 회원 가입 페이지
- 아이디 & 이메일의 중복 불가
2. 로그인 페이지
- 로그인 성공 시, BE로부터 jwt 반환 & 추후 로그인 사용자 요청은 jwt를 매번 전송(쿠키 같은 방식 이용)
- 로그아웃 기능
3. 투표 페이지
- 파트장 투표 : 본인 파트의 파트장만 투표 가능
- 공통
- 로그인 한 사용자만 투표 가능 / 로그인 안한 사용자도 조회 가능 but 투표는 불가능
- 본인 혹은 본인이 속한 팀에 투표 불가
- 투표는 한 번만 가능
4. 투표 결과 페이지
- 로그인 안한 사용자도 조회 가능
- 투표 수 동일 시 공동순위

### **기한**
## 주요 포인트 📌

2024년 6월 26일 수요일
### 인증

### **필수 요건**
로그인 기능이 필요한 웹 페이지에는 인증을 어떻게 할 것인가?의 논쟁이 있다고 생각합니다. 제가 생각하는 인증의 구현 방식은 크게 2가지입니다<br>

- UI/UX에 대한 감각을 최대한 발휘해 디자인을 적용해 봅니다.
- `HTTPS`를 통해 서버와 통신합니다.
- 외의 사항은 [가이드 문서](https://sungjoonbae.notion.site/FE-BE-2d7ad673b78c4f1b8389708762627b7f)를 참고해주세요.
1. 세션 기반의 인증 방식 : 백엔드 서버는 로그인 정보를 기반으로 세션을 생성하고, 이를 브라우저에게 반환합니다. 백엔드 서버는 이를 데이터베이스에 넣어두거나, 자체 메모리에 올려두는 방식으로 추후 사용자의 인증 요청을 진행합니다. 이는 상태성을 지니는 것이므로, 무상태성을 지녀야 수평 확장을 할 수 있는 백엔드 시스템을 구축하기에 불리한 측면이 있습니다.
2. jwt 토큰 기반의 인증 방식 : 서버는 비밀키만을 보유하고, 프론트엔드(브라우저)에서 jwt를 보관하고 있다가 전송하면 이를 해석하여 인증을 시도합니다. 이는 백엔드 시스템을 stateless 하게 설계할 수 있다는 장점이 있습니다.<br><br>

### **선택 사항**
### CORS

- API Fetch는 어떤 방식을 사용하든 무방합니다 (Fetch API, axios 등)
- `Promise.then()` 보단 `async/await`를 사용해 보세요. 더 최신 스펙이랍니다.
CORS 정책은 브라우저 자체 단에서 출처(프로토콜 + 도메인 주소 + 포트번호)가 다를 경우 요청을 차단하는 개념입니다.

## **링크 및 참고자료**
1. preflight 요청 : option 메서드로 전송되며, 백엔드 서버에서 `Access-Control-Allow-Origin` 헤더에 프론트엔드의 주소가 포함되어 있어야 합니다.
2. jwt와 같은 토큰 정보를 헤더에 싣어보낼 때, `Access-Control-Expose-Headers` 헤더에 해당 정보를 보내는 헤더명을 명시해주면 프론트엔드에서 Javascript로 접근할 수 있습니다.

- [리액트 API 연동의 기본](https://react.vlpt.us/integrate-api/01-basic.html)
- [자바스크립트 - 동기(Synchronous)? 비동기(asynchronous)?](https://ljtaek2.tistory.com/142)
- [async와 await, 비동기를 동기코드 처럼](https://kamang-it.tistory.com/entry/JavaScript11async%EC%99%80-await-%EB%B9%84%EB%8F%99%EA%B8%B0%EB%A5%BC-%EB%8F%99%EA%B8%B0%EC%BD%94%EB%93%9C-%EC%B2%98%EB%9F%BC)
- [REST API 제대로 알고 사용하기](https://meetup.toast.com/posts/92)
- [axios란? (feat. Fetch API)](https://velog.io/@shin6403/React-axios%EB%9E%80-feat.-Fetch-API)
- [Postman, 어렵지 않게 사용하기](https://gngsn.tistory.com/26)
### tailwindCSS와 nextJS

nextJS는 서버 사이드 렌더링을 지원하는 reactJS 기반의 프레임워크입니다. 기존의 `styled-components` 같은 라이브러리를 이용하여 스타일링을 진행하면, 내부적으로 reactJS의 상태 개념을 이용하여 만들어낸 hash 값을 클래스명으로 이용하기 때문에 로직이 클라이언트 단에서 이루어집니다. 만약 Javascript 실행 속도가 느린 환경이라면 사용자에게는 스타일링이 적용되지 않은, 단순 html 즉 layout만 보이는 순간이 존재할 수도 있습니다. 따라서 전처리기, 후처리기의 원리를 차용한 `tailwindCSS`를 이용하면 좀 더 편하지 않을까 싶습니다.

## 느낀점 🧐

1. 은수
그동안 백엔드 없이 구현했기 때문에 겪을 수 없던 CORS, 토큰관련 문제들을 경험해볼 수 있어서 좋았습니다. 모달을 만들 때 리액트에서 처럼 createPortal이 아닌 parallel & intercepting routes를 사용해 만들어 모달이 라우팅되는 것처럼 구현했는데 익숙치 않아서 그런지 더 번거로운 느낌이 들어 빨리 익숙해지고 싶다는 생각이 들었습니다. 쿠키를 사용하는 것, 중복된 코드들에 대한 리팩토링을 하지 못한 아쉬움이 남습니다. 본격적으로 프로젝트를 시작하게 되면 처음부터 재사용성을 고려한 코드를 작성해야겠다는 다짐을 했습니다.

2. 승완
지난 과제를 진행할 때에는 어떤 컴포넌트는 서버 컴포넌트로 만들 것인지를 많이 고민하면서 했는데, 이번에는 백엔드와의 cors 이슈를 해결하느라 이에 대해 다소 소홀했던 것 같습니다. 또한 사실 jwt를 쿠키에 저장해두고, 매번 자동으로 브라우저의 동작 원리에 따라 jwt를 쿠키에 담아 백엔드 단으로 전송하는 로직이 좀 더 바람직한데, 이를 하지 못한 것 같아 다소 아쉽습니다. accessToken과 refreshToken을 각각 클라이언트에서 어떻게 저장할지 고려해보면 더 좋을 것 같습니다.
61 changes: 61 additions & 0 deletions next.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (config) => {
config.module.rules.push({
test: /\.svg$/,
use: ['@svgr/webpack'],
});

return config;
},
async rewrites() {
return [
{
source: '/api/vote/team',
destination: `${process.env.NEXT_PUBLIC_BACKEND_DOMAIN}/vote/team`,
},
{
source: '/api/vote/team-vote',
destination: `${process.env.NEXT_PUBLIC_BACKEND_DOMAIN}/vote/team-vote`,
},
{
source: '/api/vote/fe',
destination: `${process.env.NEXT_PUBLIC_BACKEND_DOMAIN}/vote/fe`,
},
{
source: '/api/vote/fe-vote',
destination: `${process.env.NEXT_PUBLIC_BACKEND_DOMAIN}/vote/fe-vote`,
},
{
source: '/api/vote/be',
destination: `${process.env.NEXT_PUBLIC_BACKEND_DOMAIN}/vote/be`,
},
{
source: '/api/vote/be-vote',
destination: `${process.env.NEXT_PUBLIC_BACKEND_DOMAIN}/vote/be-vote`,
},
{
source: '/api/vote/team-result',
destination: `${process.env.NEXT_PUBLIC_BACKEND_DOMAIN}/vote/team-result`,
},
{
source: '/api/vote/fe-result',
destination: `${process.env.NEXT_PUBLIC_BACKEND_DOMAIN}/vote/fe-result`,
},
{
source: '/api/vote/be-result',
destination: `${process.env.NEXT_PUBLIC_BACKEND_DOMAIN}/vote/be-result`,
},
{
source: '/api/user/signup',
destination: `${process.env.NEXT_PUBLIC_BACKEND_DOMAIN}/api/user/signup`,
},
{
source: '/api/user/login',
destination: `${process.env.NEXT_PUBLIC_BACKEND_DOMAIN}/api/user/login`,
},
];
},
};

export default nextConfig;
Loading