feat : 곡 상세 댓글 정보 구현 - #106
Conversation
📝 WalkthroughWalkthrough핀 곡 상세 페이지와 라우트가 추가되었고, 상세 피드의 정렬·좋아요·신고 및 소유자별 수정/삭제 메뉴가 구현되었습니다. 곡 이미지 필드가 Changes핀 곡 상세 흐름
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Router
participant PinDetailPage
participant SongFeedCard
participant ReportModal
Router->>PinDetailPage: pins/:pinId 경로로 페이지 렌더링
PinDetailPage->>SongFeedCard: 정렬된 피드와 메뉴 콜백 전달
SongFeedCard->>PinDetailPage: 신고 대상 id 전달
PinDetailPage->>ReportModal: 신고 모달 열기
ReportModal->>PinDetailPage: 모달 닫기
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (1)
src/features/pin/components/SongFeedCard.tsx (1)
91-94: 🚀 Performance & Scalability | 🔵 Trivial
cn유틸 사용 일관성같은 기능(조건부 클래스 결합)에 다른 파일들(
PinDetailPage.tsx등)은cn()유틸을 쓰는데 여기는 템플릿 리터럴을 직접 사용합니다. 통일하면 가독성과 일관성이 좋아집니다.♻️ 제안 수정
+import { cn } from '`@/lib/utils`'; ... - <LikeIcon - className={`size-5 ${entry.liked ? 'text-grayscale-100' : 'text-grayscale-400'}`} - aria-hidden - /> + <LikeIcon + className={cn('size-5', entry.liked ? 'text-grayscale-100' : 'text-grayscale-400')} + aria-hidden + />🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/features/pin/components/SongFeedCard.tsx` around lines 91 - 94, Update the LikeIcon className in SongFeedCard to use the existing cn() utility for combining the static size-5 class with the conditional liked-state color class, matching the established pattern used by related components.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/features/pin/components/SongCard.tsx`:
- Around line 15-17: Update the image source in the SongCard component to use
the existing rectangleBg fallback when song.coverUrl is missing, matching the
song.coverUrl || rectangleBg pattern used by SongDetailPage. Keep the current
alt text and image styling unchanged.
In `@src/features/pin/data/mockPinSearchPlaces.ts`:
- Around line 104-158: Update MOCK_SONG_DETAIL_LOVE_ATTACK so registerCount
matches the intended unique registrant count and the feeds data reflects that
count consistently. Adjust the feed entries or their nicknames as needed,
preserving the existing PinDetail structure and ensuring the displayed
registration total aligns with the rendered feed cards and authors.
In `@src/pages/MapPage.tsx`:
- Around line 162-178: Update PinListSheet to derive its open state from
selectedMapPinId and clear that state in onClose so the sheet can close. Replace
the hardcoded place object with selectedPlaceForSheet, deriving the actual
selected place from selectedMapPinId and the map pin data while preserving the
existing pin navigation behavior.
In `@src/pages/PinDetailPage.tsx`:
- Line 27: 알 수 없는 pinId를 조용히 MOCK_SONG_DETAIL_LOVE_ATTACK으로 대체하지 않도록
PinDetailPage의 pinDetail 처리에서 “정보를 찾을 수 없음” 상태를 표시하거나 최소한 콘솔 경고를 남기도록 수정하고,
src/features/pin/data/mockPinSearchPlaces.ts 160-202행의 MOCK_PIN_CARD_DATA가 참조하는
'toxic-till-the-end'에 대해서는 MOCK_SONG_DETAILS에 PinDetail 목업을 추가하거나 카드 pinId를 실제
존재하는 값으로 변경하세요.
- Line 110: PinDetailPage의 ReportModal 사용부에서 ReportModal.onSubmit(reason,
detail?)를 연결하고, 제출 시 현재 reportFeedId를 신고 API 또는 저장 로직에 전달하도록 수정하세요. 신고 제출이 완료되면
기존 onClose와 동일하게 상태를 정리하고, reportFeedId가 없는 경우에는 제출을 진행하지 않도록 처리하세요.
- Around line 100-107: Update the sortedFeeds rendering in PinDetailPage so
SongFeedCard receives a real like-toggle handler that updates each feed’s liked
state and likeCount using the same pattern as the top-song like control, and
pass an onPlay handler for preview playback. Preserve the existing onReport
behavior and ensure both card interactions produce the corresponding local UI
updates.
---
Nitpick comments:
In `@src/features/pin/components/SongFeedCard.tsx`:
- Around line 91-94: Update the LikeIcon className in SongFeedCard to use the
existing cn() utility for combining the static size-5 class with the conditional
liked-state color class, matching the established pattern used by related
components.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 3d06335c-cbb8-4bec-b6de-2de437ac6fea
⛔ Files ignored due to path filters (5)
src/assets/icons/change.svgis excluded by!**/*.svgsrc/assets/icons/like.svgis excluded by!**/*.svgsrc/assets/icons/more.svgis excluded by!**/*.svgsrc/assets/icons/soundwaves.svgis excluded by!**/*.svgsrc/assets/images/Hype-Boy.pngis excluded by!**/*.png
📒 Files selected for processing (12)
src/features/pin/components/SongCard.tsxsrc/features/pin/components/SongFeedCard.tsxsrc/features/pin/data/mockPinSearchPlaces.tssrc/features/pin/data/songPreview.tssrc/features/pin/types.tssrc/index.csssrc/layouts/MapLayout.tsxsrc/layouts/RootLayout.tsxsrc/pages/MapPage.tsxsrc/pages/PinDetailPage.tsxsrc/pages/SongDetailPage.tsxsrc/routes/index.tsx
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/features/pin/data/mockPinSearchPlaces.ts (1)
161-163: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win모든 핀 카드에 대응하는 상세 데이터를 추가해 주세요.
MOCK_SONG_DETAILS에는love-attack만 등록되어 있지만MOCK_PIN_CARD_DATA에는toxic-till-the-end카드가 포함되어 있습니다. 해당 카드를 선택해pinId로 상세 페이지를 열면 조회 결과가 없어 상세 흐름이 깨질 수 있습니다. Toxic 곡의PinDetailmock을 추가하거나, 상세 mock이 준비될 때까지 해당 카드를 목록에서 제외해야 합니다.Also applies to: 177-197
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/features/pin/data/mockPinSearchPlaces.ts` around lines 161 - 163, Update MOCK_SONG_DETAILS and the related mock data so every entry in MOCK_PIN_CARD_DATA has matching PinDetail data, including toxic-till-the-end. Prefer adding the Toxic song’s PinDetail mock and registering it in MOCK_SONG_DETAILS; otherwise remove that card from MOCK_PIN_CARD_DATA until its detail mock exists, ensuring every selectable pinId resolves successfully.src/pages/PinDetailPage.tsx (1)
29-32: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win다른 핀으로 이동할 때 각 핀별 상태를 초기화하세요.
likes,likeCount,sort,reportFeedId는 마운트 시에만 적용되는useState초기값으로 설정됩니다.pins/:pinId라우트에서pinId가 바뀌더라도 컴포넌트가 언마운트되지 않으면 이전 핀의 좋아요, 개수, 정렬, 신고 상태가 그대로 남아 현재 핀 데이터와 어긋납니다. 해당 상태들을pinId/pinDetail변경 시 재설정하거나key={pinId}로 컴포넌트를 새로 마운트하세요.수정 예시
-import { useMemo, useState } from 'react'; +import { useEffect, useMemo, useState } from 'react'; ... + useEffect(() => { + setSort('latest'); + setLiked(Boolean(pinDetail.liked)); + setLikeCount(pinDetail.likeCount); + setReportFeedId(null); + }, [pinId, pinDetail.liked, pinDetail.likeCount]);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/pages/PinDetailPage.tsx` around lines 29 - 32, Reset the per-pin state in PinDetailPage when pinId or pinDetail changes, including sort, liked, likeCount, and reportFeedId, so navigation between pins cannot retain the previous pin’s values. Alternatively, remount the component with key={pinId}, while preserving initialization from the current pinDetail.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/pages/PinDetailPage.tsx`:
- Around line 106-107: Update the owner actions in PinDetailPage’s SongFeedCard
usage so onEdit and onDelete invoke the existing edit and delete flows instead
of empty callbacks; if those flows are not available, remove or hide the owner
menu until they are implemented.
---
Outside diff comments:
In `@src/features/pin/data/mockPinSearchPlaces.ts`:
- Around line 161-163: Update MOCK_SONG_DETAILS and the related mock data so
every entry in MOCK_PIN_CARD_DATA has matching PinDetail data, including
toxic-till-the-end. Prefer adding the Toxic song’s PinDetail mock and
registering it in MOCK_SONG_DETAILS; otherwise remove that card from
MOCK_PIN_CARD_DATA until its detail mock exists, ensuring every selectable pinId
resolves successfully.
In `@src/pages/PinDetailPage.tsx`:
- Around line 29-32: Reset the per-pin state in PinDetailPage when pinId or
pinDetail changes, including sort, liked, likeCount, and reportFeedId, so
navigation between pins cannot retain the previous pin’s values. Alternatively,
remount the component with key={pinId}, while preserving initialization from the
current pinDetail.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: ae8271f2-26f6-4bb0-a54f-43f9b913c227
📒 Files selected for processing (5)
src/features/pin/components/SongFeedCard.tsxsrc/features/pin/data/mockPinSearchPlaces.tssrc/features/pin/types.tssrc/pages/PinDetailPage.tsxsrc/routes/index.tsx
변경 내용
주요 작업
PinDetailPage추가 (/app/pins/:pinId)SongFeedCard추가ReportModal연결PinListSheet의 카드 클릭 시 곡 상세로 이동PinDetail·PinFeedEntry타입 추가관련 이슈
Closes #82
변경 사항
테스트
스크린샷 (UI 변경시)
체크리스트
pnpm format)pnpm lint:fix)코드 품질 확인
PR 제출 전에 다음 명령어를 실행하여 코드 품질을 확인해주세요:
Summary by CodeRabbit
새 기능
버그 수정