Skip to content

fix : 문제 리스트 페이지 api body값 수정#108

Closed
leetaewon123 wants to merge 2 commits intodevfrom
fix/problems
Closed

fix : 문제 리스트 페이지 api body값 수정#108
leetaewon123 wants to merge 2 commits intodevfrom
fix/problems

Conversation

@leetaewon123
Copy link
Copy Markdown
Collaborator

@leetaewon123 leetaewon123 commented Sep 4, 2025

🔎 작업 사항

  • 문제리스트 api body값 수정(페이지가 1부터 시작하는 이슈 0으로 수정)

➕ 관련 이슈

Summary by CodeRabbit

  • Bug Fixes

    • 문제 목록과 검색이 항상 첫 페이지(초기 페이지)에서 시작하도록 일관성 있게 조정했습니다.
    • 페이지네이션의 첫/마지막 경계 및 그룹 이동 로직을 수정해 마지막 페이지로 정확히 이동합니다.
    • 페이지 번호 클릭/표시/하이라이트 동작을 일치시키고, 버튼 레이블은 사용자에겐 1부터 보이도록 유지했습니다.
  • UI

    • 필터 영역을 3열(카테고리/난이도/검색) 레이아웃으로 재구성하고 관련 제어의 식별자를 추가했습니다.
    • 문제 목록 테이블에서 일부 칼럼을 제거하고 레이아웃·스타일을 소폭 조정했습니다.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Sep 4, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

페이지네이션 인덱싱을 1-based에서 0-based로 전환하고, 검색/페이징 핸들러와 UI 그리드(3열 필터) 구조를 조정했습니다. Table 컴포넌트의 페이지 그룹 계산·이동 로직과 버튼 표시 방식도 0-based에 맞게 변경됐습니다.

Changes

Cohort / File(s) Change summary
Problems 페이지 상태 및 필터 레이아웃
src/app/(auth)/(navigationsBarLayout)/problems/page.tsx
- currentPage 초기값 1→0으로 변경
- 초기 useProblemListQuery 호출에 page=0 사용
- 검색(엔터/버튼) 시 currentPage를 0으로 리셋하도록 조정
- ProblemTablesetCurrentPage={(p) => setCurrentPage(p)} 형태로 전달(직접 전달 대신 래퍼)
- 필터 UI를 단일 wrapper에서 3열(카테고리, 난이도, 검색)로 재구성하고 각 Select에 id 추가
Table 페이지네이션 및 렌더링 로직
src/app/(auth)/(navigationsBarLayout)/problems/ui/Table.tsx
- 페이지 인덱싱을 0-based로 전환: pageGroupStart 초기값 1→0, 페이지 경계 계산을 0-based로 수정(lastIndex = max(totalPages - 1, 0) 사용)
- 페이지 번호 범위/의존성 업데이트, totalPages ≤ 0 가드 추가
- 그룹 네비게이션을 그룹 단위 Prev/Next에서 handlePrevPage/handleNextPage로 변경(이전 그룹 끝/다음 그룹 시작 또는 마지막 인덱스로 이동)
- 페이지 버튼은 내부 0-based 인덱스를 유지하되 라벨은 num + 1로 1-based 표시
- myProblemsList 채우기에서 mapforEach로 변경, 관련 effect 의존성 업데이트
- 행별 제출 비율(주석 블록) 제거 및 소소한 클래스/스타일 정리

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as 사용자
  participant P as Problems page (page.tsx)
  participant Q as useProblemListQuery
  participant T as Table (ui/Table.tsx)

  rect rgb(245,250,255)
    note over P,Q: 초기 요청은 0-based 페이지(페이지 0)
    U->>P: 페이지 진입
    P->>Q: query(page=0)
    Q-->>P: 데이터(page=0)
    P->>T: props(currentPage=0, totalPages, setCurrentPage)
    T-->>U: 페이징 UI(버튼 라벨은 num+1)
  end

  alt 페이지 버튼 클릭
    U->>T: 페이지 버튼(라벨=2)
    T->>P: onChangePage(index=1)  -- 0-based 전달
    P->>Q: query(page=1)
    Q-->>P: 데이터(page=1)
  else Next 클릭 (일반)
    U->>T: Next
    T->>P: onChangePage(nextIndex) -- nextIndex = current+1 또는 그룹 시작
  else Next 클릭 (마지막 그룹 초과)
    note right of T: 그룹 경계 넘기면 마지막 인덱스로 점프(lastIndex)
    T->>P: onChangePage(lastIndex)
  end

  opt 검색 실행
    U->>P: 검색(엔터/버튼)
    P->>P: setCurrentPage(0)
    P->>Q: query(page=0)
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

refactoring

Poem

나는 작은 토끼, 코드 밭을 뛰네 🐇
0부터 세니 계산이 반듯하구나.
버튼은 1로 웃고 속은 0으로 춤추네,
페이지 퐁당퐁당, 마지막까지 폴짝!
축하해요 — 당근 하나 어서요 🥕


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a65cb53 and 3a0d088.

📒 Files selected for processing (2)
  • src/app/(auth)/(navigationsBarLayout)/problems/page.tsx (6 hunks)
  • src/app/(auth)/(navigationsBarLayout)/problems/ui/Table.tsx (5 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/problems

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot added the fix label Sep 4, 2025
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (6)
src/app/(auth)/(navigationsBarLayout)/problems/ui/Table.tsx (4)

67-71: pageGroupStart 재계산: 1-based 공식을 0-based로 교체 필요

현재 수식은 (currentPage - 1) … + 1 패턴으로 1-based 전제입니다. 0-based에 맞게 아래처럼 교체하세요.

-      setPageGroupStart(Math.floor((currentPage - 1) / PAGE_LIMIT) * PAGE_LIMIT + 1);
+      setPageGroupStart(Math.floor(currentPage / PAGE_LIMIT) * PAGE_LIMIT);

100-108: handlePrevPage: 0-based 경계 및 그룹 단위 이동으로 수정

현 구현은 최소 페이지를 1로 가정하고 있어 0-based와 불일치합니다. 이전 그룹의 시작으로 점프하려면 다음이 간결합니다.

-    if (currentPage > 1) {
-      if (currentPage - PAGE_LIMIT < 1) {
-        setCurrentPage(1);
-      } else {
-        setCurrentPage(currentPage - (currentPage % PAGE_LIMIT || PAGE_LIMIT));
-      }
-    }
+    if (currentPage > 0) {
+      const prevGroupStart = Math.max(
+        0,
+        Math.floor(currentPage / PAGE_LIMIT) * PAGE_LIMIT - PAGE_LIMIT
+      );
+      setCurrentPage(prevGroupStart);
+    }

59-64: setState 반복 호출로 불필요한 리렌더 유발

map 내부에서 setMyProblemsList를 N번 호출하고 있습니다. 한 번에 설정하도록 바꾸세요.

-    myProblems.result.map((item) => setMyProblemsList((prev) => [...prev, item.problemId]));
+    setMyProblemsList(myProblems.result.map((item) => item.problemId));

200-257: UX: 경계/로딩 시 페이지 버튼 비활성화

로딩 중 또는 currentPage가 0/마지막일 때 Prev/Next 버튼을 disabled 처리하면 오작동 방지 및 접근성이 향상됩니다.

예: disabled={isLoading || currentPage === 0} / disabled={isLoading || currentPage === lastIndex}

src/app/(auth)/(navigationsBarLayout)/problems/page.tsx (2)

148-151: 검색(Enter) 시 페이지를 1이 아니라 0으로 리셋

0-based 전환과 불일치입니다. 두 번째 페이지부터 검색이 시작되는 버그가 발생합니다.

-                        setSearch(keyword);
-                        setCurrentPage(1);
+                        setSearch(keyword);
+                        setCurrentPage(0);

156-161: 검색 버튼 클릭 시도 동일하게 0으로 리셋

위 Enter 핸들러와 동일한 버그입니다.

-                      setSearch(keyword);
-                      setCurrentPage(1);
+                      setSearch(keyword);
+                      setCurrentPage(0);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between dbc99d0 and a65cb53.

📒 Files selected for processing (2)
  • src/app/(auth)/(navigationsBarLayout)/problems/page.tsx (1 hunks)
  • src/app/(auth)/(navigationsBarLayout)/problems/ui/Table.tsx (4 hunks)
🔇 Additional comments (4)
src/app/(auth)/(navigationsBarLayout)/problems/ui/Table.tsx (2)

54-54: 0-based 전환 자체는 맞지만, 하단 그룹 재계산 로직이 1-based 잔재

초기값 0으로의 전환은 적절합니다. 다만 아래 useEffect의 그룹 시작 계산식이 1-based 공식을 그대로 사용하고 있어 현재 페이지와 불일치가 발생합니다. 아래 수정 코멘트를 반영해 주세요.


234-234: 1-based 라벨링은 적절합니다

내부 인덱스(0-based)와 표시(1-based)를 분리한 점 좋습니다.

src/app/(auth)/(navigationsBarLayout)/problems/page.tsx (2)

76-76: 초기 페이지 0 전환은 적절합니다

Table.tsx의 0-based 전환과 일치합니다. 아래 검색 핸들러의 페이지 초기화도 0으로 맞춰 주세요.


101-101: totalPages 의미(개수 vs 마지막 인덱스) 확인 요청

Table.tsx에서 계산 로직이 totalPages=“개수”를 전제로 수정됩니다. API 스키마가 이 전제를 보장하는지 확인해 주세요. 만약 “마지막 인덱스”라면 Table.tsx의 lastIndex 계산에서 -1 보정을 제거해야 합니다.

Comment thread src/app/(auth)/(navigationsBarLayout)/problems/ui/Table.tsx Outdated
Comment on lines 91 to 98
if (currentPage < totalPages) {
if (currentPage + PAGE_LIMIT > totalPages) {
setCurrentPage(totalPages - 1);
setCurrentPage(totalPages); // 마지막 페이지로 이동
} else {
setCurrentPage(currentPage + PAGE_LIMIT);
}
}
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

handleNextPage: 마지막 페이지 비교/이동 off-by-one

currentPage < totalPages 및 마지막 페이지로 setCurrentPage(totalPages)는 0-based 전제에서 한 칸 밀립니다. 아래처럼 lastIndex를 기준으로 비교/이동하세요.

-    if (currentPage < totalPages) {
-      if (currentPage + PAGE_LIMIT > totalPages) {
-        setCurrentPage(totalPages); // 마지막 페이지로 이동
+    // totalPages는 '개수'라고 가정
+    if (totalPages <= 0) return;
+    const lastIndex = totalPages - 1;
+    if (currentPage < lastIndex) {
+      if (currentPage + PAGE_LIMIT > lastIndex) {
+        setCurrentPage(lastIndex); // 마지막 페이지로 이동
       } else {
         setCurrentPage(currentPage + PAGE_LIMIT);
       }
     }
📝 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.

Suggested change
if (currentPage < totalPages) {
if (currentPage + PAGE_LIMIT > totalPages) {
setCurrentPage(totalPages - 1);
setCurrentPage(totalPages); // 마지막 페이지로 이동
} else {
setCurrentPage(currentPage + PAGE_LIMIT);
}
}
};
// totalPages는 '개수'라고 가정
if (totalPages <= 0) return;
const lastIndex = totalPages - 1;
if (currentPage < lastIndex) {
if (currentPage + PAGE_LIMIT > lastIndex) {
setCurrentPage(lastIndex); // 마지막 페이지로 이동
} else {
setCurrentPage(currentPage + PAGE_LIMIT);
}
}
};
🤖 Prompt for AI Agents
In src/app/(auth)/(navigationsBarLayout)/problems/ui/Table.tsx around lines 91
to 98, the handleNextPage uses currentPage < totalPages and sets
setCurrentPage(totalPages) which is off-by-one for 0-based page indexes; change
the logic to compute lastIndex = totalPages - 1, compare currentPage <
lastIndex, and when advancing either setCurrentPage(lastIndex) if currentPage +
PAGE_LIMIT > lastIndex or setCurrentPage(currentPage + PAGE_LIMIT), ensuring you
never set page to totalPages (out of range).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant