Open In App

Build a Task Management App using Next JS

Last Updated : 22 Nov, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

A Task management app is a useful web application that assists in efficiently organizing and managing tasks. It provides various functionalities such as creating tasks, assigning prioritie­s and deadlines, marking complete tasks, and enabling task search based on ke­ywords and priorities.

Preview of final output: Let us have a look at how the final output will look like

Build-a-Task-Management-App-using-Next-Js

Prerequisites :

Approach :

  • The use­State hook is employed to e­ffectively manage compone­nt state, ensuring smooth handling of tasks and input fields re­lated to task management, se­arch, and filtering.
  • To handle task-relate­d information such as name, priority, and deadline, thre­e input handlers are imple­mented to update the­ir respective state­ variables.
  • The addTask function is responsible­ for both validating and adding tasks, while the handleEditTask function facilitate­s task editing and removal.
  • Additionally, the handle­DeleteTask function re­moves tasks when nece­ssary, whereas the markDone­ function marks tasks as completed and moves the­m to the completedTasks se­ction.
  • To further enhance use­r experience­, filteredTasks effe­ctively filters upcoming tasks based on use­r-defined criteria such as se­arching and filtering by priority.

Steps to create the Next JS Application:

Step 1: Create a new Next.js project using the following command

npx create-next-app task-management-app

Step 2: Change to the project directory:

cd task-management-app

Project Structure:

The updated dependencies in package.json file will look like :

"dependencies": {
"next": "^13.0.6",
"react": "^18.2.0",
"react-dom": "^18.2.0"
}

Example: In this example, we will create the Task Management App Using Next Js.

Javascript




//index.js
 
import { useState } from "react";
import Head from "next/head";
import styles from "../styles/Home.module.css";
 
export default function TaskScheduler() {
    const [tasks, setTasks] = useState([]);
    const [completedTasks, setCompletedTasks] = useState([]);
    const [taskName, setTaskName] = useState("");
    const [taskPriority, setTaskPriority] = useState("Top");
    const [taskDeadline, setTaskDeadline] = useState("");
    const [searchKeyword, setSearchKeyword] = useState("");
    const [filterPriority, setFilterPriority] = useState("");
 
    const handleTaskNameChange = (e) => {
        setTaskName(e.target.value);
    };
 
    const handleTaskPriorityChange = (e) => {
        setTaskPriority(e.target.value);
    };
 
    const handleTaskDeadlineChange = (e) => {
        setTaskDeadline(e.target.value);
    };
 
    const addTask = () => {
        if (taskName.trim() === "" || taskDeadline === "") {
            alert("Please enter a task and select a valid deadline.");
            return;
        }
 
        const selectedDate = new Date(taskDeadline);
        const currentDate = new Date();
 
        if (selectedDate <= currentDate) {
            alert("Please select a future date for the deadline.");
            return;
        }
 
        const newTask = {
            id: tasks.length + 1,
            task: taskName,
            priority: taskPriority,
            deadline: taskDeadline,
            done: false,
        };
 
        setTasks([...tasks, newTask]);
 
        setTaskName("");
        setTaskPriority("Top");
        setTaskDeadline("");
    };
 
    const handleEditTask = (id) => {
        const taskToEdit = tasks.find((t) => t.id === id);
        setTaskName(taskToEdit.task);
        setTaskPriority(taskToEdit.priority);
        setTaskDeadline(taskToEdit.deadline);
        const updatedTasks = tasks.filter((t) => t.id !== id);
        setTasks(updatedTasks);
    };
 
    const handleDeleteTask = (id) => {
        const updatedTasks = tasks.filter((t) => t.id !== id);
        setTasks(updatedTasks);
    };
 
    const markDone = (id) => {
        const updatedTasks = tasks.map((t) =>
            t.id === id ? { ...t, done: true } : t
        );
        setTasks(updatedTasks);
 
        const completedTask = tasks.find((t) => t.id === id);
        if (completedTask) {
            setCompletedTasks([...completedTasks, completedTask]);
        }
    };
 
    const filteredTasks = tasks
        .filter((t) => !t.done)
        .filter((t) =>
            t.task.toLowerCase().includes(searchKeyword.toLowerCase())
        )
        .filter((t) => (filterPriority ? t.priority === filterPriority : true));
 
    return (
        <div className={styles.App}>
            <Head>
                <title>Task Management - Geeksforgeeks.org</title>
            </Head>
            <header className={styles.taskHeader}>
                <h1>Task Management</h1>
            </header>
            <main>
                <div className={styles.taskForm}>
                    <input
                        type="text"
                        className={styles.taskNameInput}
                        placeholder="Enter task..."
                        value={taskName}
                        onChange={handleTaskNameChange}
                    />
                    <select
                        className={styles.taskPrioritySelect}
                        value={taskPriority}
                        onChange={handleTaskPriorityChange}
                    >
                        <option value="Top">Top Priority</option>
                        <option value="Middle">Middle Priority</option>
                        <option value="Low">Less Priority</option>
                    </select>
                    <input
                        type="date"
                        className={styles.taskDeadlineInput}
                        value={taskDeadline}
                        onChange={handleTaskDeadlineChange}
                    />
                    <button className={styles.addTaskButton} onClick={addTask}>
                        Add Task
                    </button>
                </div>
                <div className={styles.searchFilter}>
                    <input
                        type="text"
                        className={styles.searchInput}
                        placeholder="Search tasks"
                        value={searchKeyword}
                        onChange={(e) => setSearchKeyword(e.target.value)}
                    />
                    <select
                        className={styles.filterPrioritySelect}
                        value={filterPriority}
                        onChange={(e) => setFilterPriority(e.target.value)}
                    >
                        <option value="">All Priorities</option>
                        <option value="Top">Top Priority</option>
                        <option value="Middle">Middle Priority</option>
                        <option value="Low">Less Priority</option>
                    </select>
                </div>
                <h2 className={styles.heading}>Upcoming Tasks</h2>
                <div className={styles.taskList}>
                    <table className={styles.taskTable}>
                        <thead>
                            <tr>
                                <th>Task Name</th>
                                <th>Priority</th>
                                <th>Deadline</th>
                                <th>Action</th>
                            </tr>
                        </thead>
                        <tbody>
                            {filteredTasks.map((t) => (
                                <tr key={t.id}>
                                    <td>{t.task}</td>
                                    <td>{t.priority}</td>
                                    <td>{t.deadline}</td>
                                    <td>
                                        {!t.done && (
                                            <div>
                                                <button
                                                    className={
                                                        styles.markDoneButton
                                                    }
                                                    onClick={() =>
                                                        markDone(t.id)
                                                    }
                                                >
                                                    Mark Done
                                                </button>
                                                <button
                                                    className={
                                                        styles.editTaskButton
                                                    }
                                                    onClick={() =>
                                                        handleEditTask(t.id)
                                                    }
                                                >
                                                    Edit
                                                </button>
                                                <button
                                                    className={
                                                        styles.deleteTaskButton
                                                    }
                                                    onClick={() =>
                                                        handleDeleteTask(t.id)
                                                    }
                                                >
                                                    Delete
                                                </button>
                                            </div>
                                        )}
                                    </td>
                                </tr>
                            ))}
                        </tbody>
                    </table>
                </div>
                <div className={styles.completedTaskList}>
                    <h2 className={styles.completedHeading}>Completed Tasks</h2>
                    <table className={styles.completedTable}>
                        <thead>
                            <tr>
                                <th>Task Name</th>
                                <th>Priority</th>
                                <th>Deadline</th>
                            </tr>
                        </thead>
                        <tbody>
                            {completedTasks.map((ct) => (
                                <tr key={ct.id}>
                                    <td>{ct.task}</td>
                                    <td>{ct.priority}</td>
                                    <td>{ct.deadline}</td>
                                </tr>
                            ))}
                        </tbody>
                    </table>
                </div>
            </main>
        </div>
    );
}


CSS




/* global.css */
 
.App {
    font-family: 'Arial', sans-serif;
    margin: 30px auto;
    padding: 20px;
    max-width: 800px;
    background-color: white;
    box-shadow: 0 2px 16px rgba(0, 0, 0, 0.1);
    border-radius: 15px;
}
 
.taskHeader {
    text-align: center;
    background-color: #007bff;
    color: white;
    padding: 10px 0;
    margin-bottom: 20px;
    border-radius: 8px 8px 0 0;
}
 
.taskForm {
    margin-bottom: 20px;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
}
 
.taskNameInput,
.taskPrioritySelect,
.taskDeadlineInput,
.addTaskButton {
    margin: 5px;
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 4px;
    flex-grow: 1;
    font-size: 16px;
}
 
.taskPrioritySelect {
    cursor: pointer;
    background-color: #f0f0f0;
}
 
.addTaskButton {
    background-color: #007bff;
    color: white;
    border: none;
    cursor: pointer;
    transition: background-color 0.3s;
}
 
.addTaskButton:hover {
    background-color: #0056b3;
}
 
.searchFilter {
    display: flex;
    justify-content: space-between;
    align-items: center;
}
 
.searchInput,
.filterPrioritySelect {
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 4px;
    flex-grow: 1;
    font-size: 16px;
}
 
.taskTable {
    width: 100%;
    border-collapse: collapse;
    background-color: white;
}
 
.taskTable th,
.taskTable td {
    padding: 10px;
    text-align: left;
}
 
.taskTable th {
    background-color: #007bff;
    color: white;
}
 
.taskTable tbody tr:nth-child(even) {
    background-color: #f5f5f5;
}
 
.completedTable {
    width: 100%;
    border-collapse: collapse;
    background-color: white;
}
 
.completedTable th,
.completedTable td {
    padding: 10px;
    text-align: left;
}
 
.completedTable th {
    background-color: #007bff;
    color: white;
}
 
.completedTable tbody tr:nth-child(even) {
    background-color: #f5f5f5;
}
 
.deleteTaskButton {
    margin-right: 5px;
    cursor: pointer;
    padding: 12px;
    background: crimson;
    border-radius: 10px;
    border: none;
    color: white;
}
 
.markDoneButton,
.editTaskButton {
    margin-right: 5px;
    cursor: pointer;
    padding: 12px;
    background: #007bff;
    border-radius: 10px;
    border: none;
    color: white;
}
 
@media (max-width: 600px) {
    .taskForm {
        flex-direction: column;
    }
 
    .searchFilter {
        flex-direction: column;
    }
}


Steps to run the application:

Step 1: Run this command to start the application:

npm run dev

Step 2: To run the next.js application use the following command and then go to this URL:

http://localhost:3000

Output:

Build-a-Task-Management-App-using-Next-Js



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads