Open In App

Daily Activity Planner App with Next.js

Last Updated : 14 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Managing your tasks is one of the most important things in a hectic routine. In this article, we will see step-by-step procedure of creating a task manager app from scratch.

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

d

Final look

Prerequisites :

Approach to create Daily Activity Planner:

  • State Management: For efficient task and input field handling, use useState.
  • Input Handling: Put in place handlers for the name, priority, and deadline of each task.
  • Task Functions: Task operations are managed by functions such as addTask, EditTask, DeleteTask, and markDone.
  • Improve user experience (UX) by using filtered tasks to effortlessly filter tasks according to user-specified requirements.

Steps to create the Next JS Application:

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

npx create-next-app task-manager-app

Step 2: Change to the project directory:

cd task-manager-app

Project Structure:

a

Project Structure

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

"dependencies": {
"react": "^18",
"react-dom": "^18",
"next": "14.1.0"
}

Example: Create the required files as seen on folder structure and paste the code components as per the structure.

CSS
/* Home.module.css */

.App {
    font-family: 'Arial', sans-serif;
    margin: 30px auto;
    padding: 20px;
    max-width: 800px;
    background-color: #ffdbac;
    box-shadow: 0 2px 16px rgba(0, 0, 0, 0.1);
    border-radius: 15px;
}

.taskHeader {
    text-align: center;
    background-color: #f1c27d;
    color: #3b3b3a;
    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 #3e3730;
    border-radius: 4px;
    flex-grow: 1;
    font-size: 16px;
    color: #f5f5f5;
}

.taskPrioritySelect {
    cursor: pointer;
    background-color: #e0ac69;
}

.addTaskButton {
    background-color: #e0ac69;
    color: rgb(253, 253, 253);
    border: none;
    cursor: pointer;
    transition: background-color 0.3s;
}

.addTaskButton:hover {
    background-color: #e4c193d4;
}

.searchFilter {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.searchInput,
.filterPrioritySelect {
    padding: 10px;
    border: 1px solid #b8b8b8f6;
    border-radius: 4px;
    flex-grow: 1;
    font-size: 16px;
}

.heading {
    color: black;
    text-align: center;
    font-weight: 400;
}

.completedHeading {
    color: black;
    text-align: center;
    font-weight: 400;
}

.taskTable {
    width: 100%;
    border-collapse: collapse;
    background-color: #8d5524;
}

.taskTable th,
.taskTable td {
    padding: 10px;
    text-align: center;
}

.taskTable th {
    background-color: #a88a63;
    color: white;
}

.taskTable tbody tr:nth-child(even) {
    background-color: #836338;
}

.completedTable {
    width: 100%;
    border-collapse: collapse;
    background-color: #8d5524;
}

.completedTable th,
.completedTable td {
    padding: 10px;
    text-align: center;
}

.completedTable th {
    background-color: #a88a63;
    color: white;
}

.completedTable tbody tr:nth-child(even) {
    background-color: #836338;
}

.deleteTaskButton {
    margin-right: 5px;
    cursor: pointer;
    padding: 12px;
    background: rgba(224, 43, 43, 0.595);
    border-radius: 10px;
    border: none;
    color: white;
}

.deleteTaskButton:hover {
    background: red;
}

.markDoneButton,
.editTaskButton {
    margin-right: 5px;
    cursor: pointer;
    padding: 12px;
    background: #218a1574;
    border-radius: 10px;
    border: none;
    color: white;
}

.markDoneButton:hover {
    background: rgb(23, 175, 23);
}

.editTaskButton:hover {
    background: rgb(23, 175, 23);
}

@media (max-width: 600px) {
    .taskForm {
        flex-direction: column;
    }

    .searchFilter {
        flex-direction: column;
    }
}
Javascript
// pages/index.js

import TaskScheduler from "../components/TaskScheduler";

export default TaskScheduler;
Javascript
// src/components/CompletedTaskList.js

import React from 'react';
import styles from '../styles/Home.module.css';

const CompletedTaskList = ({ completedTasks }) => {
    return (
        <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>
    );
};

export default CompletedTaskList;
Javascript
// src/components/TaskForm.js

import styles from "../styles/Home.module.css";

const TaskForm = ({
    taskName,
    taskPriority,
    taskDeadline,
    handleTaskNameChange,
    handleTaskPriorityChange,
    handleTaskDeadlineChange,
    addTask
}) => {
    return (
        <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">High Priority</option>
                <option value="Middle">Medium Priority</option>
                <option value="Low">Not Important</option>
            </select>
            <input
                type="date"
                className={styles.taskDeadlineInput}
                value={taskDeadline}
                onChange={handleTaskDeadlineChange}
            />
            <button className={styles.addTaskButton} onClick={addTask}>
                Add Task
            </button>
        </div>
    );
};

export default TaskForm;
Javascript
// src/components/TaskList.js

import React from 'react';
import styles from '../styles/Home.module.css';

const TaskList = ({
    tasks,
    markDone,
    handleEditTask,
    handleDeleteTask
}) => {
    return (
        <div className={styles.taskList}>
            <table className={styles.taskTable}>
                <thead>
                    <tr>
                        <th>Name</th>
                        <th>Priority</th>
                        <th>Deadline</th>
                        <th>State</th>
                    </tr>
                </thead>
                <tbody>
                    {tasks.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)}
                                        >
                                            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>
    );
};

export default TaskList; 
Javascript
// src/components/TaskScheduler.js

import React, { useState, useEffect } from "react";
import Head from "next/head";
import styles from "../styles/Home.module.css";
import TaskForm from '../components/TaskForm';
import TaskList from '../components/TaskList';
import CompletedTaskList from '../components/CompletedTaskList';

const TaskScheduler = () => {
    const [tasks, setTasks] = useState([]);
    const [completedTasks, setCompletedTasks] = useState([]);
    const [taskName, setTaskName] = useState("");
    const [taskPriority, setTaskPriority] = useState("Top");
    const [taskVal, setTaskDeadline] = useState("");
    const [searchKeyword, setSearchKeyword] = useState("");
    const [filterPriority, setFilterPriority] = useState("");

    const TASKS_STORAGE_KEY = "tasks";
    const COMPLETED_TASKS_STORAGE_KEY = "completedTasks";

    useEffect(() => {
        const storedTasks = JSON.parse(localStorage.getItem(TASKS_STORAGE_KEY));
        if (storedTasks) {
            setTasks(storedTasks);
        }

        const storedCompletedTasks = JSON.parse(localStorage.getItem(COMPLETED_TASKS_STORAGE_KEY));
        if (storedCompletedTasks) {
            setCompletedTasks(storedCompletedTasks);
        }
    }, []);

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

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

    const handleTaskNameChange = (e) => {
        6
        setTaskName(e.target.value);
    };

    const handleTaskPriorityChange = (e) => {
        setTaskPriority(e.target.value);
    };

    const handleTaskDeadlineChange = (e) => {
        setTaskDeadline(e.target.value);
    };

    const addTask = () => {
        if (taskName.trim() === "" || taskVal === "") {
            alert("Enter a task, Must not Empty!!!");
            return;
        }

        const selDate = new Date(taskVal);
        const currDate = new Date();

        if (selDate <= currDate) {
            alert("Can't go back in time.");
            return;
        }

        const newTask = {
            id: tasks.length + 1,
            task: taskName,
            priority: taskPriority,
            deadline: taskVal,
            done: false,
        };

        // Fetch existing tasks from local storage
        const existingTasks = JSON.parse(localStorage.getItem(TASKS_STORAGE_KEY)) || [];

        // Append the new task to existing tasks
        const updatedTasks = [...existingTasks, newTask];

        // Update tasks state
        setTasks(updatedTasks);

        // Update local storage with combined old and new tasks
        localStorage.setItem(TASKS_STORAGE_KEY, JSON.stringify(updatedTasks));

        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 Manager - Geeksforgeeks.org</title>
            </Head>
            <header className={styles.taskHeader}>
                <h1>Task Manager</h1>
            </header>
            <main>
                <TaskForm
                    taskName={taskName}
                    taskPriority={taskPriority}
                    taskDeadline={taskVal}
                    handleTaskNameChange={handleTaskNameChange}
                    handleTaskPriorityChange={handleTaskPriorityChange}
                    handleTaskDeadlineChange={handleTaskDeadlineChange}
                    addTask={addTask}
                />
                {/* Search and Filter Component */}
                <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</option>
                        <option value="Top">High Priority</option>
                        <option value="Middle">Medium Priority</option>
                        <option value="Low">Not Important</option>
                    </select>
                </div>
                <h2 className={styles.heading}>Tasks</h2>
                <TaskList
                    tasks={filteredTasks}
                    markDone={markDone}
                    handleEditTask={handleEditTask}
                    handleDeleteTask={handleDeleteTask}
                />
                <CompletedTaskList completedTasks={completedTasks} />
            </main>
        </div>
    );
};

export default TaskScheduler;

Steps to run the application:

Step 1: Run this command to start the application:

npm run dev

Step 2: Visit the URL:

http://localhost:3000

Output:

Daily Activity Planner App

Daily Activity Planner App



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads