Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Task Matrix Pro</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| .task-card { | |
| transition: all 0.3s ease; | |
| } | |
| .task-card:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); | |
| } | |
| .kanban-column { | |
| min-height: 400px; | |
| } | |
| .calendar-day { | |
| transition: all 0.2s ease; | |
| } | |
| .calendar-day:hover { | |
| background-color: #f3f4f6; | |
| } | |
| .calendar-day.has-tasks::after { | |
| content: ''; | |
| display: block; | |
| width: 6px; | |
| height: 6px; | |
| background-color: #3b82f6; | |
| border-radius: 50%; | |
| margin: 2px auto 0; | |
| } | |
| .active-tab { | |
| border-bottom: 3px solid #3b82f6; | |
| font-weight: 600; | |
| } | |
| [draggable="true"] { | |
| cursor: move; | |
| } | |
| .kanban-column.highlight { | |
| background-color: #f0f9ff; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-50 min-h-screen"> | |
| <div class="container mx-auto px-4 py-8"> | |
| <!-- Header --> | |
| <header class="mb-8"> | |
| <h1 class="text-3xl font-bold text-gray-800">Task Matrix Pro</h1> | |
| <p class="text-gray-600">Organize your tasks with Eisenhower Matrix</p> | |
| </header> | |
| <!-- Navigation Tabs --> | |
| <div class="flex border-b border-gray-200 mb-6"> | |
| <button id="matrix-tab" class="px-4 py-2 active-tab">Matrix View</button> | |
| <button id="kanban-tab" class="px-4 py-2">Kanban Board</button> | |
| <button id="calendar-tab" class="px-4 py-2">Calendar</button> | |
| </div> | |
| <!-- Matrix View --> | |
| <div id="matrix-view" class="view-content"> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> | |
| <!-- Task Input Form --> | |
| <div class="bg-white p-4 rounded-lg shadow"> | |
| <h2 class="text-xl font-semibold mb-4">Add New Task</h2> | |
| <form id="task-form" class="space-y-4"> | |
| <div> | |
| <label for="task-title" class="block text-sm font-medium text-gray-700">Task Title</label> | |
| <input type="text" id="task-title" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 p-2 border"> | |
| </div> | |
| <div> | |
| <label for="task-description" class="block text-sm font-medium text-gray-700">Description</label> | |
| <textarea id="task-description" rows="2" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 p-2 border"></textarea> | |
| </div> | |
| <div class="grid grid-cols-2 gap-4"> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700">Urgency</label> | |
| <div class="mt-1 flex space-x-4"> | |
| <label class="inline-flex items-center"> | |
| <input type="radio" name="urgency" value="urgent" class="h-4 w-4 text-blue-600 focus:ring-blue-500"> | |
| <span class="ml-2 text-sm text-gray-700">Urgent</span> | |
| </label> | |
| <label class="inline-flex items-center"> | |
| <input type="radio" name="urgency" value="not-urgent" class="h-4 w-4 text-blue-600 focus:ring-blue-500"> | |
| <span class="ml-2 text-sm text-gray-700">Not Urgent</span> | |
| </label> | |
| </div> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700">Importance</label> | |
| <div class="mt-1 flex space-x-4"> | |
| <label class="inline-flex items-center"> | |
| <input type="radio" name="importance" value="important" class="h-4 w-4 text-blue-600 focus:ring-blue-500"> | |
| <span class="ml-2 text-sm text-gray-700">Important</span> | |
| </label> | |
| <label class="inline-flex items-center"> | |
| <input type="radio" name="importance" value="not-important" class="h-4 w-4 text-blue-600 focus:ring-blue-500"> | |
| <span class="ml-2 text-sm text-gray-700">Not Important</span> | |
| </label> | |
| </div> | |
| </div> | |
| </div> | |
| <div> | |
| <label for="task-due" class="block text-sm font-medium text-gray-700">Due Date</label> | |
| <input type="date" id="task-due" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 p-2 border"> | |
| </div> | |
| <button type="submit" class="w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"> | |
| Add Task | |
| </button> | |
| </form> | |
| </div> | |
| <!-- Eisenhower Matrix Explanation --> | |
| <div class="bg-white p-4 rounded-lg shadow"> | |
| <h2 class="text-xl font-semibold mb-4">Eisenhower Matrix Guide</h2> | |
| <div class="grid grid-cols-2 gap-2"> | |
| <div class="bg-red-100 p-3 rounded"> | |
| <h3 class="font-medium text-red-800">Urgent & Important</h3> | |
| <p class="text-sm text-red-700">Do these tasks immediately</p> | |
| </div> | |
| <div class="bg-yellow-100 p-3 rounded"> | |
| <h3 class="font-medium text-yellow-800">Important, Not Urgent</h3> | |
| <p class="text-sm text-yellow-700">Schedule these tasks</p> | |
| </div> | |
| <div class="bg-blue-100 p-3 rounded"> | |
| <h3 class="font-medium text-blue-800">Urgent, Not Important</h3> | |
| <p class="text-sm text-blue-700">Delegate if possible</p> | |
| </div> | |
| <div class="bg-green-100 p-3 rounded"> | |
| <h3 class="font-medium text-green-800">Not Urgent, Not Important</h3> | |
| <p class="text-sm text-green-700">Consider eliminating</p> | |
| </div> | |
| </div> | |
| <div class="mt-4 text-sm text-gray-600"> | |
| <p>The Eisenhower Matrix helps you prioritize tasks based on urgency and importance. This method was popularized by US President Dwight D. Eisenhower.</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Task Matrix --> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
| <!-- Quadrant 1: Urgent & Important --> | |
| <div class="bg-red-50 p-4 rounded-lg shadow"> | |
| <h2 class="text-lg font-semibold text-red-800 mb-4 flex items-center"> | |
| <i class="fas fa-exclamation-triangle mr-2"></i> Urgent & Important | |
| </h2> | |
| <div id="quadrant-1" class="space-y-3"> | |
| <!-- Tasks will be added here dynamically --> | |
| </div> | |
| </div> | |
| <!-- Quadrant 2: Important, Not Urgent --> | |
| <div class="bg-yellow-50 p-4 rounded-lg shadow"> | |
| <h2 class="text-lg font-semibold text-yellow-800 mb-4 flex items-center"> | |
| <i class="fas fa-calendar-check mr-2"></i> Important, Not Urgent | |
| </h2> | |
| <div id="quadrant-2" class="space-y-3"> | |
| <!-- Tasks will be added here dynamically --> | |
| </div> | |
| </div> | |
| <!-- Quadrant 3: Urgent, Not Important --> | |
| <div class="bg-blue-50 p-4 rounded-lg shadow"> | |
| <h2 class="text-lg font-semibold text-blue-800 mb-4 flex items-center"> | |
| <i class="fas fa-share-square mr-2"></i> Urgent, Not Important | |
| </h2> | |
| <div id="quadrant-3" class="space-y-3"> | |
| <!-- Tasks will be added here dynamically --> | |
| </div> | |
| </div> | |
| <!-- Quadrant 4: Not Urgent, Not Important --> | |
| <div class="bg-green-50 p-4 rounded-lg shadow"> | |
| <h2 class="text-lg font-semibold text-green-800 mb-4 flex items-center"> | |
| <i class="fas fa-trash-alt mr-2"></i> Not Urgent, Not Important | |
| </h2> | |
| <div id="quadrant-4" class="space-y-3"> | |
| <!-- Tasks will be added here dynamically --> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Kanban Board View (hidden by default) --> | |
| <div id="kanban-view" class="view-content hidden"> | |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-6"> | |
| <!-- Backlog Column --> | |
| <div class="bg-gray-100 p-4 rounded-lg shadow kanban-column" | |
| id="backlog-column" | |
| ondrop="handleDrop(event, 'backlog')" | |
| ondragover="handleDragOver(event)" | |
| ondragenter="handleDragEnter(event)" | |
| ondragleave="handleDragLeave(event)"> | |
| <h2 class="text-lg font-semibold text-gray-800 mb-4 flex items-center justify-between"> | |
| <span><i class="fas fa-clipboard-list mr-2"></i> Backlog</span> | |
| <span id="backlog-count" class="bg-gray-200 text-gray-700 text-xs font-medium px-2.5 py-0.5 rounded-full">0</span> | |
| </h2> | |
| <div id="backlog-tasks" class="space-y-3"> | |
| <!-- Tasks will be added here dynamically --> | |
| </div> | |
| </div> | |
| <!-- In Progress Column --> | |
| <div class="bg-blue-100 p-4 rounded-lg shadow kanban-column" | |
| id="progress-column" | |
| ondrop="handleDrop(event, 'progress')" | |
| ondragover="handleDragOver(event)" | |
| ondragenter="handleDragEnter(event)" | |
| ondragleave="handleDragLeave(event)"> | |
| <h2 class="text-lg font-semibold text-blue-800 mb-4 flex items-center justify-between"> | |
| <span><i class="fas fa-spinner mr-2"></i> In Progress</span> | |
| <span id="progress-count" class="bg-blue-200 text-blue-800 text-xs font-medium px-2.5 py-0.5 rounded-full">0</span> | |
| </h2> | |
| <div id="progress-tasks" class="space-y-3"> | |
| <!-- Tasks will be added here dynamically --> | |
| </div> | |
| </div> | |
| <!-- Done Column --> | |
| <div class="bg-green-100 p-4 rounded-lg shadow kanban-column" | |
| id="done-column" | |
| ondrop="handleDrop(event, 'done')" | |
| ondragover="handleDragOver(event)" | |
| ondragenter="handleDragEnter(event)" | |
| ondragleave="handleDragLeave(event)"> | |
| <h2 class="text-lg font-semibold text-green-800 mb-4 flex items-center justify-between"> | |
| <span><i class="fas fa-check-circle mr-2"></i> Done</span> | |
| <span id="done-count" class="bg-green-200 text-green-800 text-xs font-medium px-2.5 py-0.5 rounded-full">0</span> | |
| </h2> | |
| <div id="done-tasks" class="space-y-3"> | |
| <!-- Tasks will be added here dynamically --> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Calendar View (hidden by default) --> | |
| <div id="calendar-view" class="view-content hidden"> | |
| <div class="bg-white p-4 rounded-lg shadow mb-6"> | |
| <div class="flex items-center justify-between mb-4"> | |
| <button id="prev-month" class="p-2 rounded-full hover:bg-gray-100"> | |
| <i class="fas fa-chevron-left"></i> | |
| </button> | |
| <h2 id="current-month" class="text-xl font-semibold">July 2023</h2> | |
| <button id="next-month" class="p-2 rounded-full hover:bg-gray-100"> | |
| <i class="fas fa-chevron-right"></i> | |
| </button> | |
| </div> | |
| <div class="grid grid-cols-7 gap-1"> | |
| <div class="text-center font-medium text-gray-500 py-2">Sun</div> | |
| <div class="text-center font-medium text-gray-500 py-2">Mon</div> | |
| <div class="text-center font-medium text-gray-500 py-2">Tue</div> | |
| <div class="text-center font-medium text-gray-500 py-2">Wed</div> | |
| <div class="text-center font-medium text-gray-500 py-2">Thu</div> | |
| <div class="text-center font-medium text-gray-500 py-2">Fri</div> | |
| <div class="text-center font-medium text-gray-500 py-2">Sat</div> | |
| </div> | |
| <div id="calendar-days" class="grid grid-cols-7 gap-1"> | |
| <!-- Calendar days will be generated here --> | |
| </div> | |
| </div> | |
| <div id="day-tasks" class="bg-white p-4 rounded-lg shadow"> | |
| <h2 id="selected-day" class="text-xl font-semibold mb-4">Select a date to view tasks</h2> | |
| <div id="day-tasks-list" class="space-y-3"> | |
| <!-- Tasks for selected day will appear here --> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Task data structure | |
| let tasks = []; | |
| let currentDate = new Date(); | |
| let selectedDay = null; | |
| let draggedTaskId = null; | |
| // DOM Elements | |
| const taskForm = document.getElementById('task-form'); | |
| const matrixView = document.getElementById('matrix-view'); | |
| const kanbanView = document.getElementById('kanban-view'); | |
| const calendarView = document.getElementById('calendar-view'); | |
| const views = [matrixView, kanbanView, calendarView]; | |
| // Tab buttons | |
| const matrixTab = document.getElementById('matrix-tab'); | |
| const kanbanTab = document.getElementById('kanban-tab'); | |
| const calendarTab = document.getElementById('calendar-tab'); | |
| const tabs = [matrixTab, kanbanTab, calendarTab]; | |
| // Calendar elements | |
| const prevMonthBtn = document.getElementById('prev-month'); | |
| const nextMonthBtn = document.getElementById('next-month'); | |
| const currentMonthEl = document.getElementById('current-month'); | |
| const calendarDaysEl = document.getElementById('calendar-days'); | |
| const selectedDayEl = document.getElementById('selected-day'); | |
| const dayTasksListEl = document.getElementById('day-tasks-list'); | |
| // Initialize the app | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // Load tasks from localStorage if available | |
| const savedTasks = localStorage.getItem('tasks'); | |
| if (savedTasks) { | |
| tasks = JSON.parse(savedTasks); | |
| } else { | |
| // Initialize with some sample tasks if none exist | |
| tasks = [ | |
| { | |
| id: '1', | |
| title: 'Complete project proposal', | |
| description: 'Finish writing the project proposal document', | |
| dueDate: formatDateForInput(new Date()), | |
| urgency: 'urgent', | |
| importance: 'important', | |
| status: 'progress', | |
| createdAt: new Date().toISOString() | |
| }, | |
| { | |
| id: '2', | |
| title: 'Schedule team meeting', | |
| description: 'Plan next week\'s team meeting', | |
| dueDate: formatDateForInput(new Date(Date.now() + 86400000 * 2)), | |
| urgency: 'not-urgent', | |
| importance: 'important', | |
| status: 'backlog', | |
| createdAt: new Date().toISOString() | |
| } | |
| ]; | |
| saveTasks(); | |
| } | |
| // Set up event listeners | |
| setupEventListeners(); | |
| // Render initial views | |
| renderMatrixView(); | |
| renderKanbanView(); | |
| renderCalendar(); | |
| // Set matrix view as default | |
| switchView(0); | |
| }); | |
| // Set up event listeners | |
| function setupEventListeners() { | |
| // Task form submission | |
| taskForm.addEventListener('submit', function(e) { | |
| e.preventDefault(); | |
| addNewTask(); | |
| }); | |
| // Tab switching | |
| tabs.forEach((tab, index) => { | |
| tab.addEventListener('click', () => switchView(index)); | |
| }); | |
| // Calendar navigation | |
| prevMonthBtn.addEventListener('click', () => { | |
| currentDate.setMonth(currentDate.getMonth() - 1); | |
| renderCalendar(); | |
| }); | |
| nextMonthBtn.addEventListener('click', () => { | |
| currentDate.setMonth(currentDate.getMonth() + 1); | |
| renderCalendar(); | |
| }); | |
| } | |
| // Switch between views | |
| function switchView(index) { | |
| views.forEach(view => view.classList.add('hidden')); | |
| views[index].classList.remove('hidden'); | |
| tabs.forEach(tab => tab.classList.remove('active-tab')); | |
| tabs[index].classList.add('active-tab'); | |
| // Update specific views when switched to | |
| if (index === 1) renderKanbanView(); | |
| if (index === 2) renderCalendar(); | |
| } | |
| // Add a new task | |
| function addNewTask() { | |
| const title = document.getElementById('task-title').value.trim(); | |
| const description = document.getElementById('task-description').value.trim(); | |
| const dueDate = document.getElementById('task-due').value; | |
| const urgency = document.querySelector('input[name="urgency"]:checked')?.value; | |
| const importance = document.querySelector('input[name="importance"]:checked')?.value; | |
| if (!title || !urgency || !importance) { | |
| alert('Please fill in all required fields'); | |
| return; | |
| } | |
| const newTask = { | |
| id: Date.now().toString(), | |
| title, | |
| description, | |
| dueDate, | |
| urgency, | |
| importance, | |
| status: 'backlog', // Default status for Kanban | |
| createdAt: new Date().toISOString() | |
| }; | |
| tasks.push(newTask); | |
| saveTasks(); | |
| renderMatrixView(); | |
| renderKanbanView(); | |
| renderCalendar(); | |
| // Reset form | |
| taskForm.reset(); | |
| } | |
| // Save tasks to localStorage | |
| function saveTasks() { | |
| localStorage.setItem('tasks', JSON.stringify(tasks)); | |
| } | |
| // Render the matrix view | |
| function renderMatrixView() { | |
| const quadrants = { | |
| 'quadrant-1': { urgency: 'urgent', importance: 'important' }, | |
| 'quadrant-2': { urgency: 'not-urgent', importance: 'important' }, | |
| 'quadrant-3': { urgency: 'urgent', importance: 'not-important' }, | |
| 'quadrant-4': { urgency: 'not-urgent', importance: 'not-important' } | |
| }; | |
| // Clear all quadrants | |
| for (const quadrantId in quadrants) { | |
| document.getElementById(quadrantId).innerHTML = ''; | |
| } | |
| // Add tasks to their respective quadrants | |
| tasks.forEach(task => { | |
| const { urgency, importance } = task; | |
| let quadrantId = ''; | |
| if (urgency === 'urgent' && importance === 'important') { | |
| quadrantId = 'quadrant-1'; | |
| } else if (urgency === 'not-urgent' && importance === 'important') { | |
| quadrantId = 'quadrant-2'; | |
| } else if (urgency === 'urgent' && importance === 'not-important') { | |
| quadrantId = 'quadrant-3'; | |
| } else { | |
| quadrantId = 'quadrant-4'; | |
| } | |
| const taskElement = createTaskElement(task, true); | |
| document.getElementById(quadrantId).appendChild(taskElement); | |
| }); | |
| } | |
| // Render the kanban view | |
| function renderKanbanView() { | |
| const statuses = ['backlog', 'progress', 'done']; | |
| const statusIds = ['backlog-tasks', 'progress-tasks', 'done-tasks']; | |
| const countIds = ['backlog-count', 'progress-count', 'done-count']; | |
| // Clear all columns | |
| statusIds.forEach(id => { | |
| document.getElementById(id).innerHTML = ''; | |
| }); | |
| // Update counts | |
| statuses.forEach((status, index) => { | |
| const count = tasks.filter(task => task.status === status).length; | |
| document.getElementById(countIds[index]).textContent = count; | |
| }); | |
| // Add tasks to their respective columns | |
| tasks.forEach(task => { | |
| let columnId = ''; | |
| switch(task.status) { | |
| case 'backlog': columnId = 'backlog-tasks'; break; | |
| case 'progress': columnId = 'progress-tasks'; break; | |
| case 'done': columnId = 'done-tasks'; break; | |
| } | |
| const taskElement = createTaskElement(task, false); | |
| taskElement.setAttribute('draggable', 'true'); | |
| taskElement.addEventListener('dragstart', (e) => { | |
| draggedTaskId = task.id; | |
| e.dataTransfer.setData('text/plain', task.id); | |
| e.currentTarget.classList.add('opacity-50'); | |
| }); | |
| taskElement.addEventListener('dragend', (e) => { | |
| e.currentTarget.classList.remove('opacity-50'); | |
| }); | |
| document.getElementById(columnId).appendChild(taskElement); | |
| }); | |
| } | |
| // Drag and drop handlers | |
| function handleDragStart(e) { | |
| draggedTaskId = e.target.dataset.id; | |
| e.dataTransfer.setData('text/plain', draggedTaskId); | |
| e.target.classList.add('opacity-50'); | |
| } | |
| function handleDragEnd(e) { | |
| e.target.classList.remove('opacity-50'); | |
| } | |
| function handleDragOver(e) { | |
| e.preventDefault(); | |
| } | |
| function handleDragEnter(e) { | |
| if (e.target.classList.contains('kanban-column')) { | |
| e.target.classList.add('highlight'); | |
| } | |
| } | |
| function handleDragLeave(e) { | |
| if (e.target.classList.contains('kanban-column')) { | |
| e.target.classList.remove('highlight'); | |
| } | |
| } | |
| function handleDrop(e, newStatus) { | |
| e.preventDefault(); | |
| e.target.classList.remove('highlight'); | |
| const taskId = e.dataTransfer.getData('text/plain'); | |
| const taskIndex = tasks.findIndex(task => task.id === taskId); | |
| if (taskIndex !== -1) { | |
| tasks[taskIndex].status = newStatus; | |
| saveTasks(); | |
| renderKanbanView(); | |
| } | |
| } | |
| // Render the calendar | |
| function renderCalendar() { | |
| // Update month display | |
| const options = { month: 'long', year: 'numeric' }; | |
| currentMonthEl.textContent = currentDate.toLocaleDateString('en-US', options); | |
| // Get first day of month and total days | |
| const firstDay = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1).getDay(); | |
| const daysInMonth = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 0).getDate(); | |
| // Clear calendar | |
| calendarDaysEl.innerHTML = ''; | |
| // Add empty cells for days before the first day of the month | |
| for (let i = 0; i < firstDay; i++) { | |
| const emptyCell = document.createElement('div'); | |
| emptyCell.className = 'h-12'; | |
| calendarDaysEl.appendChild(emptyCell); | |
| } | |
| // Add cells for each day of the month | |
| for (let day = 1; day <= daysInMonth; day++) { | |
| const dayCell = document.createElement('div'); | |
| dayCell.className = 'h-12 border border-gray-200 flex items-center justify-center calendar-day'; | |
| dayCell.textContent = day; | |
| // Check if this day has tasks | |
| const dateStr = `${currentDate.getFullYear()}-${(currentDate.getMonth() + 1).toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`; | |
| const dayTasks = tasks.filter(task => task.dueDate === dateStr); | |
| if (dayTasks.length > 0) { | |
| dayCell.classList.add('has-tasks'); | |
| } | |
| // Add click event to show tasks for this day | |
| dayCell.addEventListener('click', () => { | |
| selectedDay = dateStr; | |
| showDayTasks(dateStr); | |
| }); | |
| calendarDaysEl.appendChild(dayCell); | |
| } | |
| } | |
| // Show tasks for a specific day | |
| function showDayTasks(dateStr) { | |
| const date = new Date(dateStr); | |
| const options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }; | |
| selectedDayEl.textContent = date.toLocaleDateString('en-US', options); | |
| // Filter tasks for this day | |
| const dayTasks = tasks.filter(task => task.dueDate === dateStr); | |
| // Clear previous tasks | |
| dayTasksListEl.innerHTML = ''; | |
| if (dayTasks.length === 0) { | |
| dayTasksListEl.innerHTML = '<p class="text-gray-500">No tasks for this day</p>'; | |
| return; | |
| } | |
| // Add tasks to the list | |
| dayTasks.forEach(task => { | |
| const taskElement = createTaskElement(task, true); | |
| dayTasksListEl.appendChild(taskElement); | |
| }); | |
| } | |
| // Create a task element | |
| function createTaskElement(task, showDelete) { | |
| const taskElement = document.createElement('div'); | |
| taskElement.className = 'bg-white p-3 rounded shadow task-card'; | |
| taskElement.id = `task-${task.id}`; | |
| taskElement.dataset.id = task.id; | |
| // Determine priority color | |
| let priorityClass = ''; | |
| if (task.urgency === 'urgent' && task.importance === 'important') { | |
| priorityClass = 'bg-red-100 text-red-800'; | |
| } else if (task.urgency === 'not-urgent' && task.importance === 'important') { | |
| priorityClass = 'bg-yellow-100 text-yellow-800'; | |
| } else if (task.urgency === 'urgent' && task.importance === 'not-important') { | |
| priorityClass = 'bg-blue-100 text-blue-800'; | |
| } else { | |
| priorityClass = 'bg-green-100 text-green-800'; | |
| } | |
| // Task content | |
| taskElement.innerHTML = ` | |
| <div class="flex justify-between items-start mb-1"> | |
| <h3 class="font-medium">${task.title}</h3> | |
| <span class="text-xs px-2 py-1 rounded-full ${priorityClass}"> | |
| ${task.urgency === 'urgent' ? 'Urgent' : 'Not Urgent'}, | |
| ${task.importance === 'important' ? 'Important' : 'Not Important'} | |
| </span> | |
| </div> | |
| ${task.description ? `<p class="text-sm text-gray-600 mb-2">${task.description}</p>` : ''} | |
| ${task.dueDate ? `<p class="text-xs text-gray-500"><i class="far fa-calendar-alt mr-1"></i> Due: ${formatDate(task.dueDate)}</p>` : ''} | |
| <div class="mt-2 flex justify-between items-center"> | |
| <span class="text-xs text-gray-400">Created: ${formatDate(task.createdAt, true)}</span> | |
| ${showDelete ? `<button class="delete-task text-red-500 hover:text-red-700 text-sm" data-id="${task.id}"> | |
| <i class="fas fa-trash-alt"></i> Delete | |
| </button>` : ''} | |
| </div> | |
| `; | |
| // Add delete event listener if needed | |
| if (showDelete) { | |
| const deleteBtn = taskElement.querySelector('.delete-task'); | |
| deleteBtn.addEventListener('click', (e) => { | |
| e.stopPropagation(); | |
| deleteTask(task.id); | |
| }); | |
| } | |
| return taskElement; | |
| } | |
| // Delete a task | |
| function deleteTask(taskId) { | |
| if (confirm('Are you sure you want to delete this task?')) { | |
| tasks = tasks.filter(task => task.id !== taskId); | |
| saveTasks(); | |
| renderMatrixView(); | |
| renderKanbanView(); | |
| renderCalendar(); | |
| // If viewing day tasks, update that view too | |
| if (selectedDay) { | |
| showDayTasks(selectedDay); | |
| } | |
| } | |
| } | |
| // Helper function to format dates | |
| function formatDate(dateStr, includeTime = false) { | |
| const date = new Date(dateStr); | |
| if (includeTime) { | |
| return date.toLocaleString('en-US', { | |
| month: 'short', | |
| day: 'numeric', | |
| year: 'numeric', | |
| hour: '2-digit', | |
| minute: '2-digit' | |
| }); | |
| } else { | |
| return date.toLocaleDateString('en-US', { | |
| month: 'short', | |
| day: 'numeric', | |
| year: 'numeric' | |
| }); | |
| } | |
| } | |
| // Helper function to format date for input field | |
| function formatDateForInput(date) { | |
| const d = new Date(date); | |
| let month = '' + (d.getMonth() + 1); | |
| let day = '' + d.getDate(); | |
| const year = d.getFullYear(); | |
| if (month.length < 2) month = '0' + month; | |
| if (day.length < 2) day = '0' + day; | |
| return [year, month, day].join('-'); | |
| } | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=mayankgrd/deepseek-task-matrix" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |