Skip to content

Conversation

@mulddang2
Copy link
Collaborator

요구사항

기본

상품 등록 페이지

  • 상품 등록 페이지 주소는 "/addboard" 입니다.
  • 게시판 이미지는 최대 한개 업로드가 가능합니다.
  • 각 input의 placeholder 값을 정확히 입력해주세요.
  • 이미지를 제외하고 input 에 모든 값을 입력하면 '등록' 버튼이 활성화 됩니다.

상품 상세 페이지

  • 상품 상세 페이지 주소는 "/board/{id}" 입니다.
  • 댓글 input 값을 입력하면 '등록' 버튼이 활성화 됩니다.
  • 활성화된 '등록' 버튼을 누르면 댓글이 등록됩니다

심화

상품 등록 페이지

  • 회원가입, 로그인 api를 사용하여 받은accessToken을 사용하여 게시물 등록을 합니다.
  • '등록' 버튼을 누르면 게시물 상세 페이지로 이동합니다.

주요 변경사항

  • /addboard 페이지 추가 및 게시글 등록 기능구현

스크린샷

image

멘토에게

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

@mulddang2 mulddang2 requested a review from GANGYIKIM November 2, 2024 11:46
@mulddang2 mulddang2 self-assigned this Nov 2, 2024
@mulddang2 mulddang2 added 매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다. 미완성🫠 죄송합니다.. labels Nov 2, 2024
Copy link
Collaborator

@GANGYIKIM GANGYIKIM left a comment

Choose a reason for hiding this comment

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

수지님 이번 스프린트 미션 고생하셨습니다~
동일 사항에 대해서는 한번만 코멘트를 드리니 리팩토링하실때 비슷한 사항도 찾아서 같이 적용해보시면 더 좋을 것 같습니다~


useEffect(() => {
const fetchArticles = async () => {
let url = `https://panda-market-api.vercel.app/articles?orderBy=${orderBy}`;
Copy link
Collaborator

Choose a reason for hiding this comment

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

P3:
공통으로 사용되는 기본 주소는 변수에 저장해두고 쓰셔도 좋을 것 같아요~

Suggested change
let url = `https://panda-market-api.vercel.app/articles?orderBy=${orderBy}`;
let url = `${BASE_URL}/articles?orderBy=${orderBy}`;

Comment on lines +63 to +65
const handleInputChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
setComment(e.target.value);
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

P2:
이렇게 인풋값이 입력될때마다 state를 바꿔주는 경우 debounce를 통해 이벤트를 묶어 실행해주시는 것이 좋습니다.
그렇게 되면 리렌더링되는 횟수를 줄일 수 있습니다.

Comment on lines +106 to +108
interface ItemProfileSectionProps {
product: Product;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

P3:
product으로 묶어 전달 받기보다 images, name, price 등으로 받는 게 더 좋아보여요~
product 객체로 받으면 꼭 다른 값도 받기위해서 묶어서 받는 것처럼 보이니, 필요한 값만 전달 받으시면 더 좋을 것 같아요

Comment on lines +151 to +152
: // 참고: 요구사항에는 없었지만 항상 Empty State UI 구현하는 걸 잊지 마세요! Empty State을 재사용 가능한 컴포넌트로 만들었어요.
// 키워드가 입력되지 않은 상태에서 검색 시 Empty State이 보이지 않도록 조건 추가
Copy link
Collaborator

Choose a reason for hiding this comment

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

P3:
좋은 주석이 많네요~ empty UI, skeleton UI 등을 구현하는것이 늘 더 좋습니다~

Copy link
Collaborator

Choose a reason for hiding this comment

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

P3:
많은 주석과 여러개의 컴포넌트, styledComponent 로 인해 파일의 가독성이 떨어집니다.
분리하시면 더 좋을 것 같아요~

Comment on lines +38 to +46
const getPageSize = (width: number) => {
if (width < 768) {
return 4; // Mobile viewport
} else if (width < 1280) {
return 6; // Tablet viewport
} else {
return 10; // Desktop viewport
}
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

P3:
해당 함수의 반환값이 number가 아닌 4 | 6 | 10 이므로 pageSize에서도 이를 명시해주시면 더 좋습니다.

type PageSizeType = ReturnType<typeof getPageSize>;
const [pageSize, setPageSize] = useState<PageSizeType | null>(null);

Comment on lines +18 to +19
// Next.js에서는 next/link의 Link 컴포넌트를 사용해 주세요.
// 참고: Next.js 버전 13부터는 Link 자체가 anchor 태그의 역할을 해요. Link 요소 내에 <a> 태그가 중첩되어 있으면 hydration 오류가 발생하니 주의해 주세요.
Copy link
Collaborator

Choose a reason for hiding this comment

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

P3:
학습에 좋은 주석이네요 👍

`;

interface DropdownMenuProps {
onSortSelection: (sortOption: any) => void;
Copy link
Collaborator

Choose a reason for hiding this comment

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

P2:
any 보다는 타입을 명시해주시면 좋겠습니다.
여기서는 {key: string; label: string}으로 아래의 sortOptions 와 동일한 타입이므로 따로 정의해서 사용하시면 더 좋겠네요.

interface DropdownOptionProps { key: string; label: string }

interface DropdownMenuProps {
  onSortSelection: (sortOption: DropdownOptionProps) => void;
  sortOptions: DropdownOptionProps[];
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

P3:
파일 길이가 250줄 가까이되니 가독성이 떨어지네요~
이미지 업로드같은 내부 로직들을 custom hook으로 분리하면 좋을 것 같아요.

Comment on lines +2 to +6
writer: {
image: string;
nickname: string;
id: number;
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

P2:
writer가 해당 파일과 articleTypes에서 반복적으로 사용되는 것 같으니 공용으로 타입하나 정의해서 쓰시면 더 좋을 것 같습니다.

export interface WriterProps {
  image: string;
  nickname: string;
  id: number;
};

export interface ProductComment {
  writer: WriterProps;
}

export interface Article {
  writer: Omit<WriterProps, 'image'>;
}

@GANGYIKIM GANGYIKIM merged commit bf77f21 into codeit-bootcamp-frontend:Next-이수지 Nov 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다. 미완성🫠 죄송합니다..

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants