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

[이수지] sprint10 #127

Conversation

mulddang2
Copy link
Collaborator

요구사항

기본

상품 등록 페이지

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

상품 상세 페이지

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

심화

상품 등록 페이지

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

주요 변경사항

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

스크린샷

image

멘토에게

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

@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