Conversation
- 실시간 인기 사이트 랭킹을 표시하는 페이지 UI 구현 - 기간(period) 및 카테고리(category)에 따른 필터링 기능 추가 - 데이터 로딩, 에러, 목록이 없는 경우(Empty State)에 대한 UI 상태 처리를 구현 - API 호출 로직을 popularSites 모듈로 분리
API 응답 데이터의 실제 식별자 키가 `site_id`가 아닌 `id`로 확인되어, FE 데이터 모델과 불일치가 발생했습니다.
이로 인해 RankingPage에서 `site.site_id`가 `undefined`로 평가되어, 목록 렌더링 시 React key 경고가 발생하는 문제를 해결했습니다.
- Site 인터페이스의 `site_id`를 `id`로 변경
- 컴포넌트에서 `key={site.id}`를 사용하도록 수정
|
Caution Review failedThe pull request is closed. Walkthrough실시간 랭킹 페이지와 API 클라이언트, 빈 상태 컴포넌트가 추가되었고, 헤더 내비게이션 링크들이 실경로로 업데이트되었으며 Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant RP as RankingPage
participant API as getPopularSites()
participant BE as Backend API
User->>RP: 페이지 진입 / 필터 선택
activate RP
RP->>API: getPopularSites({period, category})
activate API
API->>BE: GET /api/sites/popular/popular-sites?period=...&limit=10[&category=...]
activate BE
BE-->>API: 200 + { success, data.sites } / error
deactivate BE
API-->>RP: Promise<Site[]> 또는 예외
deactivate API
alt 성공 및 데이터 존재
RP-->>User: 랭킹 리스트 렌더링 (랭크 배지, 사이트, 클릭수)
else 성공이지만 빈 결과
RP-->>User: EmptyState 표시
else 실패
RP-->>User: 에러 메시지 표시
end
deactivate RP
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
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: 1
🧹 Nitpick comments (7)
src/components/ui/Header.tsx (1)
70-72: 도움말 링크를 실제 경로로 연결북마크 페이지에서는 /help로 연결하고 있습니다. 헤더도 동일하게 맞추는 게 좋습니다.
다음 변경을 제안합니다:
- <Link href="#" className="hover:text-black transition-colors"> + <Link href="/help" className="hover:text-black transition-colors"> 도움말 </Link>src/app/bookmarks/page.tsx (1)
192-215: 내비게이션에 대신 next/link 사용현재 를 사용해 전체 페이지 리로드가 발생합니다. 클라이언트 라우팅을 위해 Link로 교체하세요.
다음 변경을 제안합니다:
- <a - href="/ranking" - className="text-gray-600 text-sm font-medium hover:text-black transition-colors no-underline" - > - 실시간 랭킹 - </a> + <Link + href="/ranking" + className="text-gray-600 text-sm font-medium hover:text-black transition-colors no-underline" + > + 실시간 랭킹 + </Link> - <a - href="/reaction-test" - className="text-gray-600 text-sm font-medium hover:text-black transition-colors no-underline" - > - 반응속도 게임 - </a> + <Link + href="/reaction-test" + className="text-gray-600 text-sm font-medium hover:text-black transition-colors no-underline" + > + 반응속도 게임 + </Link> - <a - href="/bookmarks" - className="text-black text-sm font-semibold no-underline" - > - 북마크 - </a> + <Link + href="/bookmarks" + className="text-black text-sm font-semibold no-underline" + > + 북마크 + </Link> - <a - href="/help" - className="text-gray-600 text-sm font-medium hover:text-black transition-colors no-underline" - > - 도움말 - </a> + <Link + href="/help" + className="text-gray-600 text-sm font-medium hover:text-black transition-colors no-underline" + > + 도움말 + </Link>src/components/RankingEmptyState.tsx (1)
6-23: 인라인 스타일 → Tailwind 전환으로 일관성 향상프로젝트 전반의 Tailwind 사용과 맞추면 유지보수성과 다크모드 대응이 좋아집니다.
다음 변경을 제안합니다:
- <div - style={{ - textAlign: 'center', - padding: '4rem 2rem', - backgroundColor: '#fff', - borderRadius: '12px', - boxShadow: '0 4px 12px rgba(0,0,0,0.1)', - }} - > - <span style={{ fontSize: '4rem' }}>텅~</span> - <h2 style={{ marginTop: '1rem', fontWeight: 'bold' }}> + <div className="text-center p-16 bg-white rounded-xl shadow-md"> + <span className="text-6xl">텅~</span> + <h2 className="mt-4 font-bold"> 아직 집계된 기록이 없어요 </h2> - <p style={{ color: '#6c757d', fontSize: '1rem' }}> + <p className="text-gray-500 text-base"> 사용자들이 사이트를 검색하면 이곳에 실시간 순위가 표시됩니다. </p> </div>src/app/ranking/page.tsx (4)
3-6: 타입 import로 명시성 개선React 네임스페이스 타입 대신 명시적 타입 import를 권장합니다.
+import type { CSSProperties } from 'react'; @@ -const getRankBadgeStyle = (rank: number): React.CSSProperties => { +const getRankBadgeStyle = (rank: number): CSSProperties => {Also applies to: 8-13
61-72: 설명 문구가 선택된 카테고리와 불일치카테고리가 ‘대학교’여도 ‘티켓팅 사이트’로 고정 표기됩니다. 동적으로 표현하세요.
- 지금 가장 많이 검색되는 티켓팅 사이트를 확인하세요. + 지금 가장 많이 검색되는 {activeCategory === '전체' ? '사이트' : `${activeCategory} 사이트`}를 확인하세요.
85-103: 필터 버튼 a11y 개선현재 선택 상태를 전달하기 위해 aria-pressed 추가 권장.
- <button + <button key={cat} onClick={() => setActiveCategory(cat)} + aria-pressed={activeCategory === cat} @@ - <button + <button key={p} onClick={() => setPeriod(p)} + aria-pressed={period === p}Also applies to: 115-131
206-209: 비정상 값 대비 안전한 표기click_count가 숫자가 아닐 때 NaN 노출을 방지하세요.
- {parseInt(site.click_count, 10).toLocaleString()} + {Number.isFinite(Number(site.click_count)) + ? Number(site.click_count).toLocaleString() + : '0'}
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (7)
package.json(2 hunks)src/app/bookmarks/page.tsx(1 hunks)src/app/ranking/page.tsx(1 hunks)src/components/ClientHeader.tsx(2 hunks)src/components/RankingEmptyState.tsx(1 hunks)src/components/ui/Header.tsx(1 hunks)src/libs/api/popularSites.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/components/ClientHeader.tsx (1)
src/components/ui/Header.tsx (1)
Header(23-105)
src/app/ranking/page.tsx (2)
src/libs/api/popularSites.ts (2)
Site(1-7)getPopularSites(23-59)src/components/RankingEmptyState.tsx (1)
EmptyState(4-24)
🔇 Additional comments (3)
src/components/ui/Header.tsx (1)
55-57: /ranking 링크 갱신 LGTM플레이스홀더에서 실제 경로로 전환되어 내비게이션 일관성이 좋아졌습니다.
src/components/ClientHeader.tsx (1)
13-17: 경로 기반 헤더 숨김 로직 LGTM/bookmarks 및 하위 경로에서 헤더 비노출 처리, 조건부 렌더 모두 적절합니다.
Also applies to: 129-138
package.json (1)
13-29: 의존성 호환성 확인 — CI/환경의 Node.js 버전 확인 필요Next.js 15.4은 Node.js 18.18+ 및 TypeScript ≥4.5.2를 요구합니다. package.json의 typescript@^5.9.2, @types/react@^19 / @types/react-dom@^19, lucide-react@0.544.0은 React 19과 호환됩니다. 조치: CI/로컬 빌드 이미지 또는 package.json engines에서 Node.js ≥18.18 사용 여부를 확인하세요.
실시간 인기 사이트 랭킹을 조회할 수 있는 페이지를 구현했습니다.
사용자는 기간 및 카테고리별로 인기 사이트 목록을 필터링하여 확인할 수 있습니다.
📌 작업 내용
🛠️ 변경 사항
id) 불일치로 인한 렌더링 오류 수정 🐞📸 스크린샷
📝 기타
텅~
Summary by CodeRabbit
New Features
Chores