Summary
Add a protected Home dashboard as the default authenticated landing page. The page should show a prominent problem coverage percentage and a GitHub-style activity grid for daily practice/exam activity.
Background / Context
LearnLoop currently redirects / and unknown routes to /problems, and the top navigation starts with Problems. The requested product behavior is to introduce a Home page before Problems in the top menu and make it the default authenticated landing page.
The Home page should initially contain two sections:
- Problem coverage: a noticeable, relatively large percentage.
- Activity statistics: a GitHub-style tile grid with 7 rows from Monday to Sunday and week columns across the last year.
Confirmed product decisions:
- Problem coverage =
# problems tried / # total problems.
- A problem is tried if it has been practiced or examined.
- Activity counts problem events.
- Practice attempts count on the practice attempt date.
- Submitted exam items count on the exam submission date, including pending-review items.
- The activity grid shows the last 1 year.
- In dark theme, lighter cells represent higher activity.
- In light theme, darker cells represent higher activity.
- When there are zero problems, show
0% with a note instead of hiding the section.
Relevant current codebase context:
- Frontend routes and top navigation live in
frontend/src/App.tsx.
- Existing pages use React Query and
frontend/src/api/client.ts.
- Backend API routers are registered in
backend/app/main.py.
- Existing related data lives in problems, practice attempts, and exams.
- Practice attempts include
createdAt.
- Submitted exams include
submittedAt and item problem IDs.
- There is no existing Home/Dashboard page or heatmap component.
Problem
Authenticated users currently land on the Problems page by default and have no high-level dashboard showing overall problem coverage or recent learning activity.
Existing endpoints expose pieces of the required data, but not a single dashboard-shaped summary. The frontend should not derive the full dashboard from paginated/grouped histories.
Goal / Expected Behavior
When an authenticated user visits /, they should see the Home dashboard instead of the Problems page.
The top navigation should show Home before Problems.
The Home dashboard should show:
- A large coverage percentage.
- Supporting text like
X of Y problems tried.
- A GitHub-style activity grid for the last 1 year.
- Theme-aware activity intensity:
- Light theme: darker means more activity.
- Dark theme: lighter means more activity.
- A zero-problem state showing
0% with a clear note.
Unknown routes should redirect to Home, preserving the current fallback behavior but changing the destination from Problems to Home.
Scope
This issue should cover:
- Add a protected Home route/page.
- Add Home to the top navigation before Problems.
- Change
/ and * route fallback from /problems to /home.
- Add a backend dashboard summary endpoint for coverage and daily activity.
- Render the coverage and activity sections on the Home page.
- Add backend and frontend tests for the new behavior.
Out of Scope
This issue should not cover:
- New practice or exam workflows.
- Changes to scoring or grading behavior.
- Timezone settings or user-configurable date ranges.
- Historical migrations or backfills.
- A broader dashboard redesign beyond the two requested sections.
- New charting libraries unless clearly justified.
Chosen Implementation Approach
Implement a small backend summary endpoint, recommended as:
GET /api/v1/home/summary
The response should include enough data for the frontend to render without re-querying practice/exam/problem histories separately:
coverage.totalProblems
coverage.triedProblems
coverage.percentage
activity.startDate
activity.endDate
activity.days[], where each day has { date: "YYYY-MM-DD", count: number }
Coverage rules:
- Denominator: all non-deleted problems owned by the current user.
- Numerator: unique non-deleted problem IDs with at least one practice attempt or appearing in a submitted exam item.
- Do not rely only on
tracking.lastTestedAt, because pending-review submitted exam items should count once the exam is submitted.
Activity rules:
- Count each practice attempt as one event on
practice_attempts.createdAt.
- Count each item in submitted exams as one event on
exam.submittedAt.
- Exclude discarded and in-progress exams.
- Use UTC calendar dates for v1.
Implementation Plan
The implementor should:
- Add a backend Home/Dashboard route module and register it under
/api/v1.
- Implement the authenticated summary endpoint using existing user scoping patterns.
- Compute problem coverage from non-deleted problems, practice attempts, and submitted exams.
- Compute last-year daily activity counts and return zero-count days for the full range.
- Add frontend types or local response interfaces for the Home summary response.
- Add a
HomePage component that fetches the summary with React Query.
- Render a prominent coverage number and supporting
X of Y text.
- Render the activity grid with 7 Monday-to-Sunday rows and week columns.
- Use theme-aware CSS variables or inline styles consistent with the existing app.
- Update
frontend/src/App.tsx routing/nav so Home appears first and / plus * redirect to /home.
- Add tests and run the relevant frontend/backend test suites.
Relevant Files / Areas
Likely relevant areas:
backend/app/main.py
backend/app/presentation/
backend/tests/api/
frontend/src/App.tsx
frontend/src/pages/
frontend/src/api/client.ts
frontend/src/theme.css
frontend/src/App.test.tsx
frontend/src/pages/*.test.tsx
Suggested verification commands:
cd backend && uv run pytest
cd frontend && npm test -- --run
Tests Required
The implementor must add or update automated tests covering:
- Backend summary endpoint with no problems.
- Backend coverage with practice attempts.
- Backend coverage with submitted exam items.
- Submitted exam pending-review items count as examined.
- Duplicate events for the same problem do not double-count coverage.
- Multiple events on the same day increase activity count.
- Deleted problems are excluded from total coverage.
- Other users' data is excluded.
- Authenticated
/ route renders Home instead of Problems.
- Top nav shows
Home before Problems.
- Unknown routes redirect to Home.
- Home page renders loading, error, zero-problem, and normal states.
- Activity grid renders returned daily counts with theme-aware intensity behavior.
At minimum, tests should verify:
- The main happy path.
- The zero-data edge case.
- User data isolation.
- Routing regression from Problems to Home.
- That coverage is unique by problem while activity counts events.
Manual Verification / Self-Check
Before claiming this issue is done, the implementor must:
- Run the relevant backend tests.
- Run the relevant frontend tests.
- Log in locally and visit
/; verify Home is shown.
- Visit an unknown app URL; verify it redirects to Home.
- Verify Home appears before Problems in the top navigation.
- Toggle light/dark theme and verify activity intensity direction:
- Light theme: darker cells mean higher activity.
- Dark theme: lighter cells mean higher activity.
- Seed or create practice/exam activity and confirm the coverage and grid update after refresh.
- Include exact commands and pass/fail results in the PR description.
Suggested verification commands:
cd backend && uv run pytest
cd frontend && npm test -- --run
Reviewer Acceptance Checklist
The reviewer should verify that:
Dependencies
None.
Follow-Up Work
Possible future work, not included in this issue:
- User timezone-aware date grouping.
- Configurable activity date ranges.
- Tooltips or drill-down details for each activity tile.
- More Home dashboard sections.
Definition of Done
This issue is done when:
- Authenticated users land on Home by default.
- The top navigation includes Home before Problems.
- The Home page shows problem coverage and a last-year activity grid.
- Backend data is correctly scoped to the current user.
- Backend and frontend automated tests cover the required behavior.
- Manual verification has been performed and documented in the PR.
Summary
Add a protected Home dashboard as the default authenticated landing page. The page should show a prominent problem coverage percentage and a GitHub-style activity grid for daily practice/exam activity.
Background / Context
LearnLoop currently redirects
/and unknown routes to/problems, and the top navigation starts withProblems. The requested product behavior is to introduce a Home page before Problems in the top menu and make it the default authenticated landing page.The Home page should initially contain two sections:
Confirmed product decisions:
# problems tried / # total problems.0%with a note instead of hiding the section.Relevant current codebase context:
frontend/src/App.tsx.frontend/src/api/client.ts.backend/app/main.py.createdAt.submittedAtand item problem IDs.Problem
Authenticated users currently land on the Problems page by default and have no high-level dashboard showing overall problem coverage or recent learning activity.
Existing endpoints expose pieces of the required data, but not a single dashboard-shaped summary. The frontend should not derive the full dashboard from paginated/grouped histories.
Goal / Expected Behavior
When an authenticated user visits
/, they should see the Home dashboard instead of the Problems page.The top navigation should show
HomebeforeProblems.The Home dashboard should show:
X of Y problems tried.0%with a clear note.Unknown routes should redirect to Home, preserving the current fallback behavior but changing the destination from Problems to Home.
Scope
This issue should cover:
/and*route fallback from/problemsto/home.Out of Scope
This issue should not cover:
Chosen Implementation Approach
Implement a small backend summary endpoint, recommended as:
GET /api/v1/home/summaryThe response should include enough data for the frontend to render without re-querying practice/exam/problem histories separately:
coverage.totalProblemscoverage.triedProblemscoverage.percentageactivity.startDateactivity.endDateactivity.days[], where each day has{ date: "YYYY-MM-DD", count: number }Coverage rules:
tracking.lastTestedAt, because pending-review submitted exam items should count once the exam is submitted.Activity rules:
practice_attempts.createdAt.exam.submittedAt.Implementation Plan
The implementor should:
/api/v1.HomePagecomponent that fetches the summary with React Query.X of Ytext.frontend/src/App.tsxrouting/nav so Home appears first and/plus*redirect to/home.Relevant Files / Areas
Likely relevant areas:
backend/app/main.pybackend/app/presentation/backend/tests/api/frontend/src/App.tsxfrontend/src/pages/frontend/src/api/client.tsfrontend/src/theme.cssfrontend/src/App.test.tsxfrontend/src/pages/*.test.tsxSuggested verification commands:
Tests Required
The implementor must add or update automated tests covering:
/route renders Home instead of Problems.HomebeforeProblems.At minimum, tests should verify:
Manual Verification / Self-Check
Before claiming this issue is done, the implementor must:
/; verify Home is shown.Suggested verification commands:
Reviewer Acceptance Checklist
The reviewer should verify that:
/and unknown routes now land on Home for authenticated users.Dependencies
None.
Follow-Up Work
Possible future work, not included in this issue:
Definition of Done
This issue is done when: