feat: 공통 네비바 + 대시보드 + 즐겨찾기 단축키 + 선택 다시 풀기 - #13
Conversation
|
Warning Review limit reached
Next review available in: 49 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthrough대시보드와 공통 네비게이션이 추가되었고, 복습 문제를 선택적으로 다시 풀 수 있도록 변경되었다. PracticeSession에는 F/f 즐겨찾기 단축키가 추가되었다. Changes앱 학습 기능 개선
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related issues
Possibly related PRs
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches 💡 1📝 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: 3
🤖 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/app/dashboard/page.tsx`:
- Around line 26-29: Update the getDashboardSummary error handler so failures
are stored in a separate error state instead of replacing the summary with
EMPTY_SUMMARY. Render a clear error message with a retry action when that state
is set, while preserving EMPTY_SUMMARY only for a successful response that
contains no learning records.
In `@src/features/nav/NavBar.tsx`:
- Around line 19-22: Update the Link elements in NavBar to expose the active
navigation state to assistive technology: set aria-current to "page" when
pathname matches link.href, and pass undefined for inactive links. Keep the
existing className styling behavior unchanged.
In `@src/features/practice/PracticeSession.tsx`:
- Around line 86-87: Update the F-key handler in PracticeSession to branch on
the current favorite state, calling addFavorite() when the item is not favorited
and removeFavorite() when it is already favorited; do not call toggleFavorite(),
so repeated F presses both add and remove the favorite as indicated by the
shortcut.
🪄 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: e3959107-6baa-4899-b6d1-b82a97bc85fd
📒 Files selected for processing (6)
src/app/dashboard/page.tsxsrc/app/layout.tsxsrc/app/review/page.tsxsrc/features/nav/NavBar.tsxsrc/features/practice/PracticeSession.tsxsrc/features/review/ReviewList.tsx
| (err) => { | ||
| console.error("getDashboardSummary failed:", err); | ||
| setSummary(EMPTY_SUMMARY); | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
조회 실패를 빈 학습 기록으로 표시하지 마세요.
getDashboardSummary()가 실패했을 때 EMPTY_SUMMARY를 렌더링하면 IndexedDB 오류가 “풀이 0건, 정답률 0%”로 오인됩니다. 오류 상태를 별도로 저장하고 재시도 또는 오류 안내를 표시해야 합니다.
수정 예시
+ const [loadError, setLoadError] = useState(false);
+
useEffect(() => {
progressRepository.getDashboardSummary().then(
(result) => setSummary(result),
(err) => {
console.error("getDashboardSummary failed:", err);
- setSummary(EMPTY_SUMMARY);
+ setLoadError(true);
}
);
}, []);
+ if (loadError) {
+ return <p className="text-center p-10">통계를 불러오지 못했습니다.</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.
| (err) => { | |
| console.error("getDashboardSummary failed:", err); | |
| setSummary(EMPTY_SUMMARY); | |
| } | |
| const [loadError, setLoadError] = useState(false); | |
| useEffect(() => { | |
| progressRepository.getDashboardSummary().then( | |
| (result) => setSummary(result), | |
| (err) => { | |
| console.error("getDashboardSummary failed:", err); | |
| setLoadError(true); | |
| } | |
| ); | |
| }, []); | |
| if (loadError) { | |
| return <p className="text-center p-10">통계를 불러오지 못했습니다.</p>; | |
| } |
🤖 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/app/dashboard/page.tsx` around lines 26 - 29, Update the
getDashboardSummary error handler so failures are stored in a separate error
state instead of replacing the summary with EMPTY_SUMMARY. Render a clear error
message with a retry action when that state is set, while preserving
EMPTY_SUMMARY only for a successful response that contains no learning records.
| } else if (e.key === "f" || e.key === "F") { | ||
| toggleFavorite(); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
F 단축키가 실제로 즐겨찾기를 전환하도록 수정하세요.
현재 toggleFavorite()은 이미 선택된 경우 반환하므로 F를 다시 눌러도 해제되지 않습니다. 상태에 따라 addFavorite()과 removeFavorite()을 분기해 안내 문구의 “F: 즐겨찾기” 동작을 충족해야 합니다.
수정 예시
function toggleFavorite() {
- if (favorited[current]) return;
- setFavorited((prev) => ({ ...prev, [current]: true }));
- progressRepository
- .addFavorite(question.questionId)
+ const nextFavorited = !(favorited[current] ?? false);
+ setFavorited((prev) => ({ ...prev, [current]: nextFavorited }));
+ const update = nextFavorited
+ ? progressRepository.addFavorite(question.questionId)
+ : progressRepository.removeFavorite(question.questionId);
+ update
.catch((err) => console.error("addFavorite failed:", err));
}Also applies to: 124-124
🤖 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/practice/PracticeSession.tsx` around lines 86 - 87, Update the
F-key handler in PracticeSession to branch on the current favorite state,
calling addFavorite() when the item is not favorited and removeFavorite() when
it is already favorited; do not call toggleFavorite(), so repeated F presses
both add and remove the favorite as indicated by the shortcut.
기능 설명
수동 QA 중 나온 4개 요구사항 처리.
layout.tsx)로 모든 페이지에서 이동 가능F키 단축키 추가ProgressRepository.getDashboardSummary()(기존 구현·테스트됨) 소비하는/dashboard화면 신설작업내용
src/features/nav/NavBar.tsx신설,src/app/layout.tsx에 삽입src/app/dashboard/page.tsx신설src/features/practice/PracticeSession.tsx—handleKeyDown에F키 분기 추가src/features/review/ReviewList.tsx— 체크박스 다중선택,onRetryAll→onRetry(questions)시그니처 변경src/app/review/page.tsx—handleRetryAll→handleRetry(selectedQuestions)로 교체검증:
npx tsc --noEmit,npm run lint,npm run build전부 통과./,/practice,/review,/dashboard라우트 curl 스모크테스트로 네비 링크·대시보드 렌더 확인. Codex 리뷰 1회 돌림 — P1 4건 나왔으나 직접 코드 대조 결과 전부 오탐(codex 샌드박스가npm run build/tsc실행을 거부당해 PowerShellGet-Content로 한글 파일 읽다 인코딩 깨진 것으로 추정) — 조치 없음.Closes #10, #11, #12
참고문서
docs/superpowers/plans/2026-07-31-nav-and-dashboard.md(로컬 전용, repo 미포함)Summary by CodeRabbit
F키로 현재 문제를 즐겨찾기에 추가하거나 해제할 수 있습니다.