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.jsfile:- 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.jsor use a state management library (like Redux if preferred):- Fetch tasks from the backend on component mount using
axios. - Organize tasks based on their
statusto display in the appropriate columns. - Update state on drag-and-drop by changing the
statusof tasks.
- Fetch tasks from the backend on component mount using
-
Integrate API calls:
- For creating, updating, and deleting tasks, use
axiosto 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, }); };
- For creating, updating, and deleting tasks, use
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).