Fadikkop commited on
Commit
4549c0d
·
verified ·
1 Parent(s): e1eb37c

Okay, die Aufgaben werden jetzt angezeigt. Ich möchte einen Knopf an jeder Aufgabe, um den Pomodoro Modus mit ihr zu starten. Wenn ich Aufgaben abhake, wird die Aufgabe nicht nach erledigt verschoben. Die Progress Bars für die Tags sollen nur für Tags angezeigt werden, die auch Aufgaben haben. Das Abhaken von Aufgaben soll visuell noch cooler aussehen, bisschen gamification. Und die Timeline soll eine schmale Seitenleiste rechts in der Übersicht sein. Implementiere all das!

Browse files
Files changed (5) hide show
  1. components/task-item.js +3 -3
  2. components/timeline-tasks.js +82 -0
  3. index.html +2 -1
  4. script.js +34 -25
  5. style.css +26 -1
components/task-item.js CHANGED
@@ -219,10 +219,10 @@ this.shadowRoot.innerHTML = `
219
  @change="${this.handleToggleComplete}">
220
  <span class="task-title">${title}</span>
221
  <div class="task-actions">
222
- <button class="task-action" @click="${this.handleFocus}" title="Fokus-Modus">
223
- <i data-feather="focus"></i>
224
  </button>
225
- <button class="task-action" @click="${this.handleEdit}" title="Bearbeiten">
226
  <i data-feather="edit-2"></i>
227
  </button>
228
  <button class="task-action" @click="${this.handleDelete}" title="Löschen">
 
219
  @change="${this.handleToggleComplete}">
220
  <span class="task-title">${title}</span>
221
  <div class="task-actions">
222
+ <button class="focus-btn" @click="${this.handleFocus}" title="Pomodoro starten">
223
+ <i data-feather="clock"></i>
224
  </button>
225
+ <button class="task-action" @click="${this.handleEdit}" title="Bearbeiten">
226
  <i data-feather="edit-2"></i>
227
  </button>
228
  <button class="task-action" @click="${this.handleDelete}" title="Löschen">
components/timeline-tasks.js ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class TimelineTasks extends HTMLElement {
2
+ connectedCallback() {
3
+ this.attachShadow({ mode: 'open' });
4
+ this.render();
5
+ }
6
+
7
+ render() {
8
+ this.shadowRoot.innerHTML = `
9
+ <style>
10
+ :host {
11
+ display: block;
12
+ background: #1f2937;
13
+ border-left: 1px solid #374151;
14
+ height: 100%;
15
+ width: 300px;
16
+ position: fixed;
17
+ right: 0;
18
+ top: 80px;
19
+ overflow-y: auto;
20
+ padding: 1rem;
21
+ }
22
+
23
+ h3 {
24
+ margin-top: 0;
25
+ color: #f97316;
26
+ padding-bottom: 1rem;
27
+ border-bottom: 1px solid #374151;
28
+ }
29
+
30
+ .task-list {
31
+ display: flex;
32
+ flex-direction: column;
33
+ gap: 8px;
34
+ }
35
+
36
+ .task-item {
37
+ background: #374151;
38
+ border-radius: 6px;
39
+ padding: 8px;
40
+ cursor: grab;
41
+ transition: all 0.2s ease;
42
+ }
43
+
44
+ .task-item:hover {
45
+ background: #4b5563;
46
+ transform: translateX(-4px);
47
+ }
48
+
49
+ .task-title {
50
+ font-size: 14px;
51
+ margin-bottom: 4px;
52
+ }
53
+
54
+ .task-time {
55
+ font-size: 12px;
56
+ color: #9ca3af;
57
+ }
58
+ </style>
59
+
60
+ <h3>Timeline</h3>
61
+ <div class="task-list" id="timeline-task-list"></div>
62
+ `;
63
+ }
64
+
65
+ updateTasks(tasks) {
66
+ const container = this.shadowRoot.getElementById('timeline-task-list');
67
+ container.innerHTML = tasks.map(task => `
68
+ <div class="task-item" draggable="true" data-task-id="${task.id}">
69
+ <div class="task-title">${task.title}</div>
70
+ <div class="task-time">${formatTime(task.estimatedTime)}</div>
71
+ </div>
72
+ `).join('');
73
+ }
74
+ }
75
+
76
+ customElements.define('timeline-tasks', TimelineTasks);
77
+
78
+ function formatTime(minutes) {
79
+ const h = Math.floor(minutes / 60);
80
+ const m = minutes % 60;
81
+ return `${h}h ${m}m`;
82
+ }
index.html CHANGED
@@ -226,9 +226,10 @@
226
  <i data-feather="plus"></i>
227
  </button>
228
  </div>
 
229
  <script src="components/task-item.js"></script>
230
  <script src="components/tag-item.js"></script>
231
- <script src="components/timeline-sidebar.js"></script>
232
  <script src="script.js"></script>
233
  <script>feather.replace();</script>
234
  <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
 
226
  <i data-feather="plus"></i>
227
  </button>
228
  </div>
229
+ <timeline-tasks id="timeline-sidebar"></timeline-tasks>
230
  <script src="components/task-item.js"></script>
231
  <script src="components/tag-item.js"></script>
232
+ <script src="components/timeline-tasks.js"></script>
233
  <script src="script.js"></script>
234
  <script>feather.replace();</script>
235
  <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
script.js CHANGED
@@ -177,16 +177,24 @@ function deleteTask(taskId) {
177
  saveToLocalStorage();
178
  render();
179
  }
180
-
181
  function toggleTaskComplete(taskId) {
182
  const task = state.tasks.find(t => t.id === taskId);
183
  if (task) {
184
  task.completed = !task.completed;
185
  saveToLocalStorage();
186
- render();
 
 
 
 
 
 
 
 
 
 
187
  }
188
  }
189
-
190
  // Modal Functions
191
  function openAddTaskModal() {
192
  const modal = document.getElementById('add-task-modal');
@@ -395,31 +403,32 @@ function renderProgressBars() {
395
  document.getElementById('total-progress-text').textContent =
396
  `${Math.round(totalProgress)}% (${formatTime(totalSpent)} / ${formatTime(totalEstimated)})`;
397
 
398
- // Tag progress bars
399
  const container = document.getElementById('tag-progress-container');
400
- container.innerHTML = state.tags.map(tag => {
401
- const tagTasks = state.tasks.filter(t => t.tags.includes(tag.id));
402
- const tagEstimated = tagTasks.reduce((sum, t) => sum + t.estimatedTime, 0) || 1;
403
- const tagSpent = tagTasks.reduce((sum, t) => sum + t.spentTime, 0);
404
- const tagProgress = (tagSpent / tagEstimated) * 100;
405
-
406
- return `
407
- <div class="bg-gray-800 rounded-lg p-4 shadow">
408
- <div class="flex items-center justify-between mb-2">
409
- <span class="font-medium" style="color: ${tag.color}">${tag.name}</span>
410
- <span class="text-sm text-gray-400">
411
- ${Math.round(tagProgress)}% (${formatTime(tagSpent)} / ${formatTime(tagEstimated)})
412
- </span>
413
- </div>
414
- <div class="w-full bg-gray-700 rounded-full h-2 overflow-hidden">
415
- <div class="h-full rounded-full"
416
- style="width: ${tagProgress}%; background-color: ${tag.color}"></div>
 
 
 
417
  </div>
418
- </div>
419
- `;
420
- }).join('');
421
  }
422
-
423
  function renderTags() {
424
  const container = document.getElementById('tags-list');
425
  container.innerHTML = state.tags.map(tag => `
 
177
  saveToLocalStorage();
178
  render();
179
  }
 
180
  function toggleTaskComplete(taskId) {
181
  const task = state.tasks.find(t => t.id === taskId);
182
  if (task) {
183
  task.completed = !task.completed;
184
  saveToLocalStorage();
185
+
186
+ // Animate task completion
187
+ const taskElement = document.querySelector(`task-item[task-id="${taskId}"]`);
188
+ if (taskElement) {
189
+ taskElement.classList.add('completed');
190
+ setTimeout(() => {
191
+ render();
192
+ }, 600); // Match animation duration
193
+ } else {
194
+ render();
195
+ }
196
  }
197
  }
 
198
  // Modal Functions
199
  function openAddTaskModal() {
200
  const modal = document.getElementById('add-task-modal');
 
403
  document.getElementById('total-progress-text').textContent =
404
  `${Math.round(totalProgress)}% (${formatTime(totalSpent)} / ${formatTime(totalEstimated)})`;
405
 
406
+ // Tag progress bars - only for tags with tasks
407
  const container = document.getElementById('tag-progress-container');
408
+ container.innerHTML = state.tags
409
+ .filter(tag => state.tasks.some(t => t.tags.includes(tag.id))) // Only tags with tasks
410
+ .map(tag => {
411
+ const tagTasks = state.tasks.filter(t => t.tags.includes(tag.id));
412
+ const tagEstimated = tagTasks.reduce((sum, t) => sum + t.estimatedTime, 0) || 1;
413
+ const tagSpent = tagTasks.reduce((sum, t) => sum + t.spentTime, 0);
414
+ const tagProgress = (tagSpent / tagEstimated) * 100;
415
+
416
+ return `
417
+ <div class="bg-gray-800 rounded-lg p-4 shadow transition-all hover:scale-[1.02]">
418
+ <div class="flex items-center justify-between mb-2">
419
+ <span class="font-medium" style="color: ${tag.color}">${tag.name}</span>
420
+ <span class="text-sm text-gray-400">
421
+ ${Math.round(tagProgress)}% (${formatTime(tagSpent)} / ${formatTime(tagEstimated)})
422
+ </span>
423
+ </div>
424
+ <div class="w-full bg-gray-700 rounded-full h-2 overflow-hidden">
425
+ <div class="h-full rounded-full transition-all duration-500"
426
+ style="width: ${tagProgress}%; background-color: ${tag.color}"></div>
427
+ </div>
428
  </div>
429
+ `;
430
+ }).join('');
 
431
  }
 
432
  function renderTags() {
433
  const container = document.getElementById('tags-list');
434
  container.innerHTML = state.tags.map(tag => `
style.css CHANGED
@@ -17,13 +17,38 @@
17
  ::-webkit-scrollbar-thumb:hover {
18
  @apply bg-gray-500;
19
  }
20
-
21
  /* Task hover effects */
22
  .task-item {
23
  @apply relative overflow-hidden;
24
  transition: all 0.3s ease;
 
 
 
 
 
 
 
 
 
 
 
25
  }
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  .task-item:hover {
28
  @apply transform scale-105 shadow-lg;
29
  }
 
17
  ::-webkit-scrollbar-thumb:hover {
18
  @apply bg-gray-500;
19
  }
 
20
  /* Task hover effects */
21
  .task-item {
22
  @apply relative overflow-hidden;
23
  transition: all 0.3s ease;
24
+ border-left: 4px solid transparent;
25
+ }
26
+
27
+ .task-item.completed {
28
+ animation: completeTask 0.6s ease forwards;
29
+ }
30
+
31
+ @keyframes completeTask {
32
+ 0% { transform: scale(1); opacity: 1; }
33
+ 50% { transform: scale(0.95); opacity: 0.8; }
34
+ 100% { transform: scale(1); opacity: 1; border-left-color: #10b981; }
35
  }
36
 
37
+ .task-item .focus-btn {
38
+ @apply absolute right-12 top-1/2 transform -translate-y-1/2;
39
+ @apply p-2 rounded-full bg-orange-500 bg-opacity-0 text-orange-500;
40
+ @apply transition-all duration-300 ease-in-out;
41
+ opacity: 0;
42
+ }
43
+
44
+ .task-item:hover .focus-btn {
45
+ @apply bg-opacity-20;
46
+ opacity: 1;
47
+ }
48
+
49
+ .task-item .focus-btn:hover {
50
+ @apply bg-opacity-100 text-white;
51
+ }
52
  .task-item:hover {
53
  @apply transform scale-105 shadow-lg;
54
  }