Skip to content

[하신혜] Sprint 9#132

Merged
orlein merged 7 commits intocodeit-sprint-fullstack:next-하신혜from
Aventurine26:next-하신혜-sprint9
Dec 25, 2024

Hidden character warning

The head ref may contain hidden characters: "next-\ud558\uc2e0\ud61c-sprint9"
Merged

[하신혜] Sprint 9#132
orlein merged 7 commits intocodeit-sprint-fullstack:next-하신혜from
Aventurine26:next-하신혜-sprint9

Conversation

@Aventurine26
Copy link
Collaborator

@Aventurine26 Aventurine26 commented Dec 23, 2024

요구사항

기본 요구사항

공통

로그인/회원가입 페이지

  • JavaScript로 구현한 로그인/회원가입 페이지를 React.js 혹은 Next.js로 마이그레이션해 주세요.

로그인 페이지

  • "회원 가입하기"를 클릭하면 회원가입 페이지로 이동해 주세요.
  • 로그인 실패하는 경우, 이메일 input 아래에 "이메일을 확인해 주세요.", 비밀번호 input 아래에 "비밀번호를 확인해 주세요." 에러 메시지를 표시해 주세요.
  • 로그인 버튼이 활성화된 후, 로그인 버튼 클릭 또는 Enter키 입력으로 로그인 실행합니다.
  • "/auth/signIn"으로 POST 요청해서 성공 응답을 받으면 중고 마켓 페이지로 이동합니다. 참고로 JWT로 구현되어 있습니다.
  • 실패할 경우, 실패 메시지를 모달을 통해 표시합니다.

회원가입 페이지

  • "회원 가입하기"를 클릭하면 '/signin'페이지로 이동합니다.
  • 회원가입 버튼 클릭 또는 Enter키 입력으로 회원가입을 실행합니다.
  • 비밀번호 input과 비밀번호 확인 ihnput의 값이 다른 경우, 비밀번호 확인 input 아래에 "비밀번호가 일치하지 않아요." 에러 메시지를 표시해 주세요.
  • 버튼이 활성화된 후, 회원가입은 "/auth/signUp" POST 요청해서 진행합니다. 참고로 JWT로 구현되어 있습니다.
  • 회원가입 성공 응답을 받으면 중고마켓 페이지로 이동합니다.
  • 실패할 경우, 실패 메시지를 모달을 통해 표시합니다.

로그인, 회원가입 페이지 공통

  • 눈 모양 아이콘 클릭 시 비밀번호의 문자열이 보이기도 하고, 가려집니다.
  • 비밀번호의 문자열이 가려질 때는 눈 모양 아이콘에는 사선이 그어져 있고, 비밀번호의 문자열이 보일 때는 사선이 없는 눈 모양 아이콘이 보입니다.
  • 소셜 로그인에 구글 아이콘 클릭 시 'https://www.google.com/', 카카오 아이콘 클릭 시 'https://www.kakaocorp.com/page'로 이동합니다.
  • 로그인/회원가입 시 성공 응답으로 받은 accessToken을 로컬 스토리지에 저장합니다.
  • 로그인/회원가입 페이지에 접근 시 로컬 스토리지에 accessToken이 있는 경우 '/items' 페이지로 이동합니다.

GNB

  • 상단 내비게이션 바에 프로필 영역은 인가된 경우, 유저 정보 API를 활용해 주세요.
  • 인가되지 않았을 경우 "로그인" 버튼이 보이게 해 주세요.

상품 상세 페이지

  • PC, Tablet, Mobile 디자인에 해당하는 상품 상세 페이지를 만들어 주세요.
  • 상품 상세 페이지 url path는 "/items/{itemId)"로 설정하세요.
  • '목록으로 돌아가기' 버튼 클릭 시 중고마켓 페이지 "/items"로 이동합니다.
  • 상품에 대한 댓글 조회도 가능합니다.
  • 상품 수정 및 삭제 기능을 API를 활용해 구현합니다. 이때, 인가된 사용자만 이용할 수 있도록 합니다
  • 상품 수정은 '/products/{productId}' PATCH을 사용합니다..
  • 상품 삭제는 '/products/{productId}' DELETE를 사용합니다.
  • 상품 상세 페이지 url path는 "/items/{itemId)"로 설정하세요.
  • 상품 삭제 전, 확인 모달을 띄워주세요.
  • 상품에 대한 좋아요 및 좋아요 취소 기능을 https://panda-market-api.vercel.app/docs에 명세된 '/products/{productId}/favorite' POST & DELETE 활용해 구현합니다. 이때 인가된 사용자만 좋아요 기능을 이용할 수 있도록 합니다.
  • 댓글 생성 및 삭제 기능을 API를 활용해 구현합니다. 이때, 인가된 사용자만 이용할 수 있도록 합니다
  • 댓글 수정은 https://panda-market-api.vercel.app/docs에 명세된 '/comments/{commentId}' PATCH을 사용합니다.
  • 댓글 삭제는 https://panda-market-api.vercel.app/docs에 명세된 '/comments/{commentId}' DELETE를 사용합니다.

심화 요구사항

로그인 및 회원가입 페이지 공통

  • 로그인, 회원가입 기능에 react-hook-form을 활용해 주세요.
  • 브라우저에 현재 보이는 화면의 영역(viewport) 너비를 기준으로 분기되는 반응형 디자인을 적용합니다.
  • PC: 1200px 이상
  • Tablet: 744px 이상 ~ 1199px 이하
  • Mobile: 375px 이상 ~ 743px 이하
  • 375px 미만 사이즈의 디자인은 고려하지 않습니다

유저 기능

  • 리퀘스트 헤더에 인증 토큰을 첨부할 때 axios interceptors를 활용해 주세요. (axios를 사용하지 않는다면 이와 유사한 기능을 활용해 주세요.)
  • React-Query로 마이그레이션
  • fetch 혹은 axios로 구현된 기존의 API 요청 코드를 React-Qeury로 마이그레이션 합니다.
  • 로딩 및 에러 핸들링
  • 로딩 인디케이터와 에러 메시지를 구현합니다.
  • 상품 목록 및 상품 상세 데이터를 Prefetching 합니다
  • 상품 데이터 캐싱 및 업데이트
  • React Query의 캐싱 기능을 활용하여 데이터 로딩 시간을 최소화합니다.
  • 상품 목록 페이지에서 데이터의 실시간 업데이트를 위해 적절한 Query Refresh 설정을 적용합니다.

멘토에게

셀프 코드 리뷰를 통해 질문 이어가겠습니다.

@Aventurine26 Aventurine26 added 매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다. 미완성🫠 완성은 아니지만 제출합니다... 제출일 이후 제출한PR 제출 마감일(일요일) 이후에 제출하는 PR입니다. 최종 제출 스프린트미션 최종 제출본입니다. labels Dec 23, 2024
@Aventurine26 Aventurine26 requested a review from orlein December 23, 2024 17:37
@Aventurine26 Aventurine26 removed the 최종 제출 스프린트미션 최종 제출본입니다. label Dec 23, 2024
@Aventurine26 Aventurine26 added the 최종 제출 스프린트미션 최종 제출본입니다. label Dec 24, 2024
Comment on lines 5 to 20
const handleFavorite = async () => {
try {
const res = await fetch(`https://panda-market-api.vercel.app/products/${product.id}/favorite`, {
method: product.isFavorited ? 'DELETE' : 'POST',
const res = await fetch(`https://panda-market-api.vercel.app/products/${product?.id}/favorite`, {
method: product?.isFavorited ? 'DELETE' : 'POST',
headers: { Authorization: `Bearer ${localStorage.getItem('token')}` },
});
if (res.ok) {
alert('좋아요 상태가 변경되었습니다.');
// 상태 업데이트 필요
if (!res.ok) {
throw new Error('좋아요 상태 변경 실패');
}
alert('좋아요 상태가 변경되었습니다.');
// 상태 업데이트 필요
} catch (error) {
console.error('Error toggling favorite:', error);
alert('좋아요 상태를 변경하는 중 오류가 발생했습니다.');
}
};
Copy link

Choose a reason for hiding this comment

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

product가 존재하지 않는 상황을 위해 product?. 로 optional chaining을 한걸로 보입니다. 그런데, handleFavorite 자체가 product가 없는 경우 아예 실행되지 않아야 합니다. 밑에 if(product) 로 처리한것 처럼, 실행 자체를 막아버리면 에러가 나오지 않습니다.

<div className={styles.productContent}>
<img src={product.image ? product.image : '/default.png'} alt={product.title || '상품이미지'} className={styles.productImage} />
<img
src={product.image ? product.image : '/default.png'}
Copy link

Choose a reason for hiding this comment

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

product.image도 없을 수 있고 이것이 default.png로 초기화되고있습니다. 25번 line에서 처리하는건 어떨까요?

{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
Copy link

Choose a reason for hiding this comment

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

src폴더 사용 좋습니다...

const res = await fetch(`https://panda-market-api.vercel.app/comments`, {
method: "POST",
headers: {
Authorization: `Bearer ${localStorage.getItem("token")}`,
Copy link

Choose a reason for hiding this comment

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

  1. Bearer만 딱 쓰는경우가 대다수이긴 하나 그렇지 않은 경우도 있습니다. realm등의 값이 들어갈 수도 있고 생각보다 다양합니다. Oauth를 사용한다면 rfc6750 를 읽어보세요
  2. 공통 header는 공통 함수를 만들어서 주입하는편이 간단합니다.

Comment on lines +88 to +91
if (isLoading) return <div>로딩 중...</div>;
if (error) return <div>오류가 발생했습니다: {error.message}</div>;

return (
Copy link

Choose a reason for hiding this comment

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

권장되는 패턴입니다. 좋습니다.


export default function Document() {
return (
<Html lang="en">
Copy link

Choose a reason for hiding this comment

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

한국어 사이트니 lang값을 고쳐주세요.

@orlein orlein merged commit 8704995 into codeit-sprint-fullstack:next-하신혜 Dec 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다. 미완성🫠 완성은 아니지만 제출합니다... 제출일 이후 제출한PR 제출 마감일(일요일) 이후에 제출하는 PR입니다. 최종 제출 스프린트미션 최종 제출본입니다.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants