Building a User Dashboard

Introduction: Why User Stats Matter

Welcome back! So far, you have learned how to fetch and display a user’s reading shelf, update progress optimistically, edit shelf status, and validate forms. In this lesson, you will take the next step by building a user stats dashboard. This dashboard gives users a clear overview of their reading achievements, such as how many books they have on their shelf, how many they have completed, and their average reading progress.

A user stats dashboard is important because it helps users track their progress and stay motivated. By the end of this lesson, you will know how to fetch user stats from the backend, process the data, and display it in a visually appealing way using React components.

Our app already lets readers build a shelf, update progress with optimistic UI, edit statuses, and validate inputs with Zod + React Hook Form. The next leap is a dashboard-style overview that turns scattered data into actionable insight. A concise stats header—books on shelf, completed count, and average progress—gives users motivation, a sense of achievement, and a quick health check of their reading habits. In this lesson, you will fetch stats from the backend, normalize them for display, and present them with small, reusable React components that slot right into your existing MyShelfPage.

Building a User Dashboard

// src/api/users.ts
import { apiClient } from "./client";
import type { UserStats } from "../lib/types";

export async function getUserStats(userId: number): Promise<UserStats> {
  const res = await apiClient.get<any>(`api/users/${userId}/stats`);
  const raw = (res?.data ?? res) as any;
  const normalized: UserStats = {
    userId: raw.userId,
    totalPagesRead: raw.totalPagesRead,
    booksInShelf: raw.booksInShelf,
    booksCompleted: raw.booksCompleted,
    avgProgressPct:
      typeof raw.avgProgressPct === "number" ? raw.avgProgressPct * 100 : 0,
  };
  return normalized;
}

Explanation:

  • The function takes a userId and fetches stats from the API.
  • The API returns avgProgressPct as a number between 0 and 1. To make it easier to display as a percentage, the function multiplies it by 100.
  • The function returns a normalized UserStats object, which is easier to use in your React components.

Example Output:
If the API returns:

{
  "userId": 1,
  "totalPagesRead": 1200,
  "booksInShelf": 5,
  "booksCompleted": 2,
  "avgProgressPct": 0.65
}

The function will return:

{
  "userId": 1,
  "totalPagesRead": 1200,
  "booksInShelf": 5,
  "booksCompleted": 2,
  "avgProgressPct": 65
}
Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal