-
Notifications
You must be signed in to change notification settings - Fork 0
[feature] 실시간 순위 페이지 구현 #10
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
- 실시간 인기 사이트 랭킹을 표시하는 페이지 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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