|
|
| <!DOCTYPE html> |
| <html lang="en" class="h-full"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>TaskSphere | Tasks</title> |
| <link rel="icon" type="image/x-icon" href="/static/favicon.ico"> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> |
| <script> |
| tailwind.config = { |
| theme: { |
| extend: { |
| colors: { |
| primary: '#4F46E5', |
| secondary: '#10B981', |
| } |
| } |
| } |
| } |
| </script> |
| <style> |
| .task-card:hover { |
| transform: translateY(-2px); |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); |
| } |
| </style> |
| </head> |
| <body class="min-h-full bg-gray-50"> |
| |
| <nav class="bg-white shadow-sm"> |
| <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> |
| <div class="flex justify-between h-16"> |
| <div class="flex"> |
| <div class="flex-shrink-0 flex items-center"> |
| <i data-feather="compass" class="h-8 w-8 text-primary"></i> |
| <span class="ml-2 text-xl font-bold text-gray-900">TaskSphere</span> |
| </div> |
| <div class="hidden sm:ml-6 sm:flex sm:space-x-8"> |
| <a href="index.html" class="border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium">Dashboard</a> |
| <a href="department.html" class="border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium">Departments</a> |
| <a href="tasks.html" class="border-primary text-gray-900 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium">Tasks</a> |
| <a href="reports.html" class="border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium">Reports</a> |
| </div> |
| </div> |
| <div class="hidden sm:ml-6 sm:flex sm:items-center"> |
| <button type="button" class="bg-white p-1 rounded-full text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary"> |
| <i data-feather="bell" class="h-6 w-6"></i> |
| </button> |
| <div class="ml-3 relative"> |
| <div> |
| <button type="button" class="bg-white rounded-full flex text-sm focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary" id="user-menu" aria-expanded="false" aria-haspopup="true"> |
| <span class="sr-only">Open user menu</span> |
| <img class="h-8 w-8 rounded-full" src="http://static.photos/office/200x200/1" alt=""> |
| </button> |
| </div> |
| </div> |
| </div> |
| <div class="-mr-2 flex items-center sm:hidden"> |
| <button type="button" class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-primary" aria-controls="mobile-menu" aria-expanded="false"> |
| <span class="sr-only">Open main menu</span> |
| <i data-feather="menu" class="block h-6 w-6"></i> |
| <i data-feather="x" class="hidden h-6 w-6"></i> |
| </button> |
| </div> |
| </div> |
| </div> |
| </nav> |
|
|
| |
| <div class="py-10"> |
| <header> |
| <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> |
| <h1 class="text-3xl font-bold leading-tight text-gray-900">Task Management</h1> |
| <div class="mt-4 flex flex-col sm:flex-row sm:items-center"> |
| <div class="relative rounded-md shadow-sm w-full sm:w-64"> |
| <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none"> |
| <i data-feather="search" class="h-5 w-5 text-gray-400"></i> |
| </div> |
| <input type="text" class="focus:ring-primary focus:border-primary block w-full pl-10 sm:text-sm border-gray-300 rounded-md py-2" placeholder="Search tasks..."> |
| </div> |
| <div class="mt-2 sm:mt-0 sm:ml-4 flex space-x-2"> |
| <button type="button" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-primary hover:bg-primary-dark focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary"> |
| <i data-feather="plus" class="-ml-1 mr-2 h-5 w-5"></i> |
| New Task |
| </button> |
| <div class="relative"> |
| <button type="button" class="inline-flex items-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary"> |
| <i data-feather="filter" class="-ml-1 mr-2 h-5 w-5 text-gray-500"></i> |
| Filter |
| </button> |
| </div> |
| </div> |
| </div> |
| </div> |
| </header> |
| <main> |
| <div class="max-w-7xl mx-auto sm:px-6 lg:px-8"> |
| <div class="px-4 py-8 sm:px-0"> |
| |
| <div class="grid grid-cols-2 gap-4 sm:grid-cols-4 mb-8"> |
| <div class="bg-white overflow-hidden shadow rounded-lg"> |
| <div class="px-4 py-5 sm:p-6 text-center"> |
| <h3 class="text-sm font-medium text-gray-500">Pending</h3> |
| <p class="mt-1 text-3xl font-semibold text-yellow-500">24</p> |
| </div> |
| </div> |
| <div class="bg-white overflow-hidden shadow rounded-lg"> |
| <div class="px-4 py-5 sm:p-6 text-center"> |
| <h3 class="text-sm font-medium text-gray-500">In Progress</h3> |
| <p class="mt-1 text-3xl font-semibold text-blue-500">18</p> |
| </div> |
| </div> |
| <div class="bg-white overflow-hidden shadow rounded-lg"> |
| <div class="px-4 py-5 sm:p-6 text-center"> |
| <h3 class="text-sm font-medium text-gray-500">Completed</h3> |
| <p class="mt-1 text-3xl font-semibold text-green-500">142</p> |
| </div> |
| </div> |
| <div class="bg-white overflow-hidden shadow rounded-lg"> |
| <div class="px-4 py-5 sm:p-6 text-center"> |
| <h3 class="text-sm font-medium text-gray-500">Overdue</h3> |
| <p class="mt-1 text-3xl font-semibold text-red-500">5</p> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="bg-white shadow overflow-hidden sm:rounded-lg"> |
| <div class="border-b border-gray-200"> |
| <div class="px-4 py-5 sm:px-6"> |
| <h3 class="text-lg leading-6 font-medium text-gray-900">All Tasks</h3> |
| <p class="mt-1 text-sm text-gray-500">A list of all the tasks in your account.</p> |
| </div> |
| </div> |
| <ul class="divide-y divide-gray-200"> |
| |
| <li class="task-card transition duration-150 ease-in-out"> |
| <div class="px-4 py-4 sm:px-6"> |
| <div class="flex items-center justify-between"> |
| <div class="flex items-center"> |
| <div class="flex-shrink-0 h-10 w-10 rounded-full bg-blue-100 flex items-center justify-center"> |
| <i data-feather="code" class="h-5 w-5 text-blue-500"></i> |
| </div> |
| <div class="ml-4"> |
| <div class="text-sm font-medium text-gray-900">Implement new API endpoints</div> |
| <div class="text-sm text-gray-500">Development</div> |
| </div> |
| </div> |
| <div class="ml-2 flex-shrink-0 flex"> |
| <span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-100 text-blue-800">In Progress</span> |
| </div> |
| </div> |
| <div class="mt-2 sm:flex sm:justify-between"> |
| <div class="sm:flex"> |
| <div class="mr-6 flex items-center text-sm text-gray-500"> |
| <i data-feather="calendar" class="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"></i> |
| Due May 20, 2023 |
| </div> |
| <div class="mt-2 flex items-center text-sm text-gray-500 sm:mt-0"> |
| <i data-feather="user" class="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"></i> |
| Assigned to John Smith |
| </div> |
| </div> |
| <div class="mt-2 flex items-center text-sm text-gray-500 sm:mt-0"> |
| <i data-feather="clock" class="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"></i> |
| Started May 10, 2023 |
| </div> |
| </div> |
| </div> |
| </li> |
| |
| |
| <li class="task-card transition duration-150 ease-in-out"> |
| <div class="px-4 py-4 sm:px-6"> |
| <div class="flex items-center justify-between"> |
| <div class="flex items-center"> |
| <div class="flex-shrink-0 h-10 w-10 rounded-full bg-green-100 flex items-center justify-center"> |
| <i data-feather="check-circle" class="h-5 w-5 text-green-500"></i> |
| </div> |
| <div class="ml-4"> |
| <div class="text-sm font-medium text-gray-900">Launch new marketing campaign</div> |
| <div class="text-sm text-gray-500">Marketing</div> |
| </div> |
| </div> |
| <div class="ml-2 flex-shrink-0 flex"> |
| <span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">Completed</span> |
| </div> |
| </div> |
| <div class="mt-2 sm:flex sm:justify-between"> |
| <div class="sm:flex"> |
| <div class="mr-6 flex items-center text-sm text-gray-500"> |
| <i data-feather="calendar" class="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"></i> |
| Due May 15, 2023 |
| </div> |
| <div class="mt-2 flex items-center text-sm text-gray-500 sm:mt-0"> |
| <i data-feather="users" class="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"></i> |
| Team project |
| </div> |
| </div> |
| <div class="mt-2 flex items-center text-sm text-gray-500 sm:mt-0"> |
| <i data-feather="clock" class="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"></i> |
| Completed May 12, 2023 |
| </div> |
| </div> |
| </div> |
| </li> |
| |
| |
| <li class="task-card transition duration-150 ease-in-out"> |
| <div class="px-4 py-4 sm:px-6"> |
| <div class="flex items-center justify-between"> |
| <div class="flex items-center"> |
| <div class="flex-shrink-0 h-10 w-10 rounded-full bg-yellow-100 flex items-center justify-center"> |
| <i data-feather="user-plus" class="h-5 w-5 text-yellow-500"></i> |
| </div> |
| <div class="ml-4"> |
| <div class="text-sm font-medium text-gray-900">Hire new sales representatives</div> |
| <div class="text-sm text-gray-500">Human Resources</div> |
| </div> |
| </div> |
| <div class="ml-2 flex-shrink-0 flex"> |
| <span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-yellow-100 text-yellow-800">Pending</span> |
| </div> |
| </div> |
| <div class="mt-2 sm:flex sm:justify-between"> |
| <div class="sm:flex"> |
| <div class="mr-6 flex items-center text-sm text-gray-500"> |
| <i data-feather="calendar" class="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"></i> |
| Due June 1, 2023 |
| </div> |
| <div class="mt-2 flex items-center text-sm text-gray-500 sm:mt-0"> |
| <i data-feather="user" class="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"></i> |
| Assigned to Sarah Johnson |
| </div> |
| </div> |
| <div class="mt-2 flex items-center text-sm text-gray-500 sm:mt-0"> |
| <i data-feather="clock" class="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"></i> |
| Created May 5, 2023 |
| </div> |
| </div> |
| </div> |
| </li> |
| |
| |
| <li class="task-card transition duration-150 ease-in-out"> |
| <div class="px-4 py-4 sm:px-6"> |
| <div class="flex items-center justify-between"> |
| <div class="flex items-center"> |
| <div class="flex-shrink-0 h-10 w-10 rounded-full bg-red-100 flex items-center justify-center"> |
| <i data-feather="alert-triangle" class="h-5 w-5 text-red-500"></i> |
| </div> |
| <div class="ml-4"> |
| <div class="text-sm font-medium text-gray-900">Fix critical server issue</div> |
| <div class="text-sm text-gray-500">Operations</div> |
| </div> |
| </div> |
| <div class="ml-2 flex-shrink-0 flex"> |
| <span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">Overdue</span> |
| </div> |
| </div> |
| <div class="mt-2 sm:flex sm:justify-between"> |
| <div class="sm:flex"> |
| <div class="mr-6 flex items-center text-sm text-gray-500"> |
| <i data-feather="calendar" class="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"></i> |
| Due May 8, 2023 |
| </div> |
| <div class="mt-2 flex items-center text-sm text-gray-500 sm:mt-0"> |
| <i data-feather="user" class="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"></i> |
| Assigned to IT Team |
| </div> |
| </div> |
| <div class="mt-2 flex items-center text-sm text-gray-500 sm:mt-0"> |
| <i data-feather="clock" class="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"></i> |
| Started May 2, 2023 |
| </div> |
| </div> |
| </div> |
| </li> |
| </ul> |
| </div> |
| |
| |
| <div class="mt-4 flex items-center justify-between"> |
| <div class="flex-1 flex justify-between sm:hidden"> |
| <a href="#" class="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50">Previous</a> |
| <a href="#" class="ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50">Next</a> |
| </div> |
| <div class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between"> |
| <div> |
| <p class="text-sm text-gray-700"> |
| Showing <span class="font-medium">1</span> to <span class="font-medium">4</span> of <span class="font-medium">24</span> results |
| </p> |
| </div> |
| <div> |
| <nav class="relative z-0 inline-flex rounded-md shadow-sm -space-x-px" aria-label="Pagination"> |
| <a href="#" class="relative inline-flex items-center px-2 py-2 rounded-l-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50"> |
| <span class="sr-only">Previous</span> |
| <i data-feather="chevron-left" class="h-5 w-5"></i> |
| </a> |
| <a href="#" aria-current="page" class="z-10 bg-primary border-primary text-white relative inline-flex items-center px-4 py-2 border text-sm font-medium">1</a> |
| <a href="#" class="bg-white border-gray-300 text-gray-500 hover:bg-gray-50 relative inline-flex items-center px-4 py-2 border text-sm font-medium">2</a> |
| <a href="#" class="bg-white border-gray-300 text-gray-500 hover:bg-gray-50 relative inline-flex items-center px-4 py-2 border text-sm font-medium">3</a> |
| <a href="#" class="relative inline-flex items-center px-2 py-2 rounded-r-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50"> |
| <span class="sr-only">Next</span> |
| <i data-feather="chevron-right" class="h-5 w-5"></i> |
| </a> |
| </nav> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| </main> |
| </div> |
|
|
| <script> |
| |
| feather.replace(); |
| |
| |
| const API_BASE_URL = 'http://localhost:5000/api'; |
| let authToken = localStorage.getItem('authToken'); |
| |
| |
| document.addEventListener('DOMContentLoaded', function() { |
| if (!authToken) { |
| window.location.href = '/login.html'; |
| return; |
| } |
| loadTasks(); |
| }); |
| |
| async function loadTasks() { |
| try { |
| const response = await fetch(`${API_BASE_URL}/tasks`, { |
| headers: { |
| 'x-auth-token': authToken |
| } |
| }); |
| const tasks = await response.json(); |
| renderTasks(tasks); |
| } catch (error) { |
| console.error('Error loading tasks:', error); |
| } |
| } |
| |
| function renderTasks(tasks) { |
| const taskList = document.querySelector('ul'); |
| taskList.innerHTML = ''; |
| |
| tasks.forEach(task => { |
| const taskItem = document.createElement('li'); |
| taskItem.className = 'task-card transition duration-150 ease-in-out'; |
| taskItem.innerHTML = ` |
| <div class="px-4 py-4 sm:px-6"> |
| <div class="flex items-center justify-between"> |
| <div class="flex items-center"> |
| <div class="flex-shrink-0 h-10 w-10 rounded-full ${getStatusColor(task.status).bg} flex items-center justify-center"> |
| <i data-feather="${getTaskIcon(task.category)}" class="h-5 w-5 ${getStatusColor(task.status).text}"></i> |
| </div> |
| <div class="ml-4"> |
| <div class="text-sm font-medium text-gray-900">${task.title}</div> |
| <div class="text-sm text-gray-500">${task.department}</div> |
| </div> |
| </div> |
| <div class="ml-2 flex-shrink-0 flex"> |
| <span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${getStatusColor(task.status).bg} ${getStatusColor(task.status).text}"> |
| ${task.status} |
| </span> |
| </div> |
| </div> |
| <div class="mt-2 sm:flex sm:justify-between"> |
| <div class="sm:flex"> |
| <div class="mr-6 flex items-center text-sm text-gray-500"> |
| <i data-feather="calendar" class="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"></i> |
| Due ${new Date(task.dueDate).toLocaleDateString()} |
| </div> |
| <div class="mt-2 flex items-center text-sm text-gray-500 sm:mt-0"> |
| <i data-feather="user" class="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"></i> |
| Assigned to ${task.assignedTo} |
| </div> |
| </div> |
| <div class="mt-2 flex items-center text-sm text-gray-500 sm:mt-0"> |
| <i data-feather="clock" class="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"></i> |
| ${task.status === 'Completed' ? 'Completed' : 'Started'} ${new Date(task.startDate).toLocaleDateString()} |
| </div> |
| </div> |
| </div> |
| `; |
| taskList.appendChild(taskItem); |
| }); |
| feather.replace(); |
| } |
| |
| function getStatusColor(status) { |
| switch(status) { |
| case 'Completed': return { bg: 'bg-green-100', text: 'text-green-500' }; |
| case 'In Progress': return { bg: 'bg-blue-100', text: 'text-blue-500' }; |
| case 'Overdue': return { bg: 'bg-red-100', text: 'text-red-500' }; |
| default: return { bg: 'bg-yellow-100', text: 'text-yellow-500' }; |
| } |
| } |
| |
| function getTaskIcon(category) { |
| switch(category) { |
| case 'Development': return 'code'; |
| case 'Marketing': return 'trending-up'; |
| case 'HR': return 'users'; |
| case 'Finance': return 'dollar-sign'; |
| default: return 'check-circle'; |
| } |
| } |
| </script> |
| </body> |
| </html> |
|
|