Task Manager Program Blog

1. Introduction

1.1 Overview of the Task Manager Program

In this project, I developed a task manager program designed to help users track their tasks efficiently. The application enables users to add, update, delete, and view tasks, with features powered by both frontend and backend technologies.

1.2 Purpose of the Program

The goal of the program is to provide an easy-to-use platform where users can manage their daily tasks. It integrates a full-stack architecture that uses a database to store task data and APIs to interact with the data dynamically. And if you have no idea what tasks to create you always have the option to use the “random-tasks” api which is mainly focused on the big idea 1 following crud operations and Algorthims and programming and also data anyalsis.


2. Purpose of Your Individual Feature(s)

2.1 Feature Overview

My individual feature within the program is the creation of the Task Manager API, which includes four main operations:

  • Create: Allows users to add tasks.
  • Read: Displays all tasks or individual task details.
  • Update: Modifies an existing task.
  • Delete: Removes a task from the database.

Each of these operations corresponds to an API endpoint and interacts directly with a database to persist and retrieve task data.


3. Input/Output Requests

3.1 Frontend API Request and Response

3.1.1 API Request (Frontend)

To interact with the backend, the frontend makes an HTTP request using JavaScript. For example, when a user submits a form to add a new task, a POST request is made to the /api/tasks endpoint.

fetch('/api/tasks', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    task: "Review the key concepts from your last CSP lesson."
  })
})
.then(response => response.json())
.then(data => {
  console.log('Task added:', data);
})
.catch(error => console.error('Error:', error));

Big Idea One CRUD Operations

HTTP Method Endpoint Description Image in Postman
GET http://127.0.0.1:8887/api/tasks/5 Proof of the GET method working. GET Image
POST http://127.0.0.1:8887/api/tasks Proof of the POST method working. POST Image
PUT http://127.0.0.1:8887/api/tasks/5 Proof of the PUT method working. PUT Image 1
PUT Image 2
DELETE http://127.0.0.1:8887/api/tasks/5 Proof of the DELETE method working. DELETE Image
Random Tasks http://127.0.0.1:8887/api/random-tasks Example of a random task endpoint calling these categories. Random Task Image

Big Idea 1: Creative Development

  • Program Purpose and Function – The project includes a clear purpose (managing tasks via CRUD operations).
  • Algorithm Implementation – Each CRUD operation follows a structured algorithm (handling requests and responses).
  • Procedural Abstraction – The API endpoints abstract complex logic into reusable functions.
  • Testing and Debugging – Using Postman to verify the functionality of API endpoints demonstrates testing.

Big Idea 3: Data

  • Data Abstraction – The API stores and retrieves structured task data, making it easier to manage.
  • Managing Data – The project creates, reads, updates, and deletes data, showing how data is modified dynamically.
  • Data Representation – Tasks are stored and manipulated using JSON, demonstrating structured data storage.
# CREATE - Add a new task
@addtaskapi.route('/api/tasks', methods=['POST'])
def add_task():
    data = request.get_json()
    newtask = data.get('task')

    if not newtask:
        return jsonify({'error': 'Missing task data'}), 400

    new_task = Task(task=newtask)
    try:
        new_task.create()
        return jsonify({'message': 'Task added successfully', 'task_id': new_task.id}), 201
    except Exception as e:
        return jsonify({'error': str(e)}), 500

# READ - Get all tasks
@addtaskapi.route('/api/tasks', methods=['GET'])
def get_tasks():
    tasks = Task.query.all()
    return jsonify([task.read() for task in tasks]), 200

# READ - Get a single task by ID
@addtaskapi.route('/api/tasks/<int:task_id>', methods=['GET'])
def get_task(task_id):
    task = Task.query.get(task_id)
    if not task:
        return jsonify({'error': 'Task not found'}), 404
    return jsonify(task.read()), 200

# UPDATE - Modify an existing task
@addtaskapi.route('/api/tasks/<int:task_id>', methods=['PUT'])
def update_task(task_id):
    data = request.get_json()
    task = Task.query.get(task_id)
    if not task:
        return jsonify({'error': 'Task not found'}), 404

    new_task_data = data.get('task')
    if not new_task_data:
        return jsonify({'error': 'Missing task data'}), 400

    try:
        task._task = new_task_data  # Update the task field
        task.update(None)  # Call update method
        return jsonify({'message': 'Task updated successfully'}), 200
    except Exception as e:
        return jsonify({'error': str(e)}), 500

# DELETE - Remove a task
@addtaskapi.route('/api/tasks/<int:task_id>', methods=['DELETE'])
def delete_task(task_id):
    task = Task.query.get(task_id)
    if not task:
        return jsonify({'error': 'Task not found'}), 404

    try:
        task.delete()
        return jsonify({'message': 'Task deleted successfully'}), 200
    except Exception as e:
        return jsonify({'error': str(e)}), 500

My frontend visual page

Image

Image

My frontend DOM methods

document.addEventListener("DOMContentLoaded", () => {
    const titleInput = document.getElementById("title-input");
    const addTaskButton = document.getElementById("add-task-button");
    const taskList = document.getElementById("task-list");
    const errorMessage = document.getElementById("error-message");

    // Edit elements
    const editTaskContainer = document.getElementById("edit-task-container");
    const editTitleInput = document.getElementById("edit-title-input");
    const updateTaskButton = document.getElementById("update-task-button");
    const overlay = document.getElementById("overlay");
    let editingTaskId = null;

    // Fetch and render tasks
    async function renderTasks() {
        try {
            const response = await fetch("http://127.0.0.1:8887/api/tasks");
            const tasks = await response.json();
            taskList.innerHTML = "";

            tasks.forEach((task) => {
                const row = document.createElement("tr");
                row.innerHTML = `
                    <td>${task.task}</td>
                    <td>
                        <button class="edit-btn" onclick="editTask(${task.id}, '${task.task}')">Edit</button>
                        <button class="delete-btn" onclick="deleteTask(${task.id})">Delete</button>
                    </td>
                `;
                taskList.appendChild(row);
            });
        } catch (error) {
            console.error("Error fetching tasks:", error);
        }
    }

    // Delete task
    window.deleteTask = async (taskId) => {
        await fetch(`http://127.0.0.1:8887/api/tasks/${taskId}`, { method: "DELETE" });
        renderTasks();
    };

    // Add new task
    addTaskButton.addEventListener("click", async () => {
        const taskTitle = titleInput.value.trim();
        if (taskTitle) {
            const res = await fetch("http://127.0.0.1:8887/api/tasks", {
                method: "POST",
                headers: { "Content-Type": "application/json" },
                body: JSON.stringify({ task: taskTitle }),
            });

            if (res.ok) {
                titleInput.value = "";
                renderTasks();
            } else {
                errorMessage.textContent = "Failed to add task.";
            }
        }
    });

    // Edit task
    window.editTask = (taskId, taskTitle) => {
        editingTaskId = taskId;
        editTaskContainer.style.display = "block";
        overlay.style.display = "block";
        editTitleInput.value = taskTitle;
    };

    // Update task
    updateTaskButton.addEventListener("click", async () => {
        const updatedTaskTitle = editTitleInput.value.trim();
        if (updatedTaskTitle && editingTaskId) {
            await fetch(`http://127.0.0.1:8887/api/tasks/${editingTaskId}`, {
                method: "PUT",
                headers: { "Content-Type": "application/json" },
                body: JSON.stringify({ task: updatedTaskTitle }),
            });

            editTaskContainer.style.display = "none";
            overlay.style.display = "none";
            editingTaskId = null;
            renderTasks();
        }
    });

    // Close edit task
    overlay.addEventListener("click", () => {
        editTaskContainer.style.display = "none";
        overlay.style.display = "none";
        editingTaskId = null;
    });

    // Random task
    document.getElementById("random-task-button").addEventListener("click", async () => {
        const selectedCategory = document.getElementById("category-select").value;
        let url = "http://127.0.0.1:8887/api/random-tasks";
        if (selectedCategory) {
            url += `?category=${encodeURIComponent(selectedCategory)}`;
        }

        try {
            const res = await fetch(url);
            const data = await res.json();
            if (data.task) {
                document.getElementById("random-task-box").textContent = data.task;
            } else {
                document.getElementById("random-task-box").textContent = "No task found.";
            }
        } catch (error) {
            document.getElementById("random-task-box").textContent = "Error fetching task.";
        }
    });

    // Initialize
    renderTasks();
});
</script>