abdul463007's picture
make task manager app
77166dc verified
Raw History Blame Contribute Delete
7.35 kB
document.addEventListener('DOMContentLoaded', () => {
// DOM Elements
const addTaskBtn = document.getElementById('addTaskBtn');
const taskModal = document.getElementById('taskModal');
const closeModalBtn = document.getElementById('closeModalBtn');
const cancelTaskBtn = document.getElementById('cancelTaskBtn');
const taskForm = document.getElementById('taskForm');
// Task containers
const todoTasks = document.getElementById('todoTasks');
const inProgressTasks = document.getElementById('inProgressTasks');
const completedTasks = document.getElementById('completedTasks');
// Sample tasks
let tasks = [
{
id: 1,
title: 'Design dashboard UI',
description: 'Create wireframes for the new dashboard',
status: 'todo',
priority: 'high',
createdAt: new Date()
},
{
id: 2,
title: 'Write documentation',
description: 'Document the API endpoints',
status: 'in-progress',
priority: 'medium',
createdAt: new Date()
},
{
id: 3,
title: 'Fix login bug',
description: 'Users unable to login on mobile',
status: 'completed',
priority: 'high',
createdAt: new Date()
}
];
// Modal handlers
addTaskBtn.addEventListener('click', () => {
taskModal.classList.remove('hidden');
});
closeModalBtn.addEventListener('click', () => {
taskModal.classList.add('hidden');
});
cancelTaskBtn.addEventListener('click', () => {
taskModal.classList.add('hidden');
});
// Form submission
taskForm.addEventListener('submit', (e) => {
e.preventDefault();
const title = document.getElementById('taskTitle').value;
const description = document.getElementById('taskDescription').value;
const priority = document.getElementById('taskPriority').value;
const newTask = {
id: Date.now(),
title,
description,
status: 'todo',
priority,
createdAt: new Date()
};
tasks.push(newTask);
renderTasks();
taskModal.classList.add('hidden');
taskForm.reset();
});
// Render all tasks
function renderTasks() {
todoTasks.innerHTML = '';
inProgressTasks.innerHTML = '';
completedTasks.innerHTML = '';
tasks.forEach(task => {
const taskElement = createTaskElement(task);
if (task.status === 'todo') {
todoTasks.appendChild(taskElement);
} else if (task.status === 'in-progress') {
inProgressTasks.appendChild(taskElement);
} else {
completedTasks.appendChild(taskElement);
}
});
feather.replace();
addDragEvents();
}
// Create a task card
function createTaskElement(task) {
const taskElement = document.createElement('div');
taskElement.className = `task-card bg-white rounded-lg shadow p-4 cursor-move task-animate priority-${task.priority}`;
taskElement.setAttribute('draggable', 'true');
taskElement.dataset.id = task.id;
let priorityColor = 'bg-gray-400';
if (task.priority === 'high') priorityColor = 'bg-red-500';
else if (task.priority === 'medium') priorityColor = 'bg-yellow-500';
else if (task.priority === 'low') priorityColor = 'bg-green-500';
taskElement.innerHTML = `
<div class="flex justify-between items-start mb-2">
<h3 class="font-medium text-gray-800">${task.title}</h3>
<span class="text-xs px-2 py-1 rounded-full ${priorityColor} text-white">${task.priority}</span>
</div>
<p class="text-sm text-gray-600 mb-3">${task.description}</p>
<div class="flex justify-between items-center text-xs text-gray-500">
<span>${formatDate(task.createdAt)}</span>
<div class="flex space-x-2">
<button class="task-edit-btn hover:text-fuchsia-600" data-id="${task.id}">
<i data-feather="edit-2" class="w-4 h-4"></i>
</button>
<button class="task-delete-btn hover:text-fuchsia-600" data-id="${task.id}">
<i data-feather="trash-2" class="w-4 h-4"></i>
</button>
</div>
</div>
`;
return taskElement;
}
// Format date
function formatDate(date) {
return new Date(date).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric'
});
}
// Drag and drop functionality
function addDragEvents() {
const taskElements = document.querySelectorAll('.task-card');
taskElements.forEach(task => {
task.addEventListener('dragstart', () => {
task.classList.add('opacity-50');
setTimeout(() => {
task.classList.add('hidden');
}, 0);
});
task.addEventListener('dragend', () => {
task.classList.remove('opacity-50', 'hidden');
});
});
const columns = [todoTasks, inProgressTasks, completedTasks];
columns.forEach(column => {
column.addEventListener('dragover', (e) => {
e.preventDefault();
const afterElement = getDragAfterElement(column, e.clientY);
const draggable = document.querySelector('.opacity-50');
if (afterElement == null) {
column.appendChild(draggable);
} else {
column.insertBefore(draggable, afterElement);
}
});
column.addEventListener('drop', (e) => {
e.preventDefault();
const taskId = parseInt(document.querySelector('.opacity-50').dataset.id);
const task = tasks.find(t => t.id === taskId);
if (column === todoTasks) {
task.status = 'todo';
} else if (column === inProgressTasks) {
task.status = 'in-progress';
} else {
task.status = 'completed';
}
});
});
}
function getDragAfterElement(container, y) {
const draggableElements = [...container.querySelectorAll('.task-card:not(.opacity-50)')];
return draggableElements.reduce((closest, child) => {
const box = child.getBoundingClientRect();
const offset = y - box.top - box.height / 2;
if (offset < 0 && offset > closest.offset) {
return { offset: offset, element: child };
} else {
return closest;
}
}, { offset: Number.NEGATIVE_INFINITY }).element;
}
// Initial render
renderTasks();
});