Skip to content

adanSiqueira/task-manager-react

Repository files navigation

Task Manager

A simple Task Manager application built with React to practice modern frontend concepts including component architecture, hooks, routing, browser APIs, and UI composition.

The project demonstrates how to build a small but complete React application using functional components, state management with hooks, localStorage persistence, and client-side routing.


Overview

This application allows users to:

  • Create tasks with title and description
  • Mark tasks as completed
  • Delete tasks
  • Persist tasks locally in the browser
  • Navigate to a Task Details page using URL query parameters

The project was designed as a learning-focused architecture to practice:

  • React component design
  • Hooks (useState, useEffect)
  • React Router
  • Browser APIs
  • Reusable UI components
  • Basic UI composition with TailwindCSS

Application Preview

Main features include:

  • Task creation form
  • Task list with completion toggle
  • Task deletion
  • Task details page
  • Local persistence using localStorage

Tech Stack

Frontend

  • React
  • Vite
  • React Router DOM
  • TailwindCSS
  • Lucide Icons

Browser APIs

  • localStorage
  • Fetch API (example included)

Project Structure

src
│
├── components
│   ├── AddTask.jsx
│   ├── Button.jsx
│   ├── Input.jsx
│   ├── Tasks.jsx
│   └── Title.jsx
│
├── pages
│   └── TaskPage.jsx
│
├── App.jsx
├── main.jsx
│
public
assets

Architecture Overview

The project follows a component-driven architecture commonly used in React applications.

Main layers

Layer Responsibility
Pages Route-level components
Components Reusable UI components
App Global state management
Router Client-side navigation

Core React Concepts Demonstrated

State Management

The global task state is managed in App.jsx using React's useState hook.

const [tasks, setTasks] = useState(
  JSON.parse(localStorage.getItem("tasks")) || []
);

Tasks are stored as objects:

{
  id: number,
  title: string,
  description: string,
  isCompleted: boolean
}

Side Effects with useEffect

useEffect is used to persist the state to localStorage whenever tasks change.

useEffect(() => {
  localStorage.setItem("tasks", JSON.stringify(tasks))
}, [tasks])

This ensures tasks persist across browser reloads.


Component Composition

The UI is composed using small reusable components.

Example:

App
 ├── Title
 ├── AddTask
 └── Tasks
      ├── Button
      ├── Button
      └── Task Item

This pattern improves:

  • readability
  • reuse
  • maintainability

Routing

Client-side navigation is implemented using React Router.

createBrowserRouter([
  { path: "/", element: <App /> },
  { path: "/task", element: <TaskPage /> }
])

The Task Details page receives data through URL query parameters.

Example URL:

/task?title=Buy%20Milk&description=Go%20to%20the%20market

Query parameters are accessed using:

useSearchParams()

UI Components

Title

Reusable heading component for page titles.

Input

A generic styled input component using prop spreading.

<input {...props} />

This allows flexible usage without redefining props.


Button

Reusable button wrapper component.

Benefits:

  • consistent styling
  • reusable behavior
  • clean JSX structure

AddTask

Handles:

  • controlled inputs
  • validation
  • task submission

Uses useState for local form state.


Tasks

Responsible for:

  • rendering the task list
  • task interactions
  • navigation to the task details page

Data Persistence

Tasks are persisted using the browser localStorage API.

Advantages:

  • no backend required
  • fast
  • simple for small applications

Example API Integration Pattern

The project also contains a commented example of fetching tasks from an external API using fetch and useEffect.

This demonstrates a common React pattern:

useEffect
   → fetch API
       → parse JSON
           → update state

Example source used:

https://jsonplaceholder.typicode.com/todos

Installation

Clone the repository:

git clone https://github.com/your-username/task-manager.git

Enter the project directory:

cd task-manager

Install dependencies:

npm install

Start the development server:

npm run dev

Open in browser:

http://localhost:5173

Design Patterns and Technical Decisions

Controlled Components

Form inputs are implemented using controlled components:

value={title}
onChange={(e) => setTitle(e.target.value)}

Benefits:

  • predictable state
  • validation control
  • easier debugging

Immutable State Updates

Task updates use immutable patterns:

setTasks(tasks.map(task => ...))

This follows React best practices for state updates.


Prop Drilling

Callbacks are passed from parent to children:

onTaskClick
onDeleteTaskClick
onAddTaskSubmit

This keeps state centralized in App.jsx.


URL-based State

Task details are passed via query parameters, demonstrating how applications can store state in URLs.


Future Improvements

Possible next steps for the project:

  • Add TypeScript
  • Add Context API or Zustand for global state
  • Add Drag & Drop task ordering
  • Add task editing
  • Add dark mode
  • Persist tasks using a backend API
  • Add unit tests with Jest + React Testing Library

About

Task manager built with React, demonstrating component architecture, hooks, routing, and localStorage persistence.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors