-
Notifications
You must be signed in to change notification settings - Fork 1
[Feat] 마이페이지 회원이 작성한 리뷰/응원한 스토리 확인 기능 #75
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
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
Walkthrough이번 변경 사항은 마이페이지 상세(리뷰/응원) 기능 추가, 관련 API 및 쿼리 훅 도입, 상태 관리(Zustand) 스토어 신설, 일부 불필요 파일 삭제, 여러 컴포넌트의 주석 및 불필요 코드 정리, 로딩 메시지 UI 개선, 날짜 유틸리티 함수 분리, 라우터 및 상세 페이지 경로 추가 등입니다. Changes
Note ⚡️ AI Code Reviews for VS Code, Cursor, WindsurfCodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback. Note ⚡️ Faster reviews with cachingCodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure ✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
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.
Actionable comments posted: 7
🧹 Nitpick comments (9)
src/store/userInfoStore.js (1)
3-17: Zustand 스토어의 상태 관리 개선Zustand 스토어 구현은 잘 되어 있으나, 몇 가지 개선 사항이 있습니다.
- 객체를 통째로 전달받는 방식으로 개선:
const useUserInfoStore = create((set) => ({ userInfo: { name: "", address: "", profileColor: "", }, - setUserInfo: (name, address, profileColor) => + setUserInfo: (userInfo) => set(() => ({ userInfo: { - name, - address, - profileColor, + ...userInfo, }, })), }));이렇게 변경하면 사용하는 컴포넌트에서 다음과 같이 간결하게 호출할 수 있습니다:
// 현재: setUserInfo(name, address, profileColor) // 개선: setUserInfo({ name, address, profileColor })
- 부분 업데이트를 지원하도록 개선할 수도 있습니다:
setUserInfo: (userInfo) => set((state) => ({ userInfo: { + ...state.userInfo, ...userInfo, }, })),src/store/useLikeStore.js (1)
3-12: 회사 좋아요 상태 관리 개선 필요Zustand를 활용한 좋아요 상태 관리 구현은 잘 되어 있으나, 몇 가지 개선 사항이 있습니다.
companyId가 숫자인 경우(관련 코드 스니펫에서
Number(companyIdParam)사용 확인), 객체 키로 사용될 때 문자열로 변환됩니다. 이 과정에서 타입 일관성을 유지하기 위한 처리가 필요할 수 있습니다.좋아요 토글 기능을 추가하면 사용성 개선:
const useLikeStore = create((set) => ({ likedMap: {}, setLike: (companyId, liked) => set((state) => ({ likedMap: { ...state.likedMap, [companyId]: liked, }, })), + toggleLike: (companyId) => + set((state) => ({ + likedMap: { + ...state.likedMap, + [companyId]: !state.likedMap[companyId], + }, + })), }));
- 상태 지속성 고려: 새로고침 후에도 좋아요 상태를 유지하기 위해 localStorage나 sessionStorage와의 연동을 고려할 수 있습니다.
src/apis/myPage/queries.js (1)
1-3: 중복 import 개선 필요getReviews와 getCheers 함수를 중복으로 import하고 있습니다.
다음과 같이 중복 import를 제거하는 것이 좋습니다:
import { useQuery } from "@tanstack/react-query"; -import { getReviews } from "@/apis/myPage/getDetail"; -import { getCheers } from "@/apis/myPage/getDetail"; +import { getReviews, getCheers } from "@/apis/myPage/getDetail";src/pages/myPageDetail/components/StoryItem.jsx (1)
14-15: item 속성에 일관된 옵셔널 체이닝 적용이 필요합니다.이미지 URL을 사용할 때는 옵셔널 체이닝을 적용하지 않았지만, 24번 줄에서는
item?.storyLikes와 같이 옵셔널 체이닝을 사용하고 있습니다. 일관성을 위해 모든 item 속성 접근에 옵셔널 체이닝을 적용하는 것이 좋습니다.- src={item.imageUrl} + src={item?.imageUrl}src/pages/myPageDetail/components/ReviewItem.jsx (2)
16-23: 사용되지 않는 더미 데이터를 제거하세요.현재 코드에 정의된
dummyReviewItem객체는 실제로 컴포넌트 내에서 사용되지 않고 있습니다. 불필요한 코드를 제거하여 코드베이스를 깔끔하게 유지하는 것이 좋습니다.-const dummyReviewItem = { - name: "김소영", - profileColor: "pink", - temperature: 74.6, - reviewContent: - "제품 품질도 후드러고 청건하게 잘 관리되어 있어요. 다시 방문하고 싶어요!", - reviewCategories: ["GOOD_QUALITY", "CLEAN", "REVISIT"], -};
107-122: 접근성 개선: 좋아요 버튼에 aria 속성 추가현재 좋아요 버튼에는 접근성을 위한 aria 속성이 없습니다. 스크린 리더 사용자를 위해 버튼에 aria 속성을 추가하는 것이 좋습니다.
<button onClick={(e) => { e.stopPropagation(); handleLikeClick(); }} + aria-label={isLoggedIn && isGloballyLiked ? "좋아요 취소" : "좋아요"} + aria-pressed={isLoggedIn && isGloballyLiked} > <img src={ isLoggedIn && isGloballyLiked ? "/svgs/storeReview/fullHeartIcon.svg" : "/svgs/Ic_Heart-Empty.svg" } alt="좋아요 버튼" className="w-6 h-6" /> </button>src/pages/support/components/CompanyTab.jsx (1)
38-52: Swiper 구성이 잘 설정되어 있으나 일부 속성에 대한 설명이 필요합니다.Swiper 구성이 자동 재생, 루프, 마우스 호버 시 일시 정지 등 다양한 기능을 포함하고 있어 좋습니다. 그러나
threshold: 4와 같은 일부 속성의 목적을 주석으로 설명하면 더 좋을 것 같습니다.<Swiper modules={[Autoplay, Pagination]} spaceBetween={12} slidesPerView="auto" loop={true} autoplay={{ delay: 3000, disableOnInteraction: true, pauseOnMouseEnter: true, }} preventClicks={true} preventClicksPropagation={true} - threshold={4} + threshold={4} // 스와이프 인식을 위한 최소 이동 거리 설정 className="w-full px-4" >src/pages/myPageDetail/MyPageDetailPage.jsx (2)
58-65: 불필요한 Fragment를 제거하세요.리뷰 아이템을 렌더링하는 코드에서 불필요한 Fragment(
<></>)가 사용되고 있습니다. 내부에 하나의 요소만 있으므로 Fragment를 제거해도 됩니다.{kind === "리뷰" && ( - <> - {reviewsData?.map((item, idx) => ( - <ReviewItem data={item} key={idx} /> - ))} - </> + reviewsData?.map((item, idx) => ( + <ReviewItem data={item} key={idx} /> + )) )}
22-27: 뒤로 가기 버튼의 접근성을 개선하세요.현재 뒤로 가기 버튼은 이미지만 사용하고 있어 스크린 리더 사용자에게 접근하기 어려울 수 있습니다. 버튼 요소를 사용하고 적절한 aria-label을 추가하는 것이 좋습니다.
-<div className="mt-10 px-5 mb-4" onClick={() => navigate(-1)}> - <img src="/svgs/myPage/backIcon.svg" className="cursor-pointer" /> -</div> +<button + className="mt-10 px-5 mb-4" + onClick={() => navigate(-1)} + aria-label="뒤로 가기" +> + <img src="/svgs/myPage/backIcon.svg" alt="" /> +</button>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (12)
public/images/1.jpegis excluded by!**/*.jpegpublic/images/2.jpegis excluded by!**/*.jpegpublic/images/kakao_login_large_wide.pngis excluded by!**/*.pngpublic/images/sample1.jpegis excluded by!**/*.jpegpublic/images/sample2.jpegis excluded by!**/*.jpegpublic/images/sample3.jpegis excluded by!**/*.jpegpublic/images/sample4.jpegis excluded by!**/*.jpegpublic/svgs/myPage/backIcon.svgis excluded by!**/*.svgpublic/svgs/myPage/cheer.svgis excluded by!**/*.svgpublic/svgs/myPage/heart.svgis excluded by!**/*.svgpublic/svgs/myPage/noResult.svgis excluded by!**/*.svgpublic/svgs/myPage/review.svgis excluded by!**/*.svg
📒 Files selected for processing (42)
src/apis/myPage/getDetail.js(1 hunks)src/apis/myPage/queries.js(1 hunks)src/apis/review/getPresignedUrl.js(0 hunks)src/apis/review/likeToggle.js(0 hunks)src/apis/review/postImageKey.js(0 hunks)src/apis/review/postRecipt.js(0 hunks)src/apis/review/postReview.js(1 hunks)src/apis/review/uploadImageToS3.js(0 hunks)src/components/common/HaveToLoginModal.jsx(0 hunks)src/components/layout/BottomTab.jsx(1 hunks)src/components/layout/LayoutWithTab.jsx(1 hunks)src/constants/iconMap.js(0 hunks)src/constants/map/socialEnterprise.js(0 hunks)src/pages/error/ErrorPage.jsx(0 hunks)src/pages/map/components/picker/DatePickerSheet.jsx(0 hunks)src/pages/map/components/picker/Picker.jsx(0 hunks)src/pages/map/components/picker/TimePickerSheet.jsx(0 hunks)src/pages/map/components/review/ReviewContent.jsx(2 hunks)src/pages/map/components/review/ReviewList.jsx(1 hunks)src/pages/myPage/MyPage.jsx(4 hunks)src/pages/myPageDetail/MyPageDetailPage.jsx(1 hunks)src/pages/myPageDetail/components/ReviewItem.jsx(1 hunks)src/pages/myPageDetail/components/StoryItem.jsx(1 hunks)src/pages/review/StoreReviewPage.jsx(2 hunks)src/pages/review/components/PlaceInfo.jsx(1 hunks)src/pages/story/StoryPage.jsx(0 hunks)src/pages/story/components/StoryDetail.jsx(0 hunks)src/pages/story/components/carousel/BestStoryCarousel.jsx(0 hunks)src/pages/story/components/carousel/StoryCarousel.jsx(2 hunks)src/pages/story/components/content/SlideContent.jsx(1 hunks)src/pages/support/SupportItemPage.jsx(0 hunks)src/pages/support/SupportListPage.jsx(1 hunks)src/pages/support/SupportPage.jsx(1 hunks)src/pages/support/components/CompanyTab.jsx(2 hunks)src/pages/support/components/FOACard.jsx(1 hunks)src/pages/support/components/FOAItem.jsx(1 hunks)src/pages/support/components/step/Step6.jsx(0 hunks)src/pages/support/utils/dateFunc.js(1 hunks)src/routes/router.jsx(2 hunks)src/store/useLikeStore.js(1 hunks)src/store/userInfoStore.js(1 hunks)src/styles/spinner.css(0 hunks)
💤 Files with no reviewable changes (18)
- src/pages/story/StoryPage.jsx
- src/pages/story/components/StoryDetail.jsx
- src/pages/story/components/carousel/BestStoryCarousel.jsx
- src/styles/spinner.css
- src/apis/review/postRecipt.js
- src/components/common/HaveToLoginModal.jsx
- src/pages/support/SupportItemPage.jsx
- src/pages/map/components/picker/TimePickerSheet.jsx
- src/pages/map/components/picker/Picker.jsx
- src/pages/support/components/step/Step6.jsx
- src/apis/review/postImageKey.js
- src/pages/map/components/picker/DatePickerSheet.jsx
- src/pages/error/ErrorPage.jsx
- src/apis/review/likeToggle.js
- src/apis/review/getPresignedUrl.js
- src/constants/map/socialEnterprise.js
- src/apis/review/uploadImageToS3.js
- src/constants/iconMap.js
🧰 Additional context used
🧬 Code Graph Analysis (6)
src/apis/review/postReview.js (3)
src/pages/review/StoreReviewPage.jsx (1)
companyId(15-15)src/pages/writeReview/components/WriteText.jsx (2)
companyId(15-15)text(13-13)src/pages/writeReview/components/SelectTag.jsx (1)
companyId(14-14)
src/components/layout/LayoutWithTab.jsx (2)
src/pages/myPageDetail/MyPageDetailPage.jsx (1)
location(11-11)src/components/layout/BottomTab.jsx (1)
location(6-6)
src/store/useLikeStore.js (2)
src/pages/myPageDetail/components/ReviewItem.jsx (1)
useLikeStore(35-35)src/pages/review/StoreReviewPage.jsx (1)
companyId(15-15)
src/store/userInfoStore.js (2)
src/pages/myPageDetail/components/ReviewItem.jsx (1)
useUserInfoStore(33-33)src/pages/myPage/MyPage.jsx (1)
useUserInfoStore(33-33)
src/pages/support/components/CompanyTab.jsx (3)
src/pages/support/components/FOACard.jsx (2)
navigate(5-5)FOACard(4-52)src/apis/announcement/queries.js (2)
useGetAnnouncement(5-10)useGetAnnouncement(5-10)src/components/common/Spinner.jsx (1)
Spinner(3-9)
src/apis/myPage/queries.js (1)
src/apis/myPage/getDetail.js (4)
getReviews(3-6)getReviews(3-6)getCheers(8-11)getCheers(8-11)
🪛 Biome (1.9.4)
src/pages/myPageDetail/MyPageDetailPage.jsx
[error] 62-68: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment
(lint/complexity/noUselessFragments)
🔇 Additional comments (40)
src/components/layout/BottomTab.jsx (1)
6-6: 주석 제거 후의 코드가 더 깔끔해 보입니다.불필요한 인라인 주석을 제거하여 코드 가독성이 향상되었습니다. 코드의 기능적인 변경 없이 깔끔하게 정리된 점이 좋습니다.
src/components/layout/LayoutWithTab.jsx (1)
3-4: 이전 경로 저장 기능 추가로 내비게이션 개선됨현재 경로를 sessionStorage에 'prevPath'로 저장하는 기능이 적절하게 구현되었습니다. 이 변경은 다른 컴포넌트에서 뒤로가기 기능을 더 정확하게 처리할 수 있도록 해줍니다.
Also applies to: 7-11
src/pages/review/StoreReviewPage.jsx (2)
27-34: 이전 경로에 따른 조건부 뒤로가기 처리 추가이전 경로에 따라 적절한 네비게이션 로직을 구현한 점이 좋습니다.
/writeReview에서 왔을 경우 루트로 이동하고, 그 외에는 이전 페이지로 돌아가도록 구현된 부분이 사용자 경험에 도움이 됩니다.
58-58: 이전 하드코딩된 경로 대신 조건부 처리 함수 사용기존의 하드코딩된 경로(
/) 대신handleBack함수를 사용하여 더 유연한 네비게이션 처리를 구현했습니다. 이전 경로를 고려한 네비게이션은 사용자 경험을 개선하는 데 도움이 됩니다.src/pages/support/SupportListPage.jsx (1)
10-10: UI 일관성: 스크롤바 숨김 스타일 적용
SupportPage.jsx와 동일하게 메인 컨테이너에scrollbar-hide클래스를 추가하여 스크롤바를 숨기고 스크롤 기능은 유지하도록 하였습니다. 의도한 대로 동작하는지 확인되었으며, 사용자 경험 관점에서도 깔끔한 레이아웃을 제공합니다.src/pages/support/SupportPage.jsx (1)
39-39: UI 일관성: 스크롤바 숨김 클래스 추가
컨테이너에scrollbar-hide클래스를 추가하여 스크롤바를 감추면서도 스크롤이 가능하도록 처리하였습니다.SupportListPage와 같은 스타일 패턴이 적용되어 일관성이 확보되었습니다.src/pages/support/utils/dateFunc.js (2)
8-20: calculateDday 함수 구현이 잘 되었습니다날짜 차이를 계산하여 D-day 형식으로 반환하는 기능이 적절하게 구현되었습니다. 입력값 검증, 시간 성분 제거를 통한 일자만 비교, 그리고 음수 일수에 대한 처리까지 고려되었습니다.
1-6:⚠️ Potential issue날짜 포맷팅 함수의 구조적 문제 수정 필요
날짜 문자열을 한국어 형식("MM월 DD일까지")으로 변환하는
formatEndDate함수에서 정규식 매칭 그룹과 배열 구조분해 간에 불일치가 있습니다.다음과 같이 수정해 주세요:
export const formatEndDate = (raw) => { const match = raw?.match(/^(\d{4})-(\d{2})-(\d{2})$/); if (!match) return raw; - const [, , mm, dd] = match; + const [, yyyy, mm, dd] = match; return `${parseInt(mm, 10)}월 ${parseInt(dd, 10)}일까지`; };현재 구현에서는 배열 구조분해가 정규식 캡처 그룹과 일치하지 않습니다. 정규식은 3개의 캡처 그룹(년, 월, 일)을 생성하며, 이는
match[1],match[2],match[3]으로 접근할 수 있습니다. 따라서 구조분해는[, yyyy, mm, dd]로 수정해야 합니다.Likely an incorrect or invalid review comment.
src/pages/support/components/FOAItem.jsx (2)
2-2: 날짜 유틸리티 함수 임포트 리팩토링이 잘 되었습니다날짜 포맷팅 로직을 별도의 유틸리티 모듈로 분리하여 가져오는 방식으로 수정한 것은 매우 좋은 리팩토링입니다. 이를 통해 코드 재사용성과 일관성이 향상되었습니다.
6-7: 날짜 함수 호출 부분이 잘 적용되었습니다유틸리티 모듈에서 가져온
formatEndDate와calculateDday함수를 올바르게 사용하고 있습니다. 이전 인라인 구현을 모듈 함수로 대체하여 코드 가독성과 유지보수성이 향상되었습니다.src/pages/support/components/FOACard.jsx (4)
2-2: 날짜 유틸리티 함수 임포트 리팩토링이 잘 되었습니다날짜 포맷팅 로직을 별도의 유틸리티 모듈로 분리하여 가져오는 방식으로 수정한 것은 좋은 리팩토링입니다. 이를 통해 코드 재사용성과 일관성이 향상되었습니다.
7-8: 날짜 함수 호출 부분이 잘 적용되었습니다유틸리티 모듈에서 가져온
formatEndDate와calculateDday함수를 올바르게 사용하고 있습니다. 이전 인라인 구현을 모듈 함수로 대체하여 코드 가독성과 유지보수성이 향상되었습니다.
10-17: 이벤트 핸들러 리팩토링이 잘 되었습니다인라인 익명 함수를 명명된
handleClick함수로 리팩토링한 것은 좋은 개선입니다. 이를 통해 코드 가독성이 향상되고 이벤트 핸들링 로직이 명확해졌습니다.
21-21: 이벤트 핸들러 적용이 잘 되었습니다명명된
handleClick함수를 onClick 이벤트에 올바르게 적용하였습니다.src/pages/story/components/content/SlideContent.jsx (1)
39-41: 코드 가독성이 향상되었습니다!제목을 표시하는 JSX 요소를 여러 줄로 포맷팅하여 가독성이 향상되었습니다. 기능적인 변경 없이 코드 스타일만 개선된 좋은 변경입니다.
src/pages/map/components/review/ReviewList.jsx (2)
3-3: import 변경 - 네비게이션 로직 개선
useNavigate대신Link를 사용하도록 변경되었습니다. 이는 리뷰 더보기 버튼에 직접 링크를 적용하는 방식으로 네비게이션 로직을 단순화한 것으로 보입니다.
11-11: 주석 제거로 코드 정리불필요한 주석이 제거되어 코드가 깔끔해졌습니다.
src/apis/review/postReview.js (2)
7-8: 불필요한 주석 제거파라미터 라인에서 주석이 제거되어 코드가 더 깔끔해졌습니다.
15-16: 에러 핸들링 주석 정리에러 처리 부분의 불필요한 주석이 제거되었습니다.
src/pages/review/components/PlaceInfo.jsx (1)
163-163: 아이콘 경로 통일성 개선빈 하트 아이콘 경로가
/svgs/Ic_Heart-Empty.svg로 변경되었습니다. 이는 좋아요 관련 기능의 리팩토링과 일관성을 위한 변경으로 보입니다.src/routes/router.jsx (2)
19-19: 마이페이지 상세 페이지 컴포넌트 추가새로운 마이페이지 상세 기능을 위한 컴포넌트를 import 했습니다.
45-48: 마이페이지 상세 라우트 추가사용자가 작성한 리뷰와 응원한 스토리를 확인할 수 있는 마이페이지 상세 기능을 위한 새로운 라우트가 추가되었습니다. 라우트 구성이 적절하게 이루어졌습니다.
src/pages/map/components/review/ReviewContent.jsx (3)
4-4: hasBorder 프롭 추가 적용이 잘 되었습니다.컴포넌트에
hasBorder프롭을 추가하여 재사용성을 높인 점이 좋습니다. 기본값을 설정하여 하위 호환성도 유지했습니다.
14-18: 조건부 클래스 스타일링 적용이 잘 되었습니다.Tailwind CSS 클래스 적용 시
hasBorder프롭에 따라 조건부로 스타일을 적용하는 방식이 깔끔합니다. 템플릿 리터럴을 활용한 문자열 조합도 잘 되었습니다.
21-21: 옵셔널 체이닝 적용이 잘 되었습니다.
item?.name과item?.temperature에 옵셔널 체이닝을 적용하여 undefined나 null 값 처리를 안전하게 한 점이 좋습니다.Also applies to: 27-27
src/pages/myPage/MyPage.jsx (3)
33-39: 유저 정보 글로벌 상태 관리 적용이 잘 되었습니다.
useEffect를 사용하여 데이터가 변경될 때마다 유저 정보 스토어를 업데이트하는 로직이 잘 구현되었습니다. 다른 컴포넌트에서 유저 정보를 쉽게 접근할 수 있게 되었습니다.
84-86: 로딩 UI 개선이 잘 되었습니다.단순 텍스트 메시지 대신
Spinner컴포넌트를 사용하여 사용자 경험을 향상시킨 점이 좋습니다. Flex를 활용한 중앙 정렬도 적절하게 적용되었습니다.
118-124: 상호작용 기능 추가가 잘 되었습니다.클릭 이벤트 핸들러와
cursor-pointer스타일을 추가하여 사용자가 상호작용할 수 있는 UI 요소임을 명확하게 표시한 점이 좋습니다. 또한 상태와 함께 페이지 이동 로직이 잘 구현되었습니다.src/pages/story/components/carousel/StoryCarousel.jsx (4)
8-9: 드래그 스크롤 기능 구현이 잘 되었습니다.
useDragScroll훅을 사용하여 드래그 스크롤 기능을 구현한 점이 좋습니다. 드래그 상태를 추적하기 위한 ref 사용도 적절합니다.
13-25: 드래그와 클릭 이벤트 처리가 잘 구현되었습니다.드래그 중 원치 않는 내비게이션을 방지하기 위한 로직이 잘 구현되었습니다. 마우스 이벤트를 적절히 활용하여 사용자 경험을 개선한 점이 좋습니다.
32-37: 스크롤 컨테이너 스타일 및 이벤트 핸들링이 잘 되었습니다.스크롤 가능한 컨테이너에 적절한 스타일을 적용하고, 드래그 이벤트 핸들러를 연결한 점이 좋습니다.
cursor-grab을 사용하여 드래그 가능함을 시각적으로 표시한 것도 좋은 UX 개선입니다.
48-48: pointer-events-none 적용이 잘 되었습니다.자식 요소에
pointer-events-none을 적용하여 드래그 스크롤 기능을 방해하지 않도록 한 점이 좋습니다. 이는 사용자 경험을 원활하게 유지하는 데 도움이 됩니다.Also applies to: 54-54, 57-57
src/pages/myPageDetail/components/ReviewItem.jsx (3)
28-37: 전역 상태와 로컬 상태 동기화 로직이 명확합니다.좋아요 상태를 로컬(
isLiked)과 전역 상태(likedMap)로 모두 관리하는 것이 잘 구현되어 있습니다. 이 방식은 컴포넌트 간에 좋아요 상태를 일관되게 유지하는 데 효과적입니다.
63-90: 좋아요 토글 핸들러가 잘 구현되어 있습니다.좋아요 토글 핸들러가 로그인 확인, 에러 처리, 로딩 상태 관리 등을 포함하여 잘 구현되어 있습니다. 특히 try-catch-finally 패턴을 사용하여 에러 핸들링과 로딩 상태 관리가 잘 되어 있습니다.
92-129: 잘 구성된 UI 컴포넌트입니다.ReviewContent 컴포넌트와 잘 통합되어 있고, 클릭 시 상세 페이지로 이동하는 기능이 잘 구현되어 있습니다. border와 패딩 등 디자인 요소가 일관성 있게 적용되어 있습니다.
src/pages/support/components/CompanyTab.jsx (4)
3-10: Swiper 라이브러리 통합이 잘 되어 있습니다.수평 스크롤 컨테이너를 Swiper 캐러셀로 교체한 것은 좋은 선택입니다. 필요한 모듈과 스타일을 명확하게 가져왔으며, 재사용 가능한 스타일을 활용한 점이 좋습니다.
14-14: 구조 분해 할당을 통한 코드 개선이 좋습니다.
useGetAnnouncement훅의 반환값에서data와isLoading을 구조 분해 할당으로 추출하고 기본값을 설정한 것은 좋은 방식입니다.
33-37: 로딩 UI가 일관되게 개선되었습니다.텍스트 기반 로딩 메시지 대신
Spinner컴포넌트를 사용하여 로딩 상태를 시각적으로 표시하는 것으로 개선한 것이 좋습니다. 이는 전체 애플리케이션에서 일관된 로딩 UI를 제공합니다.
63-63: 주석을 통한 코드 구조 명확화가 좋습니다.섹션을 구분하는 주석을 추가한 것은 코드의 가독성을 높이는 좋은 방법입니다. 개발자가 코드의 구조를 쉽게 이해할 수 있게 해줍니다.
src/pages/myPageDetail/MyPageDetailPage.jsx (1)
9-21: 조건부 데이터 fetching이 잘 구현되어 있습니다.
kind값에 따라 필요한 데이터만 가져오도록enabled옵션을 사용한 것은 효율적입니다. 불필요한 API 호출을 줄이는 좋은 방법입니다.다만, 사용하지 않는 코드에 대한 주석은 다음과 같이 TODO 형식으로 명확하게 표시하면 좋을 것 같습니다:
-// const { data: heartsData, isLoading: isLoadingHearts } = useGetHearts({ enabled: kind === "찜" }); +// TODO: '찜' 기능 구현 시 아래 코드 주석 해제 +// const { data: heartsData, isLoading: isLoadingHearts } = useGetHearts({ enabled: kind === "찜" });
| import api from "@/apis/instance/api"; | ||
|
|
||
| export const getReviews = async () => { | ||
| const res = await api.get("/reviews/get-all-member-reviews"); | ||
| return res.data; | ||
| }; | ||
|
|
||
| export const getCheers = async () => { | ||
| const res = await api.get("/story/member-likes"); | ||
| return res.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.
🛠️ Refactor suggestion
API 요청 함수의 오류 처리 개선이 필요합니다.
API 호출 시 오류 처리 로직이 없습니다. API 요청 중 발생할 수 있는 네트워크 오류나 서버 오류에 대한 처리가 필요합니다.
다음과 같이 try-catch 구문을 추가하여 개선할 수 있습니다:
export const getReviews = async () => {
+ try {
const res = await api.get("/reviews/get-all-member-reviews");
return res.data;
+ } catch (error) {
+ console.error("리뷰 데이터 가져오기 실패:", error);
+ throw error;
+ }
};
export const getCheers = async () => {
+ try {
const res = await api.get("/story/member-likes");
return res.data;
+ } catch (error) {
+ console.error("응원 데이터 가져오기 실패:", error);
+ throw error;
+ }
};📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import api from "@/apis/instance/api"; | |
| export const getReviews = async () => { | |
| const res = await api.get("/reviews/get-all-member-reviews"); | |
| return res.data; | |
| }; | |
| export const getCheers = async () => { | |
| const res = await api.get("/story/member-likes"); | |
| return res.data; | |
| }; | |
| import api from "@/apis/instance/api"; | |
| export const getReviews = async () => { | |
| try { | |
| const res = await api.get("/reviews/get-all-member-reviews"); | |
| return res.data; | |
| } catch (error) { | |
| console.error("리뷰 데이터 가져오기 실패:", error); | |
| throw error; | |
| } | |
| }; | |
| export const getCheers = async () => { | |
| try { | |
| const res = await api.get("/story/member-likes"); | |
| return res.data; | |
| } catch (error) { | |
| console.error("응원 데이터 가져오기 실패:", error); | |
| throw error; | |
| } | |
| }; |
🤖 Prompt for AI Agents
In src/apis/myPage/getDetail.js lines 1 to 11, the API request functions
getReviews and getCheers lack error handling, which can cause unhandled
exceptions during network or server errors. Wrap the API calls inside try-catch
blocks to catch any errors, and handle or rethrow them appropriately to ensure
the calling code can manage failures gracefully.
| export const useGetReviews = () => { | ||
| return useQuery({ queryKey: ["userReview"], queryFn: () => getReviews() }); | ||
| }; | ||
|
|
||
| export const useGetCheers = () => { | ||
| return useQuery({ queryKey: ["userCheers"], queryFn: () => getCheers() }); | ||
| }; |
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.
🛠️ Refactor suggestion
React Query 훅 개선 필요
React Query 훅 구현이 기본적인 형태로 되어 있어, 추가적인 옵션 설정이 필요합니다.
다음과 같이 staleTime, cacheTime, 에러 처리 등 개선된 옵션을 추가하는 것이 좋습니다:
export const useGetReviews = () => {
- return useQuery({ queryKey: ["userReview"], queryFn: () => getReviews() });
+ return useQuery({
+ queryKey: ["userReview"],
+ queryFn: getReviews,
+ staleTime: 5 * 60 * 1000, // 5분
+ cacheTime: 10 * 60 * 1000, // 10분
+ retry: 1,
+ onError: (error) => {
+ console.error("리뷰 데이터 가져오기 실패:", error);
+ }
+ });
};
export const useGetCheers = () => {
- return useQuery({ queryKey: ["userCheers"], queryFn: () => getCheers() });
+ return useQuery({
+ queryKey: ["userCheers"],
+ queryFn: getCheers,
+ staleTime: 5 * 60 * 1000, // 5분
+ cacheTime: 10 * 60 * 1000, // 10분
+ retry: 1,
+ onError: (error) => {
+ console.error("응원 데이터 가져오기 실패:", error);
+ }
+ });
};이렇게 변경하면 다음과 같은 이점이 있습니다:
- staleTime 설정으로 불필요한 refetch 방지
- 에러 처리 로직 개선
- 함수 호출 방식 단순화 (화살표 함수 제거)
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export const useGetReviews = () => { | |
| return useQuery({ queryKey: ["userReview"], queryFn: () => getReviews() }); | |
| }; | |
| export const useGetCheers = () => { | |
| return useQuery({ queryKey: ["userCheers"], queryFn: () => getCheers() }); | |
| }; | |
| export const useGetReviews = () => { | |
| return useQuery({ | |
| queryKey: ["userReview"], | |
| queryFn: getReviews, | |
| staleTime: 5 * 60 * 1000, // 5분 | |
| cacheTime: 10 * 60 * 1000, // 10분 | |
| retry: 1, | |
| onError: (error) => { | |
| console.error("리뷰 데이터 가져오기 실패:", error); | |
| } | |
| }); | |
| }; | |
| export const useGetCheers = () => { | |
| return useQuery({ | |
| queryKey: ["userCheers"], | |
| queryFn: getCheers, | |
| staleTime: 5 * 60 * 1000, // 5분 | |
| cacheTime: 10 * 60 * 1000, // 10분 | |
| retry: 1, | |
| onError: (error) => { | |
| console.error("응원 데이터 가져오기 실패:", error); | |
| } | |
| }); | |
| }; |
🤖 Prompt for AI Agents
In src/apis/myPage/queries.js around lines 5 to 11, the React Query hooks
useGetReviews and useGetCheers are implemented in a basic form without
additional options. Improve these hooks by adding options such as staleTime and
cacheTime to control data freshness and caching, include error handling logic to
manage query failures gracefully, and simplify the queryFn by passing the
function reference directly instead of wrapping it in an arrow function. This
will optimize performance and enhance error management.
| <p className="h4 mt-4">이음숲, 숲과 사람을 이어주는 따뜻한 다리</p> | ||
| <p className="b5 text-gray-9 mt-1">2023년 3월 2일</p> |
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.
🛠️ Refactor suggestion
하드코딩된 텍스트 대신 동적 데이터 사용 권장
제목과 날짜가 하드코딩되어 있습니다. item 객체에서 관련 데이터를 가져와 동적으로 표시하는 것이 더 적절할 것 같습니다. 그렇지 않으면 모든 아이템이 동일한 제목과 날짜를 보여주게 됩니다.
- <p className="h4 mt-4">이음숲, 숲과 사람을 이어주는 따뜻한 다리</p>
- <p className="b5 text-gray-9 mt-1">2023년 3월 2일</p>
+ <p className="h4 mt-4">{item?.storyTitle || "제목 없음"}</p>
+ <p className="b5 text-gray-9 mt-1">{item?.createdAt || ""}</p>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <p className="h4 mt-4">이음숲, 숲과 사람을 이어주는 따뜻한 다리</p> | |
| <p className="b5 text-gray-9 mt-1">2023년 3월 2일</p> | |
| <p className="h4 mt-4">{item?.storyTitle || "제목 없음"}</p> | |
| <p className="b5 text-gray-9 mt-1">{item?.createdAt || ""}</p> |
🤖 Prompt for AI Agents
In src/pages/myPageDetail/components/StoryItem.jsx around lines 29 to 30, the
title and date are hardcoded, causing all items to display the same text. Update
the JSX to use dynamic data from the item object by replacing the static strings
with expressions that access the appropriate properties on item for the title
and date, ensuring each StoryItem renders unique content.
| useEffect(() => { | ||
| const checkLoginAndLiked = async () => { | ||
| const isAuthenticated = await useAuthStore.getState().checkAuth(); | ||
| setIsLoggedIn(isAuthenticated); | ||
|
|
||
| if (isAuthenticated && data?.companyId) { | ||
| const likedList = await getLikedCompanies(); | ||
| const liked = likedList.some( | ||
| (c) => String(c.companyId) === String(data.companyId) | ||
| ); | ||
| setIsLiked(liked); | ||
| setLike(data.companyId, liked); | ||
| } | ||
| setLoading(false); | ||
| }; | ||
|
|
||
| if (data?.companyId) checkLoginAndLiked(); | ||
| }, [data?.companyId]); |
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.
🛠️ Refactor suggestion
성능 최적화 필요: 좋아요 상태 확인 로직
현재 구현에서는 각 리뷰 아이템마다 getLikedCompanies() API를 호출하여 좋아요 목록 전체를 가져옵니다. 이는 리뷰 목록이 많을 경우 불필요한 API 호출이 발생할 수 있습니다.
좋아요 상태를 부모 컴포넌트에서 한 번에 가져오거나, 커스텀 훅으로 분리하여 중복 호출을 줄이는 것이 좋습니다:
-useEffect(() => {
- const checkLoginAndLiked = async () => {
- const isAuthenticated = await useAuthStore.getState().checkAuth();
- setIsLoggedIn(isAuthenticated);
-
- if (isAuthenticated && data?.companyId) {
- const likedList = await getLikedCompanies();
- const liked = likedList.some(
- (c) => String(c.companyId) === String(data.companyId)
- );
- setIsLiked(liked);
- setLike(data.companyId, liked);
- }
- setLoading(false);
- };
-
- if (data?.companyId) checkLoginAndLiked();
-}, [data?.companyId]);
+useEffect(() => {
+ const checkLoginAndLiked = async () => {
+ const isAuthenticated = await useAuthStore.getState().checkAuth();
+ setIsLoggedIn(isAuthenticated);
+ setLoading(false);
+ };
+
+ checkLoginAndLiked();
+}, []);
+
+// likedMap에서 좋아요 상태 가져오기
+useEffect(() => {
+ if (data?.companyId) {
+ setIsLiked(likedMap[data.companyId] ?? false);
+ }
+}, [likedMap, data?.companyId]);Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/pages/myPageDetail/components/ReviewItem.jsx around lines 44 to 61, the
current code calls getLikedCompanies() inside each ReviewItem component's
useEffect, causing redundant API calls when rendering multiple items. To fix
this, move the liked companies fetching logic to the parent component or a
custom hook so that the liked list is fetched once and passed down as props or
accessed via context, thereby avoiding repeated API calls in each ReviewItem.
| {announces.map((item) => ( | ||
| <SwiperSlide key={item.id} className="!w-[320px]"> | ||
| <div className="w-80 h-fit"> | ||
| <FOACard data={item} /> | ||
| </div> | ||
| </SwiperSlide> | ||
| ))} |
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.
💡 Verification agent
🧩 Analysis chain
SwiperSlide의 너비 스타일에 주의가 필요합니다.
!w-[320px] 클래스를 사용하는 것은 Tailwind의 중요(!) 수정자를 사용하는 것으로, Swiper가 관리하는 스타일을 덮어쓸 수 있습니다. 이로 인해 의도하지 않은 레이아웃 문제가 발생할 수 있습니다.
🌐 Web query:
Tailwind CSS !important 수정자와 Swiper 라이브러리 호환성 문제
💡 Result:
Tailwind CSS의 !important 수정자와 Swiper 라이브러리 호환성 문제
문제 개요
Tailwind CSS는 자체적으로 유틸리티 클래스에 대해 !important를 지정하는 특별한 문법이 없지만, @apply나 커스텀 CSS 작성 시 !important를 활용할 수 있습니다. 반면 Swiper는 자체 스타일시트와 인라인 스타일, 내부 우선순위가 높은 CSS를 통해 컴포넌트의 레이아웃과 버튼 등 주요 UI를 제어합니다. 이 때문에 Tailwind 스타일과 Swiper 기본 스타일이 충돌하거나, 원하는 스타일 덮어쓰기가 적용되지 않는 상황이 종종 발생합니다.
대표적인 호환성 문제
- Tailwind의 클래스가 Swiper의 내부 스타일보다 우선 적용되지 않음
- Swiper가 인라인 스타일이나 자체 CSS로 강하게 스타일 지정(
!important포함) → Tailwind로 오버라이드 불가 - Swiper 네비게이션/페이징 버튼 등
class="swiper-button-next"등에서 Tailwind@apply후에도 스타일이 적용되지 않음
해결 방법
1. Swiper 기본 CSS의 우선순위 파악 및 재정의
- Swiper의 기본 스타일(
swiper-bundle.min.css등)이 Tailwind 클래스보다 우선순위가 높거나!important를 사용합니다. - 이를 해결하려면 Tailwind를 사용한 커스텀 CSS에
!important를 직접 적용해야 합니다. - 예시:
또는 일반 CSS 방식으로도 가능:
.swiper-button-next { @apply text-white bg-blue-500 !important; } .swiper-pagination-bullet-active { @apply bg-mkOrange !important; }
Tailwind의.swiper-button-next { color: white !important; background-color: #3b82f6 !important; }
@apply만으로는 Swiper의 강한 CSS를 완전히 덮어쓸 수 없으니,!important를 함께 사용해야 합니다[3][7].
2. 클래스 우선순위 및 충돌 관리
- 클래스 충돌이나 Tailwind 클래스 병합 이슈가 있다면
tailwind-merge와 같은 도구를 활용해 클래스 우선순위를 명확히 할 수 있습니다[5].
3. Swiper 인라인 스타일 및 React에서의 스타일 적용
- Swiper가 인라인 스타일로 속성을 부여하는 경우, CSS로는 덮어쓰기 어렵고, 필요에 따라 React prop에서
style속성을 직접 지정해야 할 수도 있습니다[8].
4. 명확한 셀렉터 사용
- Swiper의 네비게이션, 페이징 등 UI 요소를 커스터마이즈할 땐 Swiper에서 사용하는 정확한 클래스를 타겟팅해야 하며, CSS 선택자 우선순위(CSS Specificity)를 높이기 위해 보다 구체적인 셀렉터 사용, 혹은 CSS 파일상에서 Tailwind CSS 클래스를 Swiper 관련 CSS 아래에 위치하도록 배치하는 것이 효과적입니다[7].
결론 및 실전 팁
- Swiper와 Tailwind CSS를 함께 사용할 때 커스텀 스타일이 Swiper 기본 스타일에 묻히는 것은 스타일 우선순위와
!important처리 문제 때문입니다. - 해결을 위해선 Tailwind의
@apply와 함께 직접!important를 명시하거나, 커스텀 CSS 파일에서 Swiper 기본 스타일을 명확하게 오버라이드해야 합니다. - 복잡한 클래스 병합, 우선순위 문제는 [tailwind-merge][5] 같은 유틸리티 또는 명확한 CSS 선택자 지정으로 보완하세요.
예시 코드:
/* tailwind.css 또는 별도 CSS 파일에서 */
.swiper-button-next,
.swiper-button-prev {
@apply text-2xl text-white bg-blue-600 rounded-lg !important;
}
.swiper-pagination-bullet-active {
@apply bg-orange-500 !important;
}이처럼 Tailwind의 유틸리티를 @apply로 활용하면서, 반드시 !important를 추가해 Swiper의 기본 스타일을 확실히 덮어써야 원하는 디자인을 구현할 수 있습니다[3][7].
추가 참고: Tailwind CSS 및 Swiper 공식문서에서 CSS 커스터마이징 가이드를 함께 참조하세요.
Citations:
- 1: https://www.youtube.com/watch?v=Sr5DxNrmSuA
- 2: https://xionwcfm.tistory.com/331
- 3: https://velog.io/@ijinkyung/TypeScript-ReactSwiper-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC-%EC%82%AC%EC%9A%A9%EB%B2%95
- 4: https://velog.io/@yeonjin1357/JS-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC-Swiper.js%EC%9D%98-%EB%AA%A8%EB%93%A0-%EA%B2%83
- 5: https://xionwcfm.tistory.com/328
- 6: https://fresh-mint.tistory.com/entry/%ED%94%8C%EB%9F%AC%EA%B7%B8%EC%9D%B8%EC%8A%AC%EB%9D%BC%EC%9D%B4%EB%93%9C-swiper
- 7: https://pagedone.io/docs/carousel
- 8: https://velog.io/@sargadi/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC-Swiper
- 9: https://www.youtube.com/watch?v=yCzBObw3ia8
- 10: https://hotsunchip.tistory.com/14
SwiperSlide 너비 제어 방식 수정 필요
src/pages/support/components/CompanyTab.jsx (53-59줄)에서
<SwiperSlide key={item.id} className="!w-[320px]">
…
</SwiperSlide>처럼 Tailwind의 !w-[320px] 유틸리티를 쓰면 내부적으로 !important가 붙어 Swiper가 계산하는 슬라이드 너비(inline style)를 덮어써 레이아웃이 깨질 수 있습니다.
다음 중 한 가지 방법으로 변경하세요:
- Swiper 옵션으로 제어
• slidesPerView, spaceBetween, breakpoints 등 - React style prop 사용
<SwiperSlide key={item.id} style={{ width: '320px' }}> … </SwiperSlide>
- CSS 파일에서 명시적 오버라이드
(별도 CSS 관리 필요)
/* src/styles/swiper-overrides.css */ .swiper-slide { width: 320px !important; }
🤖 Prompt for AI Agents
In src/pages/support/components/CompanyTab.jsx around lines 53 to 59, avoid
using Tailwind's !w-[320px] class on SwiperSlide because it applies !important
and overrides Swiper's inline width styles, causing layout issues. Instead,
control the slide width by setting the width via Swiper's options like
slidesPerView or spaceBetween, or apply the width directly using the React style
prop (e.g., style={{ width: '320px' }}), or alternatively override the width in
a CSS file with a high specificity selector and !important if necessary.
| {kind === "응원" && | ||
| cheersData.map((item) => ( | ||
| <StoryItem item={item} key={item.storyId} /> | ||
| ))} | ||
| </div> |
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.
cheersData가 undefined일 가능성에 대한 처리가 필요합니다.
cheersData가 로딩 중이거나 undefined일 경우 .map() 메서드 호출 시 오류가 발생할 수 있습니다. 조건부 렌더링 또는 옵셔널 체이닝을 추가하는 것이 좋습니다.
{kind === "응원" &&
- cheersData.map((item) => (
+ cheersData?.map((item) => (
<StoryItem item={item} key={item.storyId} />
))}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| {kind === "응원" && | |
| cheersData.map((item) => ( | |
| <StoryItem item={item} key={item.storyId} /> | |
| ))} | |
| </div> | |
| {kind === "응원" && | |
| cheersData?.map((item) => ( | |
| <StoryItem item={item} key={item.storyId} /> | |
| ))} | |
| </div> |
🤖 Prompt for AI Agents
In src/pages/myPageDetail/MyPageDetailPage.jsx around lines 67 to 71, cheersData
may be undefined, causing an error when calling .map(). To fix this, add a check
to ensure cheersData is defined before mapping, either by using optional
chaining (cheersData?.map) or by conditionally rendering only if cheersData
exists.
| {kind === "찜" && ( | ||
| <div className="flex justify-between items-center px-5"> | ||
| <div className="flex gap-2 items-center"> | ||
| <img src={heart} className="w-8 h-8" /> | ||
| <p className="h3">저장한 장소</p> | ||
| </div> | ||
| <p className="b5 text-gray-9">총 0개</p> | ||
| </div> | ||
| )} |
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.
🛠️ Refactor suggestion
'찜' 기능의 구현 상태를 사용자에게 알려주세요.
'찜' 섹션의 UI는 준비되어 있지만, 기능이 아직 구현되지 않았습니다. 사용자에게 이 기능이 준비 중임을 알려주는 메시지를 추가하는 것이 좋습니다.
{kind === "찜" && (
<div className="flex justify-between items-center px-5">
<div className="flex gap-2 items-center">
<img src={heart} className="w-8 h-8" />
<p className="h3">저장한 장소</p>
</div>
<p className="b5 text-gray-9">총 0개</p>
</div>
)}
+{kind === "찜" && (
+ <div className="flex flex-col gap-4 w-full bg-gray-2 p-5 min-h-screen">
+ <div className="flex justify-center items-center h-40 bg-white rounded-md">
+ <p className="b4 text-gray-6">준비 중인 기능입니다.</p>
+ </div>
+ </div>
+)}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| {kind === "찜" && ( | |
| <div className="flex justify-between items-center px-5"> | |
| <div className="flex gap-2 items-center"> | |
| <img src={heart} className="w-8 h-8" /> | |
| <p className="h3">저장한 장소</p> | |
| </div> | |
| <p className="b5 text-gray-9">총 0개</p> | |
| </div> | |
| )} | |
| {kind === "찜" && ( | |
| <div className="flex justify-between items-center px-5"> | |
| <div className="flex gap-2 items-center"> | |
| <img src={heart} className="w-8 h-8" /> | |
| <p className="h3">저장한 장소</p> | |
| </div> | |
| <p className="b5 text-gray-9">총 0개</p> | |
| </div> | |
| )} | |
| {kind === "찜" && ( | |
| <div className="flex flex-col gap-4 w-full bg-gray-2 p-5 min-h-screen"> | |
| <div className="flex justify-center items-center h-40 bg-white rounded-md"> | |
| <p className="b4 text-gray-6">준비 중인 기능입니다.</p> | |
| </div> | |
| </div> | |
| )} |
🤖 Prompt for AI Agents
In src/pages/myPageDetail/MyPageDetailPage.jsx around lines 38 to 46, the UI for
the '찜' feature is present but the functionality is not implemented yet. Add a
clear message within this section to inform users that the '찜' feature is
currently under development or coming soon, so they understand the feature is
not yet available.
shroqkf
left a comment
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.


🌟 어떤 이유로 MR를 하셨나요?
📝 세부 내용 - 왜 해당 MR이 필요한지 작업 내용을 자세하게 설명해주세요
📸 작업 화면 스크린샷
Summary by CodeRabbit
신규 기능
개선 사항
버그 수정
리팩터
기타