hharris928 commited on
Commit
095025a
·
verified ·
1 Parent(s): f69c167

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +6 -4
  2. index.html +967 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Task Manager 2
3
- emoji: 🌍
4
  colorFrom: gray
5
- colorTo: red
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: task-manager-2
3
+ emoji: 🐳
4
  colorFrom: gray
5
+ colorTo: blue
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,967 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Task Management Dashboard</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ .sidebar-item.active {
11
+ background-color: #F3F4F6;
12
+ border-left: 4px solid #4F46E5;
13
+ }
14
+ .status-completed {
15
+ background-color: #D1FAE5;
16
+ color: #065F46;
17
+ }
18
+ .status-in-progress {
19
+ background-color: #FEF3C7;
20
+ color: #92400E;
21
+ }
22
+ .status-pending {
23
+ background-color: #FEE2E2;
24
+ color: #991B1B;
25
+ }
26
+ .task-card:hover {
27
+ transform: translateY(-2px);
28
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
29
+ }
30
+ .progress-bar {
31
+ height: 6px;
32
+ border-radius: 3px;
33
+ background-color: #E5E7EB;
34
+ }
35
+ .progress-fill {
36
+ height: 100%;
37
+ border-radius: 3px;
38
+ background-color: #4F46E5;
39
+ }
40
+ .avatar-group {
41
+ display: flex;
42
+ }
43
+ .avatar {
44
+ width: 32px;
45
+ height: 32px;
46
+ border-radius: 50%;
47
+ border: 2px solid white;
48
+ margin-left: -8px;
49
+ }
50
+ .avatar:first-child {
51
+ margin-left: 0;
52
+ }
53
+ .kanban-column {
54
+ min-height: 400px;
55
+ background-color: #F9FAFB;
56
+ border-radius: 0.5rem;
57
+ }
58
+ .kanban-header {
59
+ border-top-left-radius: 0.5rem;
60
+ border-top-right-radius: 0.5rem;
61
+ padding: 0.75rem 1rem;
62
+ font-weight: 600;
63
+ }
64
+ .kanban-task-list {
65
+ min-height: 100px;
66
+ padding: 0.5rem;
67
+ }
68
+ .kanban-task {
69
+ margin-bottom: 0.75rem;
70
+ cursor: grab;
71
+ user-select: none;
72
+ }
73
+ .kanban-task.dragging {
74
+ opacity: 0.5;
75
+ transform: scale(1.02);
76
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
77
+ }
78
+ .view-toggle {
79
+ background-color: #E5E7EB;
80
+ border-radius: 0.375rem;
81
+ padding: 0.25rem;
82
+ }
83
+ .view-toggle-btn {
84
+ padding: 0.375rem 0.75rem;
85
+ border-radius: 0.25rem;
86
+ font-size: 0.875rem;
87
+ font-weight: 500;
88
+ }
89
+ .view-toggle-btn.active {
90
+ background-color: white;
91
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
92
+ }
93
+ .modal {
94
+ transition: opacity 0.3s ease;
95
+ }
96
+ .modal-overlay {
97
+ background-color: rgba(0, 0, 0, 0.5);
98
+ }
99
+ </style>
100
+ </head>
101
+ <body class="bg-gray-50 font-sans">
102
+ <div class="flex h-screen overflow-hidden">
103
+ <!-- Sidebar -->
104
+ <div class="hidden md:flex md:flex-shrink-0">
105
+ <div class="flex flex-col w-64 border-r border-gray-200 bg-white">
106
+ <div class="flex items-center h-16 px-4 border-b border-gray-200">
107
+ <div class="flex items-center">
108
+ <div class="w-8 h-8 rounded-full bg-indigo-500 flex items-center justify-center text-white font-bold">T</div>
109
+ <span class="ml-2 text-lg font-semibold">Task Manager</span>
110
+ </div>
111
+ </div>
112
+ <div class="flex flex-col flex-grow pt-4 pb-4 overflow-y-auto">
113
+ <nav class="flex-1 px-2 space-y-1">
114
+ <a href="#" class="sidebar-item active flex items-center px-4 py-3 text-sm font-medium text-gray-900 rounded-md">
115
+ <i class="fas fa-chart-pie mr-3 text-gray-500"></i>
116
+ Dashboard
117
+ </a>
118
+ <a href="#" class="sidebar-item flex items-center px-4 py-3 text-sm font-medium text-gray-600 rounded-md">
119
+ <i class="fas fa-tasks mr-3 text-gray-500"></i>
120
+ Projects
121
+ </a>
122
+ <a href="#" class="sidebar-item flex items-center px-4 py-3 text-sm font-medium text-gray-600 rounded-md">
123
+ <i class="fas fa-calendar-alt mr-3 text-gray-500"></i>
124
+ Calendar
125
+ </a>
126
+ <a href="#" class="sidebar-item flex items-center px-4 py-3 text-sm font-medium text-gray-600 rounded-md">
127
+ <i class="fas fa-users mr-3 text-gray-500"></i>
128
+ Team
129
+ </a>
130
+ <a href="#" class="sidebar-item flex items-center px-4 py-3 text-sm font-medium text-gray-600 rounded-md">
131
+ <i class="fas fa-file-alt mr-3 text-gray-500"></i>
132
+ Reports
133
+ </a>
134
+ <a href="#" class="sidebar-item flex items-center px-4 py-3 text-sm font-medium text-gray-600 rounded-md">
135
+ <i class="fas fa-cog mr-3 text-gray-500"></i>
136
+ Settings
137
+ </a>
138
+ </nav>
139
+ </div>
140
+ <div class="p-4 border-t border-gray-200">
141
+ <div class="flex items-center">
142
+ <img class="w-10 h-10 rounded-full" src="https://randomuser.me/api/portraits/women/44.jpg" alt="User profile">
143
+ <div class="ml-3">
144
+ <p class="text-sm font-medium text-gray-900">Sarah Johnson</p>
145
+ <p class="text-xs font-medium text-gray-500">Admin</p>
146
+ </div>
147
+ </div>
148
+ </div>
149
+ </div>
150
+ </div>
151
+
152
+ <!-- Main content -->
153
+ <div class="flex flex-col flex-1 overflow-hidden">
154
+ <!-- Top navigation -->
155
+ <div class="flex items-center justify-between h-16 px-6 border-b border-gray-200 bg-white">
156
+ <div class="flex items-center">
157
+ <button class="md:hidden p-2 rounded-md text-gray-500 hover:text-gray-600 hover:bg-gray-100 focus:outline-none">
158
+ <i class="fas fa-bars"></i>
159
+ </button>
160
+ <h1 class="ml-4 text-xl font-semibold text-gray-900">Dashboard</h1>
161
+ </div>
162
+ <div class="flex items-center space-x-4">
163
+ <div class="relative">
164
+ <input type="text" placeholder="Search..." class="pl-10 pr-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
165
+ <i class="fas fa-search absolute left-3 top-3 text-gray-400"></i>
166
+ </div>
167
+ <button class="p-2 text-gray-500 rounded-full hover:bg-gray-100">
168
+ <i class="fas fa-bell"></i>
169
+ </button>
170
+ <div class="relative">
171
+ <button class="flex items-center focus:outline-none">
172
+ <img class="w-8 h-8 rounded-full" src="https://randomuser.me/api/portraits/women/44.jpg" alt="User profile">
173
+ </button>
174
+ </div>
175
+ </div>
176
+ </div>
177
+
178
+ <!-- Content area -->
179
+ <div class="flex-1 overflow-auto p-6 bg-gray-50">
180
+ <!-- Stats Cards -->
181
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-6">
182
+ <div class="bg-white p-6 rounded-lg shadow">
183
+ <div class="flex items-center justify-between">
184
+ <div>
185
+ <p class="text-sm font-medium text-gray-500">Total Projects</p>
186
+ <p class="text-2xl font-bold text-gray-900 mt-1">24</p>
187
+ </div>
188
+ <div class="p-3 rounded-full bg-indigo-100 text-indigo-600">
189
+ <i class="fas fa-folder-open text-lg"></i>
190
+ </div>
191
+ </div>
192
+ <div class="mt-4">
193
+ <p class="text-xs text-gray-500">+2 from last week</p>
194
+ </div>
195
+ </div>
196
+ <div class="bg-white p-6 rounded-lg shadow">
197
+ <div class="flex items-center justify-between">
198
+ <div>
199
+ <p class="text-sm font-medium text-gray-500">Completed Tasks</p>
200
+ <p class="text-2xl font-bold text-gray-900 mt-1">156</p>
201
+ </div>
202
+ <div class="p-3 rounded-full bg-green-100 text-green-600">
203
+ <i class="fas fa-check-circle text-lg"></i>
204
+ </div>
205
+ </div>
206
+ <div class="mt-4">
207
+ <p class="text-xs text-gray-500">+12 from last week</p>
208
+ </div>
209
+ </div>
210
+ <div class="bg-white p-6 rounded-lg shadow">
211
+ <div class="flex items-center justify-between">
212
+ <div>
213
+ <p class="text-sm font-medium text-gray-500">Pending Tasks</p>
214
+ <p class="text-2xl font-bold text-gray-900 mt-1">32</p>
215
+ </div>
216
+ <div class="p-3 rounded-full bg-yellow-100 text-yellow-600">
217
+ <i class="fas fa-clock text-lg"></i>
218
+ </div>
219
+ </div>
220
+ <div class="mt-4">
221
+ <p class="text-xs text-gray-500">-5 from last week</p>
222
+ </div>
223
+ </div>
224
+ <div class="bg-white p-6 rounded-lg shadow">
225
+ <div class="flex items-center justify-between">
226
+ <div>
227
+ <p class="text-sm font-medium text-gray-500">Team Members</p>
228
+ <p class="text-2xl font-bold text-gray-900 mt-1">8</p>
229
+ </div>
230
+ <div class="p-3 rounded-full bg-blue-100 text-blue-600">
231
+ <i class="fas fa-users text-lg"></i>
232
+ </div>
233
+ </div>
234
+ <div class="mt-4">
235
+ <p class="text-xs text-gray-500">+1 from last week</p>
236
+ </div>
237
+ </div>
238
+ </div>
239
+
240
+ <!-- View Toggle -->
241
+ <div class="flex justify-between items-center mb-6">
242
+ <h2 class="text-lg font-semibold text-gray-900">My Tasks</h2>
243
+ <div class="flex items-center space-x-4">
244
+ <div class="view-toggle flex">
245
+ <button id="list-view-btn" class="view-toggle-btn">
246
+ <i class="fas fa-list mr-2"></i>List View
247
+ </button>
248
+ <button id="kanban-view-btn" class="view-toggle-btn active">
249
+ <i class="fas fa-columns mr-2"></i>Kanban View
250
+ </button>
251
+ </div>
252
+ <button id="add-task-btn" class="flex items-center px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">
253
+ <i class="fas fa-plus mr-2"></i>
254
+ Add Task
255
+ </button>
256
+ </div>
257
+ </div>
258
+
259
+ <!-- List View -->
260
+ <div id="list-view" class="hidden bg-white p-6 rounded-lg shadow mb-6">
261
+ <div class="space-y-4" id="list-view-tasks">
262
+ <!-- Tasks will be dynamically added here -->
263
+ </div>
264
+ </div>
265
+
266
+ <!-- Kanban View -->
267
+ <div id="kanban-view" class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-6">
268
+ <!-- To Do Column -->
269
+ <div class="kanban-column">
270
+ <div class="kanban-header bg-blue-100 text-blue-800">
271
+ <div class="flex justify-between items-center">
272
+ <span>To Do</span>
273
+ <span class="text-xs bg-blue-200 text-blue-800 px-2 py-1 rounded-full" id="todo-count">0 tasks</span>
274
+ </div>
275
+ </div>
276
+ <div class="kanban-task-list" id="todo-column">
277
+ <!-- Tasks will be dynamically added here -->
278
+ </div>
279
+ </div>
280
+
281
+ <!-- In Progress Column -->
282
+ <div class="kanban-column">
283
+ <div class="kanban-header bg-yellow-100 text-yellow-800">
284
+ <div class="flex justify-between items-center">
285
+ <span>In Progress</span>
286
+ <span class="text-xs bg-yellow-200 text-yellow-800 px-2 py-1 rounded-full" id="inprogress-count">0 tasks</span>
287
+ </div>
288
+ </div>
289
+ <div class="kanban-task-list" id="inprogress-column">
290
+ <!-- Tasks will be dynamically added here -->
291
+ </div>
292
+ </div>
293
+
294
+ <!-- Done Column -->
295
+ <div class="kanban-column">
296
+ <div class="kanban-header bg-green-100 text-green-800">
297
+ <div class="flex justify-between items-center">
298
+ <span>Done</span>
299
+ <span class="text-xs bg-green-200 text-green-800 px-2 py-1 rounded-full" id="done-count">0 tasks</span>
300
+ </div>
301
+ </div>
302
+ <div class="kanban-task-list" id="done-column">
303
+ <!-- Tasks will be dynamically added here -->
304
+ </div>
305
+ </div>
306
+ </div>
307
+
308
+ <!-- Recent Activity -->
309
+ <div class="bg-white p-6 rounded-lg shadow">
310
+ <h2 class="text-lg font-semibold text-gray-900 mb-6">Recent Activity</h2>
311
+ <div class="space-y-4" id="recent-activity">
312
+ <!-- Activity will be dynamically added here -->
313
+ </div>
314
+ </div>
315
+ </div>
316
+ </div>
317
+ </div>
318
+
319
+ <!-- Add/Edit Task Modal -->
320
+ <div id="task-modal" class="fixed inset-0 z-50 flex items-center justify-center modal hidden opacity-0">
321
+ <div class="modal-overlay absolute inset-0 bg-gray-500 opacity-50"></div>
322
+ <div class="bg-white rounded-lg shadow-xl z-50 w-full max-w-md">
323
+ <div class="p-6">
324
+ <div class="flex justify-between items-center mb-4">
325
+ <h3 class="text-lg font-semibold text-gray-900" id="modal-title">Add New Task</h3>
326
+ <button id="close-modal" class="text-gray-400 hover:text-gray-500">
327
+ <i class="fas fa-times"></i>
328
+ </button>
329
+ </div>
330
+ <form id="task-form">
331
+ <input type="hidden" id="task-id">
332
+ <div class="mb-4">
333
+ <label for="task-title" class="block text-sm font-medium text-gray-700 mb-1">Title</label>
334
+ <input type="text" id="task-title" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500" required>
335
+ </div>
336
+ <div class="mb-4">
337
+ <label for="task-description" class="block text-sm font-medium text-gray-700 mb-1">Description</label>
338
+ <textarea id="task-description" rows="3" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"></textarea>
339
+ </div>
340
+ <div class="mb-4">
341
+ <label for="task-project" class="block text-sm font-medium text-gray-700 mb-1">Project</label>
342
+ <input type="text" id="task-project" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
343
+ </div>
344
+ <div class="mb-4">
345
+ <label for="task-status" class="block text-sm font-medium text-gray-700 mb-1">Status</label>
346
+ <select id="task-status" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
347
+ <option value="pending">Pending</option>
348
+ <option value="in-progress">In Progress</option>
349
+ <option value="completed">Completed</option>
350
+ </select>
351
+ </div>
352
+ <div class="mb-4">
353
+ <label for="task-due-date" class="block text-sm font-medium text-gray-700 mb-1">Due Date</label>
354
+ <input type="date" id="task-due-date" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
355
+ </div>
356
+ <div class="mb-4">
357
+ <label class="block text-sm font-medium text-gray-700 mb-1">Assignees</label>
358
+ <div class="flex flex-wrap gap-2">
359
+ <div class="flex items-center">
360
+ <input type="checkbox" id="assignee-1" class="h-4 w-4 text-indigo-600 border-gray-300 rounded focus:ring-indigo-500" value="1">
361
+ <label for="assignee-1" class="ml-2 text-sm text-gray-700">John Smith</label>
362
+ </div>
363
+ <div class="flex items-center">
364
+ <input type="checkbox" id="assignee-2" class="h-4 w-4 text-indigo-600 border-gray-300 rounded focus:ring-indigo-500" value="2">
365
+ <label for="assignee-2" class="ml-2 text-sm text-gray-700">Emma Wilson</label>
366
+ </div>
367
+ <div class="flex items-center">
368
+ <input type="checkbox" id="assignee-3" class="h-4 w-4 text-indigo-600 border-gray-300 rounded focus:ring-indigo-500" value="3">
369
+ <label for="assignee-3" class="ml-2 text-sm text-gray-700">Michael Brown</label>
370
+ </div>
371
+ </div>
372
+ </div>
373
+ <div class="flex justify-end space-x-3">
374
+ <button type="button" id="cancel-task" class="px-4 py-2 border border-gray-300 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
375
+ Cancel
376
+ </button>
377
+ <button type="submit" class="px-4 py-2 bg-indigo-600 text-white rounded-md text-sm font-medium hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
378
+ Save Task
379
+ </button>
380
+ </div>
381
+ </form>
382
+ </div>
383
+ </div>
384
+ </div>
385
+
386
+ <!-- Delete Confirmation Modal -->
387
+ <div id="delete-modal" class="fixed inset-0 z-50 flex items-center justify-center modal hidden opacity-0">
388
+ <div class="modal-overlay absolute inset-0 bg-gray-500 opacity-50"></div>
389
+ <div class="bg-white rounded-lg shadow-xl z-50 w-full max-w-md">
390
+ <div class="p-6">
391
+ <div class="flex justify-between items-center mb-4">
392
+ <h3 class="text-lg font-semibold text-gray-900">Confirm Deletion</h3>
393
+ <button id="close-delete-modal" class="text-gray-400 hover:text-gray-500">
394
+ <i class="fas fa-times"></i>
395
+ </button>
396
+ </div>
397
+ <p class="text-gray-700 mb-6">Are you sure you want to delete this task? This action cannot be undone.</p>
398
+ <div class="flex justify-end space-x-3">
399
+ <button type="button" id="cancel-delete" class="px-4 py-2 border border-gray-300 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
400
+ Cancel
401
+ </button>
402
+ <button type="button" id="confirm-delete" class="px-4 py-2 bg-red-600 text-white rounded-md text-sm font-medium hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:border-red-500">
403
+ Delete
404
+ </button>
405
+ </div>
406
+ </div>
407
+ </div>
408
+ </div>
409
+
410
+ <script>
411
+ // Sample data for tasks
412
+ let tasks = [
413
+ {
414
+ id: 1,
415
+ title: "Design new homepage layout",
416
+ description: "Create wireframes and mockups for the new homepage design",
417
+ project: "Website Redesign",
418
+ status: "pending",
419
+ dueDate: "2023-06-15",
420
+ assignees: [1, 2],
421
+ createdAt: new Date()
422
+ },
423
+ {
424
+ id: 2,
425
+ title: "Review app prototype",
426
+ description: "Test and provide feedback on the new mobile app prototype",
427
+ project: "Mobile App Development",
428
+ status: "completed",
429
+ dueDate: "2023-06-10",
430
+ assignees: [3],
431
+ createdAt: new Date()
432
+ },
433
+ {
434
+ id: 3,
435
+ title: "Write blog post about launch",
436
+ description: "Create content for the product launch announcement",
437
+ project: "Product Launch",
438
+ status: "pending",
439
+ dueDate: "2023-06-18",
440
+ assignees: [1],
441
+ createdAt: new Date()
442
+ },
443
+ {
444
+ id: 4,
445
+ title: "Create social media content",
446
+ description: "Design graphics and write captions for social media posts",
447
+ project: "Content Marketing",
448
+ status: "in-progress",
449
+ dueDate: "2023-06-17",
450
+ assignees: [2],
451
+ createdAt: new Date()
452
+ }
453
+ ];
454
+
455
+ // Sample data for team members
456
+ const teamMembers = [
457
+ { id: 1, name: "John Smith", avatar: "https://randomuser.me/api/portraits/men/32.jpg" },
458
+ { id: 2, name: "Emma Wilson", avatar: "https://randomuser.me/api/portraits/women/12.jpg" },
459
+ { id: 3, name: "Michael Brown", avatar: "https://randomuser.me/api/portraits/men/45.jpg" }
460
+ ];
461
+
462
+ // DOM elements
463
+ const listViewBtn = document.getElementById('list-view-btn');
464
+ const kanbanViewBtn = document.getElementById('kanban-view-btn');
465
+ const listView = document.getElementById('list-view');
466
+ const kanbanView = document.getElementById('kanban-view');
467
+ const addTaskBtn = document.getElementById('add-task-btn');
468
+ const taskModal = document.getElementById('task-modal');
469
+ const deleteModal = document.getElementById('delete-modal');
470
+ const taskForm = document.getElementById('task-form');
471
+ const taskIdInput = document.getElementById('task-id');
472
+ const taskTitleInput = document.getElementById('task-title');
473
+ const taskDescriptionInput = document.getElementById('task-description');
474
+ const taskProjectInput = document.getElementById('task-project');
475
+ const taskStatusInput = document.getElementById('task-status');
476
+ const taskDueDateInput = document.getElementById('task-due-date');
477
+ const closeModalBtn = document.getElementById('close-modal');
478
+ const cancelTaskBtn = document.getElementById('cancel-task');
479
+ const closeDeleteModalBtn = document.getElementById('close-delete-modal');
480
+ const cancelDeleteBtn = document.getElementById('cancel-delete');
481
+ const confirmDeleteBtn = document.getElementById('confirm-delete');
482
+ const modalTitle = document.getElementById('modal-title');
483
+ const todoCount = document.getElementById('todo-count');
484
+ const inprogressCount = document.getElementById('inprogress-count');
485
+ const doneCount = document.getElementById('done-count');
486
+ const recentActivity = document.getElementById('recent-activity');
487
+
488
+ // Current task to be deleted
489
+ let taskToDelete = null;
490
+
491
+ // Initialize the app
492
+ document.addEventListener('DOMContentLoaded', () => {
493
+ renderTasks();
494
+ setupDragAndDrop();
495
+ setupEventListeners();
496
+ renderRecentActivity();
497
+ });
498
+
499
+ // Render tasks in both list and kanban views
500
+ function renderTasks() {
501
+ renderListView();
502
+ renderKanbanView();
503
+ updateTaskCounts();
504
+ }
505
+
506
+ // Render list view
507
+ function renderListView() {
508
+ const listViewTasks = document.getElementById('list-view-tasks');
509
+ listViewTasks.innerHTML = '';
510
+
511
+ tasks.forEach(task => {
512
+ const statusClass = getStatusClass(task.status);
513
+ const statusText = getStatusText(task.status);
514
+
515
+ const taskElement = document.createElement('div');
516
+ taskElement.className = 'flex items-center justify-between p-4 border border-gray-200 rounded-lg';
517
+ taskElement.dataset.taskId = task.id;
518
+ taskElement.innerHTML = `
519
+ <div class="flex items-center">
520
+ <input type="checkbox" class="h-4 w-4 text-indigo-600 border-gray-300 rounded focus:ring-indigo-500" ${task.status === 'completed' ? 'checked' : ''}>
521
+ <div class="ml-4">
522
+ <p class="text-sm font-medium text-gray-900">${task.title}</p>
523
+ <p class="text-xs text-gray-500">${task.project} project</p>
524
+ </div>
525
+ </div>
526
+ <div class="flex items-center">
527
+ <span class="px-2 py-1 text-xs font-medium rounded-full ${statusClass} mr-4">
528
+ ${statusText}
529
+ </span>
530
+ <span class="text-xs text-gray-500">${getDueDateText(task.dueDate)}</span>
531
+ <button class="ml-4 text-gray-400 hover:text-gray-500 edit-task" data-task-id="${task.id}">
532
+ <i class="fas fa-edit"></i>
533
+ </button>
534
+ <button class="ml-2 text-gray-400 hover:text-gray-500 delete-task" data-task-id="${task.id}">
535
+ <i class="fas fa-trash"></i>
536
+ </button>
537
+ </div>
538
+ `;
539
+
540
+ listViewTasks.appendChild(taskElement);
541
+ });
542
+
543
+ // Add event listeners to edit and delete buttons
544
+ document.querySelectorAll('.edit-task').forEach(btn => {
545
+ btn.addEventListener('click', (e) => {
546
+ const taskId = parseInt(btn.dataset.taskId);
547
+ openEditTaskModal(taskId);
548
+ });
549
+ });
550
+
551
+ document.querySelectorAll('.delete-task').forEach(btn => {
552
+ btn.addEventListener('click', (e) => {
553
+ const taskId = parseInt(btn.dataset.taskId);
554
+ openDeleteTaskModal(taskId);
555
+ });
556
+ });
557
+ }
558
+
559
+ // Render kanban view
560
+ function renderKanbanView() {
561
+ const todoColumn = document.getElementById('todo-column');
562
+ const inprogressColumn = document.getElementById('inprogress-column');
563
+ const doneColumn = document.getElementById('done-column');
564
+
565
+ todoColumn.innerHTML = '';
566
+ inprogressColumn.innerHTML = '';
567
+ doneColumn.innerHTML = '';
568
+
569
+ tasks.forEach(task => {
570
+ const statusClass = getStatusClass(task.status);
571
+ const statusText = getStatusText(task.status);
572
+ const assignees = getAssignees(task.assignees);
573
+
574
+ const taskElement = document.createElement('div');
575
+ taskElement.className = 'kanban-task bg-white p-4 rounded-lg shadow border border-gray-200';
576
+ taskElement.draggable = true;
577
+ taskElement.dataset.taskId = task.id;
578
+ taskElement.innerHTML = `
579
+ <div class="flex items-start justify-between mb-2">
580
+ <h3 class="text-sm font-medium text-gray-900">${task.title}</h3>
581
+ <span class="px-2 py-1 text-xs font-medium rounded-full ${statusClass}">
582
+ ${statusText}
583
+ </span>
584
+ </div>
585
+ <p class="text-xs text-gray-500 mb-3">${task.project} project</p>
586
+ <div class="flex items-center justify-between">
587
+ <div class="avatar-group">
588
+ ${assignees.map(assignee => `
589
+ <img class="avatar" src="${assignee.avatar}" alt="${assignee.name}" title="${assignee.name}">
590
+ `).join('')}
591
+ </div>
592
+ <span class="text-xs text-gray-500">${getDueDateText(task.dueDate)}</span>
593
+ </div>
594
+ <div class="flex justify-end mt-3 space-x-2">
595
+ <button class="text-gray-400 hover:text-gray-500 edit-task" data-task-id="${task.id}">
596
+ <i class="fas fa-edit text-sm"></i>
597
+ </button>
598
+ <button class="text-gray-400 hover:text-gray-500 delete-task" data-task-id="${task.id}">
599
+ <i class="fas fa-trash text-sm"></i>
600
+ </button>
601
+ </div>
602
+ `;
603
+
604
+ // Add to appropriate column based on status
605
+ if (task.status === 'pending') {
606
+ todoColumn.appendChild(taskElement);
607
+ } else if (task.status === 'in-progress') {
608
+ inprogressColumn.appendChild(taskElement);
609
+ } else if (task.status === 'completed') {
610
+ doneColumn.appendChild(taskElement);
611
+ }
612
+ });
613
+
614
+ // Add event listeners to edit and delete buttons
615
+ document.querySelectorAll('.edit-task').forEach(btn => {
616
+ btn.addEventListener('click', (e) => {
617
+ e.stopPropagation();
618
+ const taskId = parseInt(btn.dataset.taskId);
619
+ openEditTaskModal(taskId);
620
+ });
621
+ });
622
+
623
+ document.querySelectorAll('.delete-task').forEach(btn => {
624
+ btn.addEventListener('click', (e) => {
625
+ e.stopPropagation();
626
+ const taskId = parseInt(btn.dataset.taskId);
627
+ openDeleteTaskModal(taskId);
628
+ });
629
+ });
630
+ }
631
+
632
+ // Update task counts in kanban view
633
+ function updateTaskCounts() {
634
+ const todoTasks = tasks.filter(task => task.status === 'pending').length;
635
+ const inprogressTasks = tasks.filter(task => task.status === 'in-progress').length;
636
+ const doneTasks = tasks.filter(task => task.status === 'completed').length;
637
+
638
+ todoCount.textContent = `${todoTasks} ${todoTasks === 1 ? 'task' : 'tasks'}`;
639
+ inprogressCount.textContent = `${inprogressTasks} ${inprogressTasks === 1 ? 'task' : 'tasks'}`;
640
+ doneCount.textContent = `${doneTasks} ${doneTasks === 1 ? 'task' : 'tasks'}`;
641
+ }
642
+
643
+ // Render recent activity
644
+ function renderRecentActivity() {
645
+ // Sort tasks by creation date (newest first)
646
+ const sortedTasks = [...tasks].sort((a, b) => b.createdAt - a.createdAt);
647
+
648
+ // Take the 3 most recent tasks
649
+ const recentTasks = sortedTasks.slice(0, 3);
650
+
651
+ recentActivity.innerHTML = recentTasks.map(task => {
652
+ const assignee = teamMembers.find(member => member.id === task.assignees[0]);
653
+ const action = task.status === 'completed' ? 'completed' :
654
+ task.status === 'in-progress' ? 'started working on' : 'created';
655
+
656
+ return `
657
+ <div class="flex">
658
+ <div class="flex-shrink-0">
659
+ <img class="h-10 w-10 rounded-full" src="${assignee.avatar}" alt="${assignee.name}">
660
+ </div>
661
+ <div class="ml-3">
662
+ <p class="text-sm font-medium text-gray-900">${assignee.name} <span class="text-gray-500">${action}</span> "${task.title}"</p>
663
+ <p class="text-xs text-gray-500">${task.project} project</p>
664
+ <p class="text-xs text-gray-400 mt-1">${formatDate(task.createdAt)}</p>
665
+ </div>
666
+ </div>
667
+ `;
668
+ }).join('');
669
+ }
670
+
671
+ // Setup drag and drop functionality
672
+ function setupDragAndDrop() {
673
+ const tasks = document.querySelectorAll('.kanban-task');
674
+ const columns = document.querySelectorAll('.kanban-task-list');
675
+
676
+ let draggedTask = null;
677
+
678
+ tasks.forEach(task => {
679
+ task.addEventListener('dragstart', () => {
680
+ draggedTask = task;
681
+ setTimeout(() => {
682
+ task.classList.add('dragging');
683
+ }, 0);
684
+ });
685
+
686
+ task.addEventListener('dragend', () => {
687
+ task.classList.remove('dragging');
688
+ draggedTask = null;
689
+ });
690
+ });
691
+
692
+ columns.forEach(column => {
693
+ column.addEventListener('dragover', e => {
694
+ e.preventDefault();
695
+ const afterElement = getDragAfterElement(column, e.clientY);
696
+ if (afterElement == null) {
697
+ column.appendChild(draggedTask);
698
+ } else {
699
+ column.insertBefore(draggedTask, afterElement);
700
+ }
701
+ });
702
+
703
+ column.addEventListener('drop', () => {
704
+ const taskId = parseInt(draggedTask.dataset.taskId);
705
+ const task = tasks.find(t => t.id === taskId);
706
+
707
+ // Determine new status based on column
708
+ let newStatus = 'pending';
709
+ if (column.id === 'inprogress-column') {
710
+ newStatus = 'in-progress';
711
+ } else if (column.id === 'done-column') {
712
+ newStatus = 'completed';
713
+ }
714
+
715
+ // Update task status
716
+ task.status = newStatus;
717
+
718
+ // Update UI
719
+ renderTasks();
720
+ renderRecentActivity();
721
+ });
722
+ });
723
+
724
+ function getDragAfterElement(column, y) {
725
+ const draggableElements = [...column.querySelectorAll('.kanban-task:not(.dragging)')];
726
+
727
+ return draggableElements.reduce((closest, child) => {
728
+ const box = child.getBoundingClientRect();
729
+ const offset = y - box.top - box.height / 2;
730
+
731
+ if (offset < 0 && offset > closest.offset) {
732
+ return { offset: offset, element: child };
733
+ } else {
734
+ return closest;
735
+ }
736
+ }, { offset: Number.NEGATIVE_INFINITY }).element;
737
+ }
738
+ }
739
+
740
+ // Setup event listeners
741
+ function setupEventListeners() {
742
+ // Sidebar item active state
743
+ const sidebarItems = document.querySelectorAll('.sidebar-item');
744
+ sidebarItems.forEach(item => {
745
+ item.addEventListener('click', (e) => {
746
+ e.preventDefault();
747
+ sidebarItems.forEach(i => i.classList.remove('active'));
748
+ item.classList.add('active');
749
+ });
750
+ });
751
+
752
+ // View toggle functionality
753
+ listViewBtn.addEventListener('click', () => {
754
+ listViewBtn.classList.add('active');
755
+ kanbanViewBtn.classList.remove('active');
756
+ listView.classList.remove('hidden');
757
+ kanbanView.classList.add('hidden');
758
+ });
759
+
760
+ kanbanViewBtn.addEventListener('click', () => {
761
+ kanbanViewBtn.classList.add('active');
762
+ listViewBtn.classList.remove('active');
763
+ kanbanView.classList.remove('hidden');
764
+ listView.classList.add('hidden');
765
+ });
766
+
767
+ // Add task button
768
+ addTaskBtn.addEventListener('click', () => {
769
+ openAddTaskModal();
770
+ });
771
+
772
+ // Task form submission
773
+ taskForm.addEventListener('submit', (e) => {
774
+ e.preventDefault();
775
+ saveTask();
776
+ });
777
+
778
+ // Modal close buttons
779
+ closeModalBtn.addEventListener('click', closeTaskModal);
780
+ cancelTaskBtn.addEventListener('click', closeTaskModal);
781
+ closeDeleteModalBtn.addEventListener('click', closeDeleteModal);
782
+ cancelDeleteBtn.addEventListener('click', closeDeleteModal);
783
+
784
+ // Delete confirmation
785
+ confirmDeleteBtn.addEventListener('click', () => {
786
+ if (taskToDelete) {
787
+ deleteTask(taskToDelete);
788
+ closeDeleteModal();
789
+ }
790
+ });
791
+ }
792
+
793
+ // Open add task modal
794
+ function openAddTaskModal() {
795
+ modalTitle.textContent = 'Add New Task';
796
+ taskIdInput.value = '';
797
+ taskTitleInput.value = '';
798
+ taskDescriptionInput.value = '';
799
+ taskProjectInput.value = '';
800
+ taskStatusInput.value = 'pending';
801
+ taskDueDateInput.value = '';
802
+
803
+ // Clear assignee checkboxes
804
+ document.querySelectorAll('input[type="checkbox"]').forEach(checkbox => {
805
+ checkbox.checked = false;
806
+ });
807
+
808
+ openModal(taskModal);
809
+ }
810
+
811
+ // Open edit task modal
812
+ function openEditTaskModal(taskId) {
813
+ const task = tasks.find(t => t.id === taskId);
814
+ if (!task) return;
815
+
816
+ modalTitle.textContent = 'Edit Task';
817
+ taskIdInput.value = task.id;
818
+ taskTitleInput.value = task.title;
819
+ taskDescriptionInput.value = task.description || '';
820
+ taskProjectInput.value = task.project || '';
821
+ taskStatusInput.value = task.status;
822
+ taskDueDateInput.value = task.dueDate || '';
823
+
824
+ // Set assignee checkboxes
825
+ document.querySelectorAll('input[type="checkbox"]').forEach(checkbox => {
826
+ checkbox.checked = task.assignees.includes(parseInt(checkbox.value));
827
+ });
828
+
829
+ openModal(taskModal);
830
+ }
831
+
832
+ // Open delete task modal
833
+ function openDeleteTaskModal(taskId) {
834
+ taskToDelete = taskId;
835
+ openModal(deleteModal);
836
+ }
837
+
838
+ // Open modal
839
+ function openModal(modal) {
840
+ modal.classList.remove('hidden');
841
+ setTimeout(() => {
842
+ modal.classList.add('opacity-100');
843
+ }, 10);
844
+ }
845
+
846
+ // Close task modal
847
+ function closeTaskModal() {
848
+ taskModal.classList.remove('opacity-100');
849
+ setTimeout(() => {
850
+ taskModal.classList.add('hidden');
851
+ }, 300);
852
+ }
853
+
854
+ // Close delete modal
855
+ function closeDeleteModal() {
856
+ taskToDelete = null;
857
+ deleteModal.classList.remove('opacity-100');
858
+ setTimeout(() => {
859
+ deleteModal.classList.add('hidden');
860
+ }, 300);
861
+ }
862
+
863
+ // Save task (add or update)
864
+ function saveTask() {
865
+ const taskId = taskIdInput.value ? parseInt(taskIdInput.value) : null;
866
+ const title = taskTitleInput.value;
867
+ const description = taskDescriptionInput.value;
868
+ const project = taskProjectInput.value;
869
+ const status = taskStatusInput.value;
870
+ const dueDate = taskDueDateInput.value;
871
+
872
+ // Get selected assignees
873
+ const assignees = [];
874
+ document.querySelectorAll('input[type="checkbox"]:checked').forEach(checkbox => {
875
+ assignees.push(parseInt(checkbox.value));
876
+ });
877
+
878
+ if (taskId) {
879
+ // Update existing task
880
+ const taskIndex = tasks.findIndex(t => t.id === taskId);
881
+ if (taskIndex !== -1) {
882
+ tasks[taskIndex] = {
883
+ ...tasks[taskIndex],
884
+ title,
885
+ description,
886
+ project,
887
+ status,
888
+ dueDate,
889
+ assignees,
890
+ createdAt: new Date()
891
+ };
892
+ }
893
+ } else {
894
+ // Add new task
895
+ const newId = tasks.length > 0 ? Math.max(...tasks.map(t => t.id)) + 1 : 1;
896
+ tasks.push({
897
+ id: newId,
898
+ title,
899
+ description,
900
+ project,
901
+ status,
902
+ dueDate,
903
+ assignees,
904
+ createdAt: new Date()
905
+ });
906
+ }
907
+
908
+ // Update UI
909
+ renderTasks();
910
+ renderRecentActivity();
911
+ closeTaskModal();
912
+ }
913
+
914
+ // Delete task
915
+ function deleteTask(taskId) {
916
+ tasks = tasks.filter(task => task.id !== taskId);
917
+ renderTasks();
918
+ renderRecentActivity();
919
+ }
920
+
921
+ // Helper functions
922
+ function getStatusClass(status) {
923
+ switch (status) {
924
+ case 'completed': return 'status-completed';
925
+ case 'in-progress': return 'status-in-progress';
926
+ default: return 'status-pending';
927
+ }
928
+ }
929
+
930
+ function getStatusText(status) {
931
+ switch (status) {
932
+ case 'completed': return 'Completed';
933
+ case 'in-progress': return 'In Progress';
934
+ default: return 'Pending';
935
+ }
936
+ }
937
+
938
+ function getDueDateText(dueDate) {
939
+ if (!dueDate) return 'No due date';
940
+
941
+ const today = new Date();
942
+ today.setHours(0, 0, 0, 0);
943
+
944
+ const due = new Date(dueDate);
945
+ due.setHours(0, 0, 0, 0);
946
+
947
+ const diffTime = due - today;
948
+ const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
949
+
950
+ if (diffDays === 0) return 'Due today';
951
+ if (diffDays === 1) return 'Due tomorrow';
952
+ if (diffDays === -1) return 'Due yesterday';
953
+ if (diffDays < 0) return `Due ${Math.abs(diffDays)} days ago`;
954
+ return `Due in ${diffDays} days`;
955
+ }
956
+
957
+ function getAssignees(assigneeIds) {
958
+ return teamMembers.filter(member => assigneeIds.includes(member.id));
959
+ }
960
+
961
+ function formatDate(date) {
962
+ const options = { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' };
963
+ return new Date(date).toLocaleDateString('en-US', options);
964
+ }
965
+ </script>
966
+ <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=hharris928/task-manager-2" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
967
+ </html>