A fully-featured Kanban board with drag-and-drop, IndexedDB persistence, and rich task management built with vanilla JavaScript (ES6+).
- Drag & Drop - Drag tasks between columns (inspired by Solitaire implementation)
- Custom Columns - Create, customize colors, and manage columns
- Rich Tasks - Title, description, assignee, start/due dates, priority levels
- IndexedDB Persistence - All data saved locally and persists across sessions
- Responsive Design - Works on desktop, tablet, and mobile
- ✅ Priority levels (Low, Medium, High) with color coding
- ✅ Due dates with overdue detection
- ✅ Task assignees
- ✅ Detailed descriptions
- ✅ Visual priority indicators
- ✅ Days remaining badges
- Clean separation: Core → Services → State → UI
- ES6+ throughout: Classes, async/await, modules, arrow functions
- Smooth animations: Fade in/out, drag states, stagger effects
- Open
index.htmlin your browser - Click "+ Task" to add a task
- Drag tasks between columns
- Click "+ Column" to customize your workflow
kanban-board/
├── index.html
├── src/
│ ├── core/ # Pure logic
│ │ ├── constants.js
│ │ ├── TaskLogic.js # Task operations
│ │ ├── ColumnLogic.js # Column operations
│ │ └── utils.js
│ ├── services/ # External integrations
│ │ └── IndexedDBService.js
│ ├── state/ # Orchestration
│ │ └── BoardState.js
│ ├── ui/ # DOM & Events
│ │ ├── Renderer.js
│ │ ├── EventHandler.js
│ │ └── DragDropHandler.js
│ └── main.js
└── styles/
├── main.css
├── components.css
└── animations.css
State (BoardState)
↓
Rules (TaskLogic + ColumnLogic) → Pure functions
↓
Actions (add, move, delete)
↓
UI (Renderer + DragDropHandler + EventHandler)
↓
Storage (IndexedDBService)
{
id: 1234567890.123,
title: "Implement feature",
description: "Add drag and drop",
assignee: "John Doe",
priority: "high", // low, medium, high
columnId: "in-progress",
startDate: "2024-01-01",
dueDate: "2024-01-15",
createdAt: 1234567890000,
updatedAt: 1234567890000,
order: 0
}// Similar to Solitaire drag system
dragStart → store task & column
↓
dragOver → visual feedback
↓
drop → move task to new column
↓
save to IndexedDB → render{
id: "custom-123",
name: "Review",
color: "#8b5cf6",
order: 2
}async addTask(data) {
await this.storage.addTask(newTask);
await this.renderer.animateAddTask(newTask);
}const { valid, error } = TaskLogic.validateTask(data);
const [columns, tasks] = await Promise.all([...]);const movedTask = { ...task, columnId: newId };
this.tasks = [...this.tasks, newTask];const columnTasks = tasks.filter(t => t.columnId === id);
columns.forEach(col => this.renderColumn(col));const firstColumn = this.columns[0]?.id || 'backlog';`<div class="task-card" data-id="${task.id}">`import { TaskLogic } from '../core/TaskLogic.js';
export class BoardState { }Based on Solitaire's drag system:
// 1. Make cards draggable
<div class="task-card" draggable="true">
// 2. Track drag state
onDragStart(e, task) {
this.draggedTask = task;
e.target.classList.add('dragging');
}
// 3. Handle drop zones
onDragOver(e, columnId) {
e.preventDefault();
column.classList.add('drag-over');
}
// 4. Complete the move
async onDrop(e, columnId) {
await this.board.moveTask(taskId, columnId);
}Two Object Stores:
- tasks - All task data
- columns - Column configurations
Indexes:
- Tasks:
columnId,priority - Columns:
order
Default Columns:
- Backlog (gray)
- To Do (blue)
- In Progress (orange)
- Done (green)
- Add task labels/tags
- Add task search
- Export board to JSON
- Add subtasks
- Add task comments
- Add file attachments
- Archive completed tasks
- Add team collaboration (Firebase)
- Add activity timeline
- Add analytics dashboard
- Rebuild in React/Vue/Svelte
- ✅ Drag & Drop API
- ✅ IndexedDB CRUD operations
- ✅ Async/await patterns
- ✅ ES6 modules
- ✅ Event delegation
- ✅ State management
- ✅ CSS Grid
- ✅ Flexbox
- ✅ CSS Variables
- ✅ Animations
- ✅ Drag states
- ✅ Separation of concerns
- ✅ Pure functions
- ✅ Service layer pattern
- ✅ State orchestration
Built with ❤️ using vanilla JavaScript, ES6+, and IndexedDB