Displaying Tasks List
Displaying a Tasks List: From Data to UI
Welcome back! In the last lesson, you learned how to show important statistics about your tasks on a dashboard. That gave users a “big picture” view of their progress.
Now, let’s take the next step: displaying a detailed list of tasks. This list will show every task’s title, status, and due date, and provide a button to view each task’s details. For now, this will be read-only — users can look but not edit or delete yet.
By the end of this lesson, you will know how to:
- Fetch a list of tasks from an API using SWR.
- Create a reusable Button component for consistent UI.
- Build a TaskRow component to display individual tasks.
- Put everything together in a Tasks page, handling loading, errors, and empty states.
Recap: From Stats to Lists
In the previous unit, you fetched all tasks from the backend (/api/tasks) and calculated summary numbers (total, completed, incomplete). That was a high-level overview.
In this unit, we’re using the same backend endpoint, but instead of summarizing tasks, we’ll display each one in detail. Think of it as zooming in:
- Dashboard → summary counts.
- Tasks page → detailed list of tasks.
The Reusable Button Component
Buttons are everywhere in web apps. To keep your UI consistent and avoid repeating code, we’ll use a reusable Button component.
Here’s the code:
Let’s break it down carefully:
ButtonProps
- We start with
ButtonHTMLAttributes<HTMLButtonElement>. This means our component accepts all the normal button props (onClick,disabled, etc.). - Then we add our own prop:
variant. This lets us choose styles ('primary' | 'secondary' | 'danger').
forwardRef
forwardRefis a React helper that lets us pass a ref down to the underlying<button>element.- A ref is like a direct reference to a DOM element. Other components can use it to focus the button, measure it, or integrate with accessibility tools.
In this course, we do not need advanced ref behavior yet, but using forwardRef makes the Button ready for common accessibility and focus-management integrations you may add later.
base
- A string of Tailwind CSS classes that apply to every button, no matter the variant.
- It sets things like
inline-flex(so text and icons align), padding (px-3 py-2), focus styles (focus:ring), and disabled styles.
styles
- An object that maps each variant to its specific colors.
- Example:
"primary"= blue background, white text."danger"= red background.
clsx
- A small utility library that combines multiple class strings into one.
- Here, it merges the base classes with the chosen
styles[variant]and any extraclassNamepassed in.
In this CodeSignal environment,
clsxmay be backed by a minimal local shim that supports the simple string-joining pattern used here. The fullclsxpackage supports richer patterns such as arrays and objects.
This design makes the button:
- Reusable (same code, different contexts).
- Consistent (all buttons share the same base look).
- Customizable (pick
variant="secondary"when needed).
Example usage:
The TaskRow Component: Displaying One Task
Now let’s build a component that shows a single task row in the list:
Breaking it down:
-
Layout
The outer<div>usesflexwithjustify-betweenso the task info is on the left and the button is on the right. -
Title and Status
The task’s title appears in bold.
Next to it, a status badge shows whether it’s completed or pending.
Conditional rendering is used: iftask.completedis true → green badge, else → yellow badge. -
Due Date
Another line shows the due date.
Iftask.dueDateexists, we display it. Otherwise, we show “No due date.” -
View Button
On the right side, we use our reusable Button component withvariant="secondary".
It’s wrapped in a Next.js<Link>. Clicking it navigates to a details page for that task (/tasks/[id]).
This demonstrates how we can compose components: Link handles navigation, and Button handles styling and behavior.
The Tasks Page: Bringing It All Together
Finally, we put everything into a full page that fetches tasks and renders them in a list:
Detailed explanation:
-
Data fetching
useSWR('/api/tasks', api.get)fetches the tasks array from the backend.
While waiting,isLoadingis true.
If something goes wrong,erroris set. -
Header bar
Shows the page title (“Tasks”).
A New Task button is included as a placeholder navigation affordance for a later course; creating tasks is not implemented in this read-only course. -
Loading & error states
IfisLoading→ show a gray “Loading tasks…” message.
Iferror→ show a red error message. -
Task list
If we have data, map through it and render a TaskRow for each task.
key={t.id}ensures React can track each row.
If no tasks exist, show a “No tasks yet” message.
This combination ensures that no matter the state (loading, error, empty, success), the page always gives users clear feedback.
Summary and Practice Preview
In this lesson, you:
- Reviewed how to fetch a list of tasks from the backend using SWR.
- Built a reusable Button component, learning about props, variants,
forwardRef,clsx, and refs. - Created a TaskRow component that conditionally renders status, due dates, and action buttons.
- Put everything together in a Tasks page that handles all states: loading, error, empty, and success.
Next, you’ll practice fetching and presenting data yourself — reinforcing how to design reusable UI and how to connect data from the backend to the frontend.
