A modern, responsive Task Management Dashboard built with Next.js 16, TypeScript, Tailwind CSS, and Zustand.
Features a beautiful Kanban board with drag-and-drop functionality for seamless task management.
👨💻 Author: Savinda Jayasekara
🔗 GitHub: github.com/savindaJ
- 🎨 Beautiful Kanban Board - 4 columns: To Do, In Progress, Completed, Cancelled
- 🖱️ Drag & Drop - Seamlessly move tasks between columns
- ⚡ Optimistic Updates - Instant UI feedback with background sync
- 📱 Responsive Design - Works on desktop, tablet, and mobile
- 🌙 Dark Mode - Automatic system preference detection
- 📄 Pagination - Load more tasks as needed
- 🔍 Task Details Modal - View full task information
- ✏️ Create/Edit Tasks - Full CRUD operations
- 🏷️ Tags Support - Organize tasks with tags
- 📅 Due Dates - Track task deadlines
- 🎯 Priority Levels - Low, Medium, High, Urgent
| Technology | Description |
|---|---|
| Next.js 16 | React framework with App Router |
| React 19 | UI library |
| TypeScript | Type-safe JavaScript |
| Tailwind CSS 4 | Utility-first CSS framework |
| Zustand | Lightweight state management |
| @dnd-kit | Drag and drop toolkit |
| Axios | HTTP client |
| Lucide React | Beautiful icons |
taskmanager-fe/
├── app/
│ ├── favicon.ico
│ ├── globals.css # Global styles & Tailwind imports
│ ├── layout.tsx # Root layout
│ └── page.tsx # Home page with Kanban board
├── src/
│ ├── components/ # React components
│ │ ├── index.ts
│ │ ├── KanbanBoard.tsx # Main board component
│ │ ├── KanbanColumn.tsx # Column component
│ │ ├── TaskCard.tsx # Draggable task card
│ │ ├── TaskModal.tsx # Create/Edit modal
│ │ └── TaskViewModal.tsx # View task details modal
│ ├── config/ # Configuration
│ │ ├── index.ts
│ │ └── axios.ts # Axios instance & interceptors
│ ├── service/ # API services
│ │ ├── index.ts
│ │ └── task.service.ts # Task API calls
│ ├── store/ # State management
│ │ ├── index.ts
│ │ └── taskStore.ts # Zustand store
│ └── types/ # TypeScript types
│ ├── index.ts
│ └── task.types.ts # Task interfaces & types
├── public/ # Static assets
├── .env.local # Environment variables (create this)
├── next.config.ts
├── package.json
├── tailwind.config.ts
├── tsconfig.json
└── README.mdMake sure you have the following installed:
- Node.js v18 or higher
- npm v9 or higher
- Backend API running (see taskmanager-be)
git clone https://github.com/savindaJ/task-manager-frontend.git
cd task-manager-frontendnpm installCreate a .env.local file in the root directory:
touch .env.localAdd the following environment variables:
# =================================
# API Configuration
# =================================
# Backend API URL (without trailing slash)
NEXT_PUBLIC_API_URL=http://localhost:8080/api| Variable | Description | Required | Default |
|---|---|---|---|
NEXT_PUBLIC_API_URL |
Backend API base URL | Yes | http://localhost:5000/api |
⚠️ Note: Variables prefixed withNEXT_PUBLIC_are exposed to the browser. Never put sensitive data here.
npm run devOpen http://localhost:3000 in your browser.
npm run build
npm start| Script | Description |
|---|---|
npm run dev |
Start development server on port 3000 |
npm run build |
Build for production |
npm start |
Start production server |
npm run lint |
Run ESLint |
The main container that renders all columns and handles drag-and-drop context.
<KanbanBoard />Individual column representing a task status (TODO, IN_PROGRESS, etc.).
<KanbanColumn column={column} tasks={tasks} />Draggable card displaying task summary. Click to view details.
<TaskCard task={task} />Modal for creating or editing tasks.
<TaskModal /> // Controlled by Zustand storeModal displaying full task details with edit/delete actions.
<TaskViewModal /> // Controlled by Zustand storeThe app uses Zustand for state management with the following store:
interface TaskState {
// State
tasks: Task[];
isLoading: boolean;
isLoadingMore: boolean;
error: string | null;
pagination: PaginationMeta;
isModalOpen: boolean;
isViewModalOpen: boolean;
selectedTask: Task | null;
viewingTask: Task | null;
// Actions
fetchTasks: () => Promise<void>;
loadMoreTasks: () => Promise<void>;
createTask: (data: CreateTaskInput) => Promise<void>;
updateTask: (id: string, data: UpdateTaskInput) => Promise<void>;
updateTaskStatus: (id: string, status: TaskStatus) => Promise<void>;
deleteTask: (id: string) => Promise<void>;
openModal: (mode: "create" | "edit", task?: Task) => void;
closeModal: () => void;
openViewModal: (task: Task) => void;
closeViewModal: () => void;
}import { useTaskStore } from "@/src/store";
function MyComponent() {
const { tasks, fetchTasks, createTask } = useTaskStore();
useEffect(() => {
fetchTasks();
}, [fetchTasks]);
return <div>{tasks.map(task => ...)}</div>;
}The API service layer handles all HTTP requests:
import { taskService } from "@/src/service";
// Get all tasks with pagination
const response = await taskService.getAllTasks({ page: 1, limit: 10 });
// Create a task
await taskService.createTask({ title: "New Task", priority: "HIGH" });
// Update a task
await taskService.updateTask(taskId, { status: "COMPLETED" });
// Delete a task
await taskService.deleteTask(taskId);
// Get task statistics
const stats = await taskService.getTaskStats();type TaskStatus = "TODO" | "IN_PROGRESS" | "COMPLETED" | "CANCELLED";
type TaskPriority = "LOW" | "MEDIUM" | "HIGH" | "URGENT";
interface Task {
id: string;
title: string;
description?: string;
status: TaskStatus;
priority: TaskPriority;
dueDate?: string;
tags: string[];
createdAt: string;
updatedAt: string;
}
interface CreateTaskInput {
title: string;
description?: string;
status?: TaskStatus;
priority?: TaskPriority;
dueDate?: string;
tags?: string[];
}
Savinda Jayasekara
- GitHub: @savindaJ
- LinkedIn: Savinda Jayasekara
- Next.js - The React Framework
- Tailwind CSS - Utility-first CSS
- dnd-kit - Drag and drop toolkit
- Zustand - State management
- Lucide - Beautiful icons
⭐ If you found this project helpful, please give it a star!