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주차] SNIFF 미션 제출합니다. #3

Open
wants to merge 75 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
8712e4d
init: create next app
oooppq Nov 20, 2023
d653601
init: 배포 자동화 설정
oooppq Nov 20, 2023
03439ad
init: 의존성 추가
oooppq Nov 22, 2023
3c6b4d6
init: 기본 컴포넌트 정리
oooppq Nov 22, 2023
31a3550
init: 필수적인 컴포넌트 구성
oooppq Nov 22, 2023
d6aeedf
style: nav bar 스타일 적용
oooppq Dec 18, 2023
e4aff6c
chore: ceos indigo color tailwind에 등록
oooppq Dec 18, 2023
5a24dac
refactor: nav bar 디자인 반응형으로 변경 및 이미지 사용방식 변경
oooppq Dec 18, 2023
a6f3ee9
style: 홈화면 스타일 적용
oooppq Dec 19, 2023
93090a7
chore: nav bar height 고정
oooppq Dec 19, 2023
dbcd659
chore: hovering button text weight semibold 설정
oooppq Dec 19, 2023
bc45614
feat: navbar 라우팅 설정
oooppq Dec 19, 2023
2eda40e
chore: pr template 추가
oooppq Dec 19, 2023
8abd85e
Merge pull request #1 from oooppq/feature/home
oooppq Dec 19, 2023
8154eae
feat: 로그인/회원가입시 navbar 보이지 않도록 함
oooppq Dec 19, 2023
03a34f4
style: 회원가입 디자인 일부 적용 완료
oooppq Dec 20, 2023
d219b8c
style: 회원가입 기본 디자인 적용 완료
oooppq Dec 20, 2023
faa822e
style: 로그인 기본 디자인 적용 완료
oooppq Dec 20, 2023
3f38d11
refactor: authInput 속성 변경
oooppq Dec 20, 2023
1027993
feat: 로그인 로직 추가
oooppq Dec 20, 2023
d2f7c0c
feat: 유저 session 받아오는 api 구현
oooppq Dec 20, 2023
5bf8d77
feat: csr용 유저 session 커스텀 훅 구현
oooppq Dec 20, 2023
3136b80
feat: userInfo 타입 지정
oooppq Dec 20, 2023
272d6b5
feat: jwt token expiration 구현
oooppq Dec 20, 2023
04fc991
feat: 홈화면 로그인 여부에 따른 view 변화 적용
oooppq Dec 21, 2023
38b161f
feat: navbar 로그인 상태 view 적용
oooppq Dec 21, 2023
f5e47f4
feat: 로그아웃 기능 구현
oooppq Dec 21, 2023
14e6733
feat: 홈화면 로그인 여부에 따른 라우팅 차이 적용
oooppq Dec 21, 2023
8995d34
feat: middleware를 통해 페이지 진입시 로그인 여부 검증
oooppq Dec 21, 2023
6c2d7e3
style: 로그인/회원가입 input 디자인 조금 변경
oooppq Dec 21, 2023
a8a4812
feat: 로그인 페이지에 회원가입 버튼 추가
oooppq Dec 21, 2023
d2271a3
feat: 로그인 실패 관련 처리 구현
oooppq Dec 21, 2023
6310452
feat: 회원가입 입력값 검증 기능 구현
oooppq Dec 22, 2023
b68c9ea
feat: 회원가입 중복아이디 이메일 처리 추가
oooppq Dec 22, 2023
8fe9f47
feat: 회원가입 드롭타운 컴포넌트 구현
oooppq Dec 22, 2023
d7dc289
feat: 드롭다운 없애고 radio 박스로 변경
oooppq Dec 22, 2023
b423be9
feat: 파트/팀 선택 관련 기능 구현
oooppq Dec 22, 2023
c5a6179
chore: fetch 관련 사소한 타이핑들 수정
oooppq Dec 22, 2023
d0cb550
Merge pull request #2 from oooppq/feature/auth
oooppq Dec 22, 2023
46eee16
feature:partvote 초기 설정
flowerseok Dec 22, 2023
ff85849
feat: partvote 페이지 초기완성
flowerseok Dec 22, 2023
5636f54
feat: partvote 페이지 초기완성
flowerseok Dec 22, 2023
84809c6
feat: 데모데이투표화면 구성
flowerseok Dec 22, 2023
e6a822a
feat: 데모데이 투표화면 구성
flowerseok Dec 22, 2023
2ceff0e
chore: 자잘한 경로들 수정
flowerseok Dec 22, 2023
22b7969
style: css 수정
flowerseok Dec 23, 2023
208a8e3
style : css수정
flowerseok Dec 23, 2023
dfe2810
feat : api header추가
flowerseok Dec 23, 2023
83251ec
feat: api header추가
flowerseok Dec 23, 2023
31e30a6
chore: 자잘한 수정
flowerseok Dec 23, 2023
3a41cf2
chore: header 추가
flowerseok Dec 23, 2023
532fb4f
chore: 오타수정
flowerseok Dec 23, 2023
7243f29
Merge pull request #3 from flowerseok/feature/demovote
oooppq Dec 24, 2023
9613795
refactor: axios 삭제
oooppq Dec 24, 2023
115c21b
refactor: 투표 결과 server-side component로 변경
oooppq Dec 24, 2023
e8d3e7a
chore: 타이포 수정 및 네비게이션 설정
oooppq Dec 24, 2023
f143feb
feat: 투표 완료시 투표여부 flag 업데이트
oooppq Dec 24, 2023
27e105d
debug: 회원가입시 중복된 id/email 관련 오류 처리 에러 수정
oooppq Dec 24, 2023
7d4cbae
feat: middleware 수정
oooppq Dec 24, 2023
09de8d8
Merge pull request #4 from oooppq/chore
oooppq Dec 24, 2023
06c23ee
style: 투표/결과 페이지 디자인 수정
oooppq Dec 24, 2023
da3171a
Merge pull request #5 from oooppq/feature/vote
oooppq Dec 24, 2023
81e8465
hotfix: 파트장 투표결과 안내문구 삽입
oooppq Dec 24, 2023
7389a8f
hotfix: 백엔드 파트장 투표 안되는 오류 해결 및 투표하기 여러번 클릭 방지
oooppq Dec 24, 2023
b9c00b8
hotfix: 로그인 한 사람은 모두 투표 결과 볼 수 있게 수정
oooppq Dec 24, 2023
a3265b3
hotfix: 모든 fetch 요청 no-cache로 변경
oooppq Dec 24, 2023
0d5b49e
hotfix: 파트별 결과 볼 수 있도록 구현
oooppq Dec 24, 2023
9f53be2
hotfix: 유저 이름 길면 navbar 줄바꿈 일어나는 문제 해결
oooppq Dec 24, 2023
937f1c3
hotfix: 로그아웃 요청이 제대로 전달 안돼도 일단 로그아웃되도록 설정
oooppq Dec 24, 2023
98f2e81
hotfix: 로그아웃 요청이 제대로 전달 안돼도 일단 로그아웃되고, 새로고침 되도록 설정
oooppq Dec 24, 2023
7449000
hotfix: 로그아웃 설정 마무리
oooppq Dec 24, 2023
5d68522
hotfix: 회원가입 화면 window가 아주 커졌을 때 패딩이 너무 넓어지는 문제 수정
oooppq Dec 24, 2023
1b47903
hotfix: 회원가입 에러가 제대로 처리되지 않는 문제 수정
oooppq Dec 24, 2023
3324914
hotfix: token exp 타임이 지나서 cookie를 삭제할 때의 error 해결
oooppq Dec 29, 2023
aeb66c8
hotfix: 아이디 검증 정규표현식 수정
oooppq Dec 29, 2023
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
6 changes: 6 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": ["next/core-web-vitals", "prettier"],
"parserOptions": {
"project": "./tsconfig.json"
}
}
7 changes: 7 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
## PR 요약

> summary

## 변경된 점

> changes
30 changes: 30 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: git push into another repo to deploy to vercel

on:
push:
branches: [main]

jobs:
build:
runs-on: ubuntu-latest
container: pandoc/latex
steps:
- uses: actions/checkout@v2
- name: Install mustache (to update the date)
run: apk add ruby && gem install mustache
- name: creates output
run: sh ./build.sh
- name: Pushes to another repository
id: push_directory
uses: cpina/github-action-push-to-another-repository@main
env:
API_TOKEN_GITHUB: ${{ secrets.DAEGYUN_GITHUB_SECRET }}
with:
source-directory: 'output'
destination-github-username: oooppq
destination-repository-name: react-vote-18th
user-email: ${{ secrets.DAEGYUN_GITHUB_EMAIL }}
commit-message: ${{ github.event.commits[0].message }}
target-branch: main
- name: Test get variable exported by push-to-another-repository
run: echo $DESTINATION_CLONED_DIRECTORY
36 changes: 36 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# 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

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
48 changes: 48 additions & 0 deletions app/api/login/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { TUserInfo } from '@/types';
import { cookies } from 'next/headers';

const EXP_LIMIT = 1000 * 60 * 60 * 24;

export async function POST(request: Request) {
const body = await request.json();
const res = await fetch(`${process.env.NEXT_PUBLIC_SERVER_URL}/users/login`, {
headers: { 'Content-Type': 'application/json' },
method: 'POST',
body: JSON.stringify({ loginId: body.loginId, password: body.password }),
cache: 'no-cache',
});

if (res.ok) {
const authInfo = await res.json();
cookies().set(
'user_info',
JSON.stringify({
...authInfo,
expTime: new Date().getTime() + EXP_LIMIT,
}),
{
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'strict',
maxAge: EXP_LIMIT,
path: '/',
}
Comment on lines +17 to +29

Choose a reason for hiding this comment

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

저희는 localStorage에 토큰 저장해서 처리했는데 이렇게 쿠키 쓸 수도 있군요! 보안 상 더 안정적일 것 같네요 ~!

Copy link

Choose a reason for hiding this comment

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

쿠키로 관리하는 법 배워갑니다!

);

return new Response('Authorized', {
status: 200,
});
} else if (res.status === 404) {
return new Response('Wrong ID', {
status: 404,
});
} else if (res.status === 401) {
return new Response('Wrong Password', {
status: 401,
});
} else {
Comment on lines +32 to +43

Choose a reason for hiding this comment

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

Next.js로 서버 역할까지 구현하신 점이 멋있어요~~

return new Response('Login Failed', {
status: 403,
});
}
}
25 changes: 25 additions & 0 deletions app/api/logout/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { cookies } from 'next/headers';

export async function POST(request: Request) {
const clientReqHeaders = request.headers;

const serverReqHeaders = new Headers();
serverReqHeaders.set('AUTHORIZATION', clientReqHeaders.get('AUTHORIZATION')!);
const res = await fetch(
`${process.env.NEXT_PUBLIC_SERVER_URL}/users/logout`,
{
method: 'POST',
headers: serverReqHeaders,
cache: 'no-cache',
}
);
cookies().delete('user_info');
if (res.ok) {
return new Response('Logout Success', {
status: 200,
});
} else
return new Response('Logout Failed', {
status: 400,
});
}
17 changes: 17 additions & 0 deletions app/api/session/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { TUserInfo } from '@/types';
import { cookies } from 'next/headers';
import { NextResponse } from 'next/server';

export async function GET() {
const cookieStore = cookies();
const stored = cookieStore.get('user_info');
if (!stored) {
return NextResponse.json(null);
}
const userInfo: TUserInfo = JSON.parse(stored.value);
if (userInfo.expTime < new Date().getTime()) {
cookieStore.delete('user_info');
return NextResponse.json(null);
}
return NextResponse.json(userInfo);
}
71 changes: 71 additions & 0 deletions app/api/v1/demoday/votes/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { getSession } from '@/utils/auth';
import { cookies } from 'next/headers';

export async function POST(req: Request) {
const userInfo = await getSession();

try {
const body = await req.json();

const token = req.headers.get('AUTHORIZATION');
if (!token) {
throw new Error('Invalid token');
}
const res = await fetch(
`${process.env.NEXT_PUBLIC_SERVER_URL}/demoday/votes`,
{
headers: {
'Content-Type': 'application/json',
AUTHORIZATION: token,
},
method: 'POST',
body: JSON.stringify({ teamName: body.teamName }),
cache: 'no-cache',
}
);

if (res.ok) {
cookies().set(
'user_info',
JSON.stringify({
...userInfo,
teamVoted: true,
})
);
return new Response(
JSON.stringify({ message: 'Vote registered successfully' }),
{
status: 201,
headers: {
'Content-Type': 'application/json',
},
}
);
} else if (res.status === 403) {
return new Response(
JSON.stringify({ message: 'Token expired or invalid' }),
{
status: 403,
headers: {
'Content-Type': 'application/json',
},
}
);
} else {
const errorResponse = await res.json();
return new Response(JSON.stringify(errorResponse), {
status: res.status,
headers: {
'Content-Type': 'application/json',
},
});
}
} catch (error) {
return new Response(JSON.stringify({ message: 'An error occurred' }), {
status: 500,
headers: {
'Content-Type': 'application/json',
},
});
}
}
68 changes: 68 additions & 0 deletions app/api/v1/part-leader/votes/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { getSession } from '@/utils/auth';
import { cookies } from 'next/headers';

export async function POST(req: Request) {
const userInfo = await getSession();
const part = userInfo?.part;
try {
const body = await req.json();
const token = req.headers.get('AUTHORIZATION');
if (!token) {
throw new Error('Invalid token');
}

const res = await fetch(
`${process.env.NEXT_PUBLIC_SERVER_URL}/part-leader/votes?part=${part}`,
{
headers: {
'Content-Type': 'application/json',
AUTHORIZATION: token,
},
method: 'POST',
body: JSON.stringify({ id: body.id }),
cache: 'no-cache',
}
);

if (res.ok) {
cookies().set(
'user_info',
JSON.stringify({
...userInfo,
candidateVoted: true,
})
);
return new Response(
JSON.stringify({ message: 'Vote registered successfully' }),
{
status: 200,
headers: {
'Content-Type': 'application/json',
},
}
);
} else if (res.status === 403) {
return new Response(JSON.stringify({ message: 'Token expired' }), {
status: 403,
headers: {
'Content-Type': 'application/json',
},
});
} else {
const errorResponse = await res.json();
return new Response(JSON.stringify(errorResponse), {
status: res.status,
headers: {
'Content-Type': 'application/json',
},
});
}
} catch (error) {
return new Response(JSON.stringify({ message: 'An error occurred' }), {
status: 409,
headers: {
'Content-Type': 'application/json',
},
});
}
}
Loading