Introduction

Tracking apps are becoming increasingly popular, whether for tracking deliveries, monitoring personal goals, or managing tasks. In this tutorial, we’ll create a simple tracking app using React.js. The app will track user activities or tasks, allowing users to add, delete, and update activities. This project will help you understand the fundamentals of React, including state management, event handling, and component-based architecture.

Project Overview

Features:

  1. Add new activities/tasks.
  2. Display a list of current activities.
  3. Update activity status (e.g., completed, in-progress).
  4. Delete activities.

Tools and Libraries Used

  • React.js: For building the user interface.
  • React Hooks: For managing state and lifecycle methods.
  • CSS: For styling the application.
  • Local Storage: For persisting data locally in the browser.

Step 1: Setting Up the React Project

First, ensure that Node.js is installed on your system. You can check this by running:

				
					node -v
				
			

If Node.js is not installed, download and install it from nodejs.org.

Now, let’s create a new React project using Create React App:

				
					npx create-react-app tracking-app
				
			

This command will create a new directory named tracking-app with all the necessary files to get started with a React project.

Step 2: Project Structure

Navigate to the tracking-app directory and start the development server:

				
					cd tracking-app
npm start
				
			

This will start a development server and open your new React app in a web browser.

Step 3: Creating the Main App Component

In your src directory, open App.js and modify it to set up the basic structure of our tracking app:

				
					// src/App.js

import React, { useState, useEffect } from 'react';
import './App.css';
import ActivityForm from './components/ActivityForm';
import ActivityList from './components/ActivityList';

function App() {
    const [activities, setActivities] = useState([]);

    useEffect(() => {
        const storedActivities = JSON.parse(localStorage.getItem('activities'));
        if (storedActivities) {
            setActivities(storedActivities);
        }
    }, []);

    useEffect(() => {
        localStorage.setItem('activities', JSON.stringify(activities));
    }, [activities]);

    const addActivity = (activity) => {
        setActivities([...activities, activity]);
    };

    const deleteActivity = (id) => {
        setActivities(activities.filter(activity => activity.id !== id));
    };

    const updateActivity = (id, updatedActivity) => {
        setActivities(activities.map(activity => 
            activity.id === id ? updatedActivity : activity
        ));
    };

    return (
        <div className="App">
            <h1>Activity Tracker</h1>
            <ActivityForm addActivity={addActivity} />
            <ActivityList 
                activities={activities} 
                deleteActivity={deleteActivity}
                updateActivity={updateActivity} 
            />
        </div>
    );
}

export default App;
				
			

Step 4: Creating the Activity Form Component

Create a new folder named components inside the src directory. Inside this folder, create a file named ActivityForm.js. This component will handle the input for adding new activities.

				
					// src/components/ActivityForm.js

import React, { useState } from 'react';

function ActivityForm({ addActivity }) {
    const [activity, setActivity] = useState('');
    const [status, setStatus] = useState('in-progress');

    const handleSubmit = (e) => {
        e.preventDefault();
        if (activity) {
            const newActivity = {
                id: Date.now(),
                name: activity,
                status: status,
            };
            addActivity(newActivity);
            setActivity('');
            setStatus('in-progress');
        }
    };

    return (
        <form onSubmit={handleSubmit} className="activity-form">
            <input
                type="text"
                placeholder="Enter an activity"
                value={activity}
                onChange={(e) => setActivity(e.target.value)}
            />
            <select value={status} onChange={(e) => setStatus(e.target.value)}>
                <option value="in-progress">In Progress</option>
                <option value="completed">Completed</option>
            </select>
            <button type="submit">Add Activity</button>
        </form>
    );
}

export default ActivityForm;
				
			

Step 5: Creating the Activity List Component

Next, create a component to display the list of activities. Inside the components folder, create a file named ActivityList.js.

				
					// src/components/ActivityList.js

import React from 'react';

function ActivityList({ activities, deleteActivity, updateActivity }) {
    const handleStatusChange = (id, status) => {
        const updatedActivity = activities.find(activity => activity.id === id);
        updatedActivity.status = status;
        updateActivity(id, updatedActivity);
    };

    return (
        <div className="activity-list">
            {activities.map((activity) => (
                <div key={activity.id} className="activity-item">
                    <span>{activity.name}</span>
                    <select 
                        value={activity.status} 
                        onChange={(e) => handleStatusChange(activity.id, e.target.value)}
                    >
                        <option value="in-progress">In Progress</option>
                        <option value="completed">Completed</option>
                    </select>
                    <button onClick={() => deleteActivity(activity.id)}>Delete</button>
                </div>
            ))}
        </div>
    );
}

export default ActivityList;
				
			

Step 6: Adding CSS for Styling

To make the app look better, let’s add some basic styling. Create a file named App.css in the src directory and add the following CSS:

				
					/* src/App.css */

.App {
    text-align: center;
    padding: 20px;
}

.activity-form {
    margin-bottom: 20px;
}

.activity-form input, .activity-form select, .activity-form button {
    padding: 10px;
    margin-right: 10px;
}

.activity-list {
    margin-top: 20px;
}

.activity-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 10px;
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 5px;
}

.activity-item span {
    flex: 1;
}
				
			

Step 7: Saving and Retrieving Data from Local Storage

We’ve implemented the use of the useEffect hook to save the activities to the browser’s local storage whenever the activities state changes. This ensures that even if the user refreshes the page, their data will still be available.

Step 8: Running the Tracking App

  • Save all your files and ensure you are in the tracking-app directory.

  • Run the development server:

				
					npm start
				
			
  • Open your web browser and go to http://localhost:3000 to see your tracking app in action.

Explanation of the Code

  1. Main App Component: Manages the overall state of the activities using the useState hook. It handles adding, deleting, and updating activities.
  2. ActivityForm Component: Provides an input field and a dropdown to add a new activity. On submission, it sends the new activity to the parent App component.
  3. ActivityList Component: Displays the list of current activities. Each activity can be marked as “In Progress” or “Completed” using a dropdown. Activities can also be deleted from the list.
  4. Local Storage: The app uses the browser’s local storage to persist data, ensuring that activities remain even after the page is refreshed.

Additional Features

To make this tracking app more robust and functional, consider adding the following features:

  • User Authentication: Allow users to log in and save their activities in a database.
  • Filter and Search: Implement filters to view only “In Progress” or “Completed” activities, and add a search function to find specific tasks.
  • Due Dates: Add due dates to activities and highlight overdue tasks.

Conclusion

Congratulations! You’ve built a simple but functional tracking app using React.js. This project demonstrates how to manage state, handle user inputs, and persist data using local storage. Feel free to expand and improve upon this app by adding more features or integrating a backend for more complex data management. Happy coding!