fervor [>]CODING & CURIOSITY
FERVOR LEARNING SYSTEMTUTORIALS
← Projects

Projects / 5 MIN READ

Kanban Task Board Overview

Kanban Task Board Project/Tutorial Overview

From the original Fervor library. Examples may use older package versions.

Below is an outline for a tutorial that walks through building a Kanban Task Board with a drag-and-drop interface, state management, and CRUD operations. This project uses React (with react-beautiful-dnd) for the frontend, Node.js/Express for the API, and MongoDB for data storage.


1. Introduction

  • Project Overview:
    Build a Trello-like board where users can create tasks, drag them between columns (e.g., To Do, In Progress, Done), and persist changes to a backend.

  • What You Will Learn:

    • Setting up a Node.js/Express backend with MongoDB
    • Building a React frontend with drag-and-drop functionality
    • Managing state and implementing CRUD operations
    • Integrating frontend and backend

2. Prerequisites

  • Basic Knowledge:

    • JavaScript (ES6+), HTML, and CSS
    • React fundamentals
    • Node.js and Express basics
    • RESTful API concepts
  • Tools Needed:

    • Node.js and npm/yarn
    • MongoDB (local installation or MongoDB Atlas)
    • Code editor (e.g., VS Code)
    • Git for version control (optional)

3. Setting Up the Backend

a. Initialize the Project

  • Create a new directory for your backend:
    mkdir kanban-backend && cd kanban-backend
    npm init -y
    
  • Install dependencies:
    npm install express mongoose cors body-parser
    

b. Set Up Express Server

  • Create an index.js file:
    • Set up a basic Express server with middleware (CORS, JSON body parsing)
    • Example:
      const express = require('express');
      const mongoose = require('mongoose');
      const cors = require('cors');
      
      const app = express();
      app.use(cors());
      app.use(express.json());
      
      // Connect to MongoDB
      mongoose.connect('mongodb://localhost/kanban', {
        useNewUrlParser: true,
        useUnifiedTopology: true,
      })
      .then(() => console.log('MongoDB connected'))
      .catch(err => console.log(err));
      
      // Start server
      const PORT = process.env.PORT || 5000;
      app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
      

c. Define Task Model

  • Create a model for tasks (e.g., Task.js):
    const mongoose = require('mongoose');
    
    const TaskSchema = new mongoose.Schema({
      title: { type: String, required: true },
      description: String,
      status: { type: String, enum: ['To Do', 'In Progress', 'Done'], default: 'To Do' },
      createdAt: { type: Date, default: Date.now },
    });
    
    module.exports = mongoose.model('Task', TaskSchema);
    

d. Create CRUD Routes

  • Set up routes in a separate file or within index.js:
    const Task = require('./Task');
    
    // Create a new task
    app.post('/tasks', async (req, res) => {
      try {
        const task = new Task(req.body);
        await task.save();
        res.status(201).json(task);
      } catch (error) {
        res.status(400).json({ error: error.message });
      }
    });
    
    // Read all tasks
    app.get('/tasks', async (req, res) => {
      try {
        const tasks = await Task.find();
        res.json(tasks);
      } catch (error) {
        res.status(500).json({ error: error.message });
      }
    });
    
    // Update a task
    app.put('/tasks/:id', async (req, res) => {
      try {
        const task = await Task.findByIdAndUpdate(req.params.id, req.body, { new: true });
        res.json(task);
      } catch (error) {
        res.status(400).json({ error: error.message });
      }
    });
    
    // Delete a task
    app.delete('/tasks/:id', async (req, res) => {
      try {
        await Task.findByIdAndDelete(req.params.id);
        res.json({ message: 'Task deleted' });
      } catch (error) {
        res.status(400).json({ error: error.message });
      }
    });
    

e. Testing the API

  • Use Postman or cURL:
    Test each endpoint to ensure CRUD operations work correctly.

4. Building the Frontend with React

a. Initialize React App

  • Create a new React project:
    npx create-react-app kanban-frontend
    cd kanban-frontend
    npm install react-beautiful-dnd axios
    

b. Project Structure

  • Organize your components:
    • App.js: Main component managing overall state and API integration.
    • Board.js: Container for columns.
    • Column.js: Represents each Kanban column (e.g., To Do, In Progress, Done).
    • Task.js: Represents an individual task card.

c. Implement Drag-and-Drop with react-beautiful-dnd

  • Wrap your board with <DragDropContext>:

    import { DragDropContext } from 'react-beautiful-dnd';
    
    function App() {
      const onDragEnd = (result) => {
        // Update state based on the result of the drag event.
        // Use result.source and result.destination for details.
      };
    
      return (
        <DragDropContext onDragEnd={onDragEnd}>
          <Board />
        </DragDropContext>
      );
    }
    
  • Implement droppable columns and draggable tasks:

    • In Column.js:

      import { Droppable } from 'react-beautiful-dnd';
      
      const Column = ({ columnId, title, tasks }) => {
        return (
          <div className="column">
            <h2>{title}</h2>
            <Droppable droppableId={columnId}>
              {(provided) => (
                <div ref={provided.innerRef} {...provided.droppableProps}>
                  {tasks.map((task, index) => (
                    <Task key={task._id} task={task} index={index} />
                  ))}
                  {provided.placeholder}
                </div>
              )}
            </Droppable>
          </div>
        );
      };
      
      export default Column;
      
    • In Task.js:

      import { Draggable } from 'react-beautiful-dnd';
      
      const Task = ({ task, index }) => {
        return (
          <Draggable draggableId={task._id} index={index}>
            {(provided) => (
              <div
                className="task"
                ref={provided.innerRef}
                {...provided.draggableProps}
                {...provided.dragHandleProps}
              >
                <p>{task.title}</p>
              </div>
            )}
          </Draggable>
        );
      };
      
      export default Task;
      

d. State Management and CRUD Operations

  • Manage state in App.js or use a state management library (like Redux if preferred):

    • Fetch tasks from the backend on component mount using axios.
    • Organize tasks based on their status to display in the appropriate columns.
    • Update state on drag-and-drop by changing the status of tasks.
  • Integrate API calls:

    • For creating, updating, and deleting tasks, use axios to communicate with your Express API.
    • Example of updating a task’s status when dropped into a new column:
      const onDragEnd = async (result) => {
        if (!result.destination) return;
      
        const { source, destination, draggableId } = result;
        // Update local state (move the task between columns)
        // ...
        // Then, update the task on the server:
        await axios.put(`http://localhost:5000/tasks/${draggableId}`, {
          status: destination.droppableId,
        });
      };
      

e. CRUD UI Elements

  • Create Task Form:

    • Add a form to create new tasks.
    • On submission, post the task to the backend and update local state.
  • Task Editing/Deletion:

    • Add options (e.g., buttons) on each task card for editing or deleting.
    • Make corresponding API calls to update or remove the task.

5. Integration & Testing

  • Test the Complete Workflow:

    • Create tasks, drag them between columns, edit, and delete.
    • Verify that changes persist by reloading the page (data should be fetched from MongoDB).
  • Debug Issues:

    • Use browser dev tools and console logs.
    • Check API logs from the Express server.

6. Deployment (Optional)

  • Backend Deployment:
    • Deploy your Express app to a service like Heroku, DigitalOcean, or any preferred provider.
  • Frontend Deployment:
    • Deploy your React app to Vercel, Netlify, or GitHub Pages.
  • Connecting Domains:
    • Ensure that your frontend makes API calls to the correct backend URL.

7. Conclusion

  • Recap:

    • Built a full-stack Kanban board with drag-and-drop functionality.
    • Learned how to integrate a React frontend with an Express/MongoDB backend.
    • Implemented CRUD operations and state management.
  • Next Steps:

    • Add user authentication to allow multiple users to have their own boards.
    • Improve styling and add animations.
    • Expand functionality (e.g., subtasks, comments).
Keep your curiosity going.Explore more Projects →
287 TUTORIALS · 22 TOPICSREADY