-
Notifications
You must be signed in to change notification settings - Fork 0
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
[Feat] 마이페이지 구매후기, 상품 상세 리뷰 모달, 이미지 리스트, 공유 버튼 구현 #158
base: develop
Are you sure you want to change the base?
The head ref may contain hidden characters: "142-feat-\uB9C8\uC774\uD398\uC774\uC9C0-\uAD6C\uB9E4\uD6C4\uAE30"
Conversation
'Content-Type': 'application/json', | ||
Authorization: `Bearer ${token}`, | ||
const res = await fetch( | ||
`${BASE_URL}/api/v1/order?page=0&size=10&startDate=2024-07-01T00:00:00&endDate=2024-07-30T23:59:59`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이거 안넣으면 오류나서 넣었는데 필요없다면 지우겠습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
나중에 제가 수정할게요~
useEffect(() => { | ||
setIsChecked(isLiked); | ||
setNewLikeCount(likeCount); | ||
}, [isLiked, likeCount]); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이걸 안넣으면 모달에서 오른쪽, 왼쪽으로 넘겼을 때 업데이트가 안되던데,,, 왤까요..?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오호,, 나중에 머지 되고 함 봐볼게욧
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
사용처에서 key = id로 넣으면 해결 가능할 것 같아요!
//ReviewItem.tsx
<ReviewLikeButton id={id} key={id} isLiked={likedByUser} likeCount={likeCount} />
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
전체적으로 data라는 네이밍으로 사용하셨는데 어떤 데이터인지 더 명확하게 표현해주시면 좋을거같아요
'Content-Type': 'application/json', | ||
Authorization: `Bearer ${token}`, | ||
const res = await fetch( | ||
`${BASE_URL}/api/v1/order?page=0&size=10&startDate=2024-07-01T00:00:00&endDate=2024-07-30T23:59:59`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
나중에 제가 수정할게요~
const { | ||
sort = 'createdAt', | ||
page = '0', | ||
size = '10', | ||
startDate = '2024-01-01T00:00:00', | ||
endDate = '2024-12-31T23:59:59', | ||
} = params; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
endDate는 현재시간 받아와서 사용하셔도 좋을거같아요~
startDate: '2024-01-01T00:00:00', | ||
endDate: '2024-12-31T23:59:59', | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
endDate는 현재시간을 받아와서 사용하셔도 좋을거같습니다~
|
||
if (!productDetailData) return null; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
null만 보여주는게 UX 차원에서 맞는걸까요?
|
||
if (!productDetailData) return null; | ||
|
||
const { name, thubmnailList, categoryName } = productDetailData; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const { name, thubmnailList, categoryName } = productDetailData; | |
const { name, thubmnailList, categoryName } = productDetailData ?? {}; |
이런식으로 empty case로 보여주는게 나을거같아요
size: searchParams.size || '16', | ||
}; | ||
|
||
const data = await getUserProductReviews(initialParams); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
개인적으로 data라는 네이밍이 조금 애매한거같아요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
페이지에서 prefetch 하고계신건가요? 캐싱으로 prefetch 하시는게 더 나을거같아요
@@ -19,7 +19,7 @@ interface TabData { | |||
interface DetailTabProps { | |||
detailsImg: string; | |||
reviewData: ProductReviewType; | |||
productId: string; | |||
productId: number; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
productId.toString() 메서드로 받으시는경우 있는거같은데
productId: number; | |
productId: number | string; |
그냥 함수에서 둘다받아도 상관없을거같아요
const { data } = useQuery<ProductReviewType>({ | ||
queryKey: ['review', productId, currentReviewId], | ||
queryFn: () => getProductReviews({ productId }), | ||
}); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const { data } = useQuery<ProductReviewType>({ | |
queryKey: ['review', productId, currentReviewId], | |
queryFn: () => getProductReviews({ productId }), | |
}); | |
const { data: 이건 어떤 데이터인가요? } = useQuery<ProductReviewType>({ | |
queryKey: ['review', productId, currentReviewId], | |
queryFn: () => getProductReviews({ productId }), | |
}); | |
import { useOutsideClick } from '@/hooks/useOutsideClick'; | ||
import { KakaoIcon, LinkCopyIcon } from '@/public/index'; | ||
import { ProductType } from '@/types/ProductTypes'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import { ProductType } from '@/types/ProductTypes'; | |
import type { ProductType } from '@/types/ProductTypes'; |
@@ -1,14 +1,19 @@ | |||
'use client'; | |||
|
|||
import { ShareIcon } from '@/public/index'; | |||
import { ProductType } from '@/types/ProductTypes'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import { ProductType } from '@/types/ProductTypes'; | |
import type { ProductType } from '@/types/ProductTypes'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고생하셨습니닷 👍
|
||
export default function MyReviewProduct({ productId, updatedAt, switchOption }: MyReviewProductProps) { | ||
const { data: productDetailData } = useQuery<ProductType>({ | ||
queryKey: ['product-detail', productId], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이거 저 모든 키를 camel 로 작성하긴 했는데 통일시키지 않아도 상관없겟져?!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
다른 getProductDetail 불러오는 함수 query키 일치시키는 게 좋을 것 같아요.
OptionEditModal 컴포넌트의 경우 아래처럼 사용하고 있어요
queryKey: [`product-${productId}`],
queryFn: () => getProductDetail(String(productId)),
두 방식 중에 하나로 하는 게 좋을 것 같습니다~
} | ||
|
||
export default function ProductReviewList({ data, productId }: ProductReviewListProps) { | ||
const { reviewDtoList, ...previewData } = data; | ||
const allReviewImgs = reviewDtoList.flatMap((review) => review.reviewImgs); | ||
const allReviewImgs = reviewDtoList.flatMap((review) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
flatMap이라닛 첨 보는 신기한 친구군뇨
disabled: isNextDisabled, | ||
})} | ||
> | ||
{'>'} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Icon안에 추가적으로 text 넣으신 이유가 무엇인가용?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
예리하시네유... ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ div로 했다가 바꿔서 남아있나봐용,,
useEffect(() => { | ||
setIsChecked(isLiked); | ||
setNewLikeCount(likeCount); | ||
}, [isLiked, likeCount]); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오호,, 나중에 머지 되고 함 봐볼게욧
const boxRef = useRef<HTMLDivElement>(null); | ||
|
||
const shareUrl = window.location.href; | ||
|
||
useOutsideClick(boxRef, () => { | ||
handleClick(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prop으로 받으시는거면 OnClickClose,,? 같은 동작의 의미가 담겨져있는 네이밍ㅇ은 호옥시 어떠신지,,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
수고하셨습니다~ 낙관적 업데이트는 잘 안되는 부분 알려주시면 아는데까진 도움을 줄 수 있습니다...(사실 저도 잘 모름/)
const [currentSectionIndex, setCurrentSectionIndex] = useState(0); | ||
|
||
const isPrevDisabled = currentSectionIndex === 0; | ||
const isNextDisabled = currentSectionIndex === Math.floor(reviewImgs.length / SECTION_SIZE) - 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1 안 빼도 될 것 같아요. reviewImgs가 빈 배열일 때 -1이라서 제대로 표시가 안되고 있어요!
const isNextDisabled = currentSectionIndex === Math.floor(reviewImgs.length / SECTION_SIZE) - 1; | |
const isNextDisabled = currentSectionIndex === Math.floor(reviewImgs.length / SECTION_SIZE); |
const handleMovePrevSection = () => { | ||
if (currentSectionIndex > 0) setCurrentSectionIndex((prev) => prev - 1); | ||
}; | ||
const handleMoveNextSection = () => { | ||
if (currentSectionIndex < Math.floor(reviewImgs.length / SECTION_SIZE)) setCurrentSectionIndex((prev) => prev + 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isPrevDisabled하고 isNextDisabled를 등호가 아닌 부등호로 하면 다음과 같이 적용할 수 있을 것 같아요!
const handleMovePrevSection = () => { | |
if (currentSectionIndex > 0) setCurrentSectionIndex((prev) => prev - 1); | |
}; | |
const handleMoveNextSection = () => { | |
if (currentSectionIndex < Math.floor(reviewImgs.length / SECTION_SIZE)) setCurrentSectionIndex((prev) => prev + 1); | |
//const isPrevDisabled = currentSectionIndex <= 0; | |
//const isNextDisabled = currentSectionIndex >= Math.floor(reviewImgs.length / SECTION_SIZE) ; | |
const handleMovePrevSection = () => { | |
if (!isPrevDisabled) { | |
setCurrentSectionIndex((prev) => prev - 1); | |
} | |
}; | |
const handleMoveNextSection = () => { | |
if (!isNextDisabled) { | |
setCurrentSectionIndex((prev) => prev + 1); | |
} |
useEffect(() => { | ||
setIsChecked(isLiked); | ||
setNewLikeCount(likeCount); | ||
}, [isLiked, likeCount]); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
사용처에서 key = id로 넣으면 해결 가능할 것 같아요!
//ReviewItem.tsx
<ReviewLikeButton id={id} key={id} isLiked={likedByUser} likeCount={likeCount} />
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고민인 부분이 어딜까용?? ㅠㅠ 고생하셨어용 ㅠㅠ
공식문서 당연히 보셨겠지만,, 일단 첨부
declare global { | ||
interface Window { | ||
Kakao: Kakao; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오홍 신기해요 카카오에서 쓰란 방식이겠죠?
export interface ReviewSearchParams { | ||
totalElements: number; | ||
totalPages: number; | ||
first: boolean; | ||
last: boolean; | ||
currentPage: number; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
페이지네이션 타입으로 함써보까나요?
totalElements: number; | ||
totalPages: number; | ||
first: boolean; | ||
last: boolean; | ||
currentPage: number; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
위에랑 겹치는고 같아용!
🚀 작업 내용
📝 참고 사항
🖼️ 스크린샷
🚨 관련 이슈 (이슈 번호)
✅ 체크리스트