Skip to content

Add protected Home dashboard with problem coverage and activity grid #305

Description

@brianlan

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:

  1. Add a backend Home/Dashboard route module and register it under /api/v1.
  2. Implement the authenticated summary endpoint using existing user scoping patterns.
  3. Compute problem coverage from non-deleted problems, practice attempts, and submitted exams.
  4. Compute last-year daily activity counts and return zero-count days for the full range.
  5. Add frontend types or local response interfaces for the Home summary response.
  6. Add a HomePage component that fetches the summary with React Query.
  7. Render a prominent coverage number and supporting X of Y text.
  8. Render the activity grid with 7 Monday-to-Sunday rows and week columns.
  9. Use theme-aware CSS variables or inline styles consistent with the existing app.
  10. Update frontend/src/App.tsx routing/nav so Home appears first and / plus * redirect to /home.
  11. 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:

  1. Run the relevant backend tests.
  2. Run the relevant frontend tests.
  3. Log in locally and visit /; verify Home is shown.
  4. Visit an unknown app URL; verify it redirects to Home.
  5. Verify Home appears before Problems in the top navigation.
  6. Toggle light/dark theme and verify activity intensity direction:
    • Light theme: darker cells mean higher activity.
    • Dark theme: lighter cells mean higher activity.
  7. Seed or create practice/exam activity and confirm the coverage and grid update after refresh.
  8. 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:

  • The implementation matches the expected Home dashboard behavior.
  • / and unknown routes now land on Home for authenticated users.
  • Home appears before Problems in the nav.
  • Coverage uses unique tried problems over total non-deleted problems.
  • Practice attempts and submitted exam items both contribute to activity.
  • Pending-review submitted exam items count as examined.
  • Other users' data is not included.
  • Deleted problems are excluded from total coverage.
  • The frontend does not assemble the dashboard from paginated history endpoints.
  • Required automated tests were added or updated.
  • The implementation is scoped to the requested Home dashboard and does not bundle unrelated refactors.
  • The PR includes self-verification commands and results.

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.

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions