Dashboard Stats Overview
Dashboard Stats Overview: Visualizing Task Progress
Welcome back! In the previous lesson, you built the foundation of your application by creating an app shell and a dashboard layout with consistent navigation and styling. Now, we’re going to bring that layout to life by adding a dashboard overview that displays important task statistics.
A dashboard is a central place where users can quickly see the most important information at a glance. In our case, that means showing how many tasks exist, how many are completed, and how many are incomplete. This gives users a clear sense of progress and helps them stay organized.
By the end of this lesson, you’ll know how to:
- Fetch data from your backend API.
- Understand what “fetching” means and what a GET request does.
- Calculate statistics from raw task data.
- Display those statistics in styled components using Tailwind CSS.
Recap: App Shell and Data Source
In the last lesson, you created:
- A root layout (
layout.tsx) that provides global HTML structure. - A dashboard layout (
(dashboard)/layout.tsx) that provides navigation and a header. - A
page.tsxthat wires everything together.
Here’s that main page.tsx file again for reference:
In this unit, we focus on DashboardPage. This is where we’ll connect to the backend, fetch task data, and show meaningful statistics.
Understanding the Backend Route
Before we fetch data, let’s remind ourselves where that data comes from.
In your project, the backend lives under src/app/api. Specifically, the file src/app/api/tasks/route.ts defines the tasks API route. This is a GET endpoint, which means when your browser (or frontend code) requests data from /api/tasks, the backend responds with a JSON object containing tasks.
For example, a GET request to /api/tasks might return something like this:
Breaking this down:
"data"is an array of tasks. Each task has fields likeid,title,content, andcompleted."meta"contains extra information, such as when the response was created.
This response is in JSON (JavaScript Object Notation), which is a text-based format commonly used for sending data between servers and clients. JSON looks like JavaScript objects and is easy for both humans and code to read.
What Does “Fetching” Data Mean?
When we say “fetching data,” we mean sending a request from the frontend to the backend and then waiting for a response.
- The frontend sends an HTTP request.
- In this case, it’s a GET request, which is the standard way to ask a server for data (as opposed to POST, which creates data, or DELETE, which removes it).
- The backend receives the request at
/api/tasks, looks up the tasks, and sends back a JSON response. - The frontend receives that JSON and uses it to update the UI.
So when our code calls fetch('/api/tasks'), it’s like asking:
“Hey backend, please give me the current list of tasks.”
And the backend replies with a JSON list of tasks.
The API Client: Talking to the Backend
To make this process easier and consistent, we use a small helper called an API client. Here’s the code:
Step by step:
- The
getfunction callsfetch(url). fetchis a built-in browser function for making HTTP requests.- Here,
urlwill be something like/api/tasks. - If the response isn’t OK (for example, the server returned an error), we throw an error.
- Otherwise, we parse the JSON response with
await res.json(). - Many of our backend routes wrap results in a
datafield, so we return thedataproperty when that key is present; otherwise, we return the whole JSON response.
This keeps all our data-fetching logic in one place. Instead of writing fetch logic every time, we just call api.get.
Fetching Data With SWR
Next, let’s see how our dashboard uses this API client together with SWR (a data-fetching library for React):
Here’s what’s happening:
useSWRis a React hook for data fetching.- It takes two arguments:
- The key (or endpoint) →
'/api/tasks'. - A fetcher function →
api.get, which actually does the request.
- The key (or endpoint) →
SWR automatically:
- Calls our API and loads the data.
- Keeps it fresh if the page refocuses or reconnects.
- Provides states like loading and error if we want to handle them.
By the time the request succeeds, data contains the array of tasks returned from the backend. We then check Array.isArray(data) to ensure we always have a safe array to work with.
Calculating Task Statistics
Now that we have the tasks, we want to calculate statistics that are meaningful to users:
tasks.length→ the total number of tasks..filter((t) => t.completed)→ a new array containing only completed tasks. We take its length.incomplete→ the remainder (total minus completed).
This is a good example of using array methods in JavaScript to transform and summarize data.
Displaying Stats With a Card Component
The last step is to display the statistics on the screen. For that, we create a simple helper component called StatCard:
Explanation:
- The card displays a title (like “Completed”) and a value (like 5).
- Tailwind classes style it:
rounded-lg= rounded corners.border bg-white= card appearance.shadow-sm= subtle drop shadow.
Finally, we render three cards in a responsive grid:
On mobile, the cards stack vertically (grid-cols-1). On larger screens, they show side by side in three columns (sm:grid-cols-3). This makes the layout responsive with just a few Tailwind classes.
How It All Fits Together
Let’s zoom out and connect the dots:
- Backend route (
/api/tasks) returns a JSON list of tasks when you send a GET request. - API client (
apiClient.ts) wraps fetch so you can easily request and parse responses. - SWR hook calls the API client, keeps the data fresh, and stores it in
data. DashboardPagecalculates totals and usesStatCardsto display them.- Layouts (
layout.tsxand(dashboard)/layout.tsx) wrap everything in consistent structure and styling.
This is a full round trip: from backend data, through fetching and processing, to rendering on the frontend.
Review and What’s Next
In this lesson, you:
- Learned what it means to make a GET request and fetch data from an API.
- Explored the
/api/tasksbackend route and saw the kind of JSON response it returns. - Used an API client and the SWR hook to request and manage data on the frontend.
- Calculated total, completed, and incomplete tasks from the raw array.
- Displayed those statistics with styled cards in the dashboard layout.
Next, you’ll practice fetching and presenting data yourself. You’ll strengthen your understanding of how the frontend and backend work together — the frontend requests data, the backend responds with JSON, and React renders it into a meaningful UI.
