Fadikkop commited on
Commit
ed0e7ff
·
verified ·
1 Parent(s): df67172

Promote version 4e9dea2 to main

Browse files

Promoted commit 4e9dea2414107edb6f5eff48279f88ea9f8aaf7e to main branch

Files changed (3) hide show
  1. components/task-item.js +25 -20
  2. index.html +10 -11
  3. script.js +16 -30
components/task-item.js CHANGED
@@ -218,12 +218,12 @@ class TaskItem extends HTMLElement {
218
  </style>
219
  <div class="task-header">
220
  <input type="checkbox" class="task-checkbox" ${this.completed ? 'checked' : ''}>
221
- <span class="task-title">${title}</span>
222
  <div class="task-actions">
223
  <button class="focus-btn" title="Pomodoro starten">
224
  <i data-feather="clock"></i>
225
  </button>
226
- <button class="task-action" title="Bearbeiten">
227
  <i data-feather="edit-2"></i>
228
  </button>
229
  <button class="task-action" title="Löschen">
@@ -231,7 +231,8 @@ class TaskItem extends HTMLElement {
231
  </button>
232
  </div>
233
  </div>
234
- <div class="task-info">
 
235
  <span class="time-info">${formatTime(spentTime)} / ${formatTime(estimatedTime)}</span>
236
  <div class="tags">${tagElements}</div>
237
  </div>
@@ -269,26 +270,30 @@ class TaskItem extends HTMLElement {
269
  icon.outerHTML = feather.icons[iconName].toSvg({ width: 16, height: 16 });
270
  });
271
  }
 
272
  setupEventListeners() {
273
- const focusBtn = this.shadowRoot.querySelector('.focus-btn');
274
- const editBtn = this.shadowRoot.querySelector('.task-action[title="Bearbeiten"]');
275
- const deleteBtn = this.shadowRoot.querySelector('.task-action[title="Löschen"]');
276
- const checkbox = this.shadowRoot.querySelector('.task-checkbox');
 
 
 
 
 
 
 
 
 
277
 
278
- if (focusBtn) {
279
- focusBtn.addEventListener('click', (e) => this.handleFocus(e));
280
- }
281
- if (editBtn) {
282
- editBtn.addEventListener('click', (e) => this.handleEdit(e));
283
- }
284
- if (deleteBtn) {
285
- deleteBtn.addEventListener('click', (e) => this.handleDelete(e));
286
- }
287
- if (checkbox) {
288
- checkbox.addEventListener('change', (e) => this.handleToggleComplete(e));
289
- }
290
  }
291
- handleToggleComplete(e) {
 
292
  const completed = e.target.checked;
293
  this.dispatchEvent(new CustomEvent('toggle-complete', {
294
  detail: { taskId: this.getAttribute('task-id'), completed },
 
218
  </style>
219
  <div class="task-header">
220
  <input type="checkbox" class="task-checkbox" ${this.completed ? 'checked' : ''}>
221
+ <span class="task-title">${title}</span>
222
  <div class="task-actions">
223
  <button class="focus-btn" title="Pomodoro starten">
224
  <i data-feather="clock"></i>
225
  </button>
226
+ <button class="task-action" title="Bearbeiten">
227
  <i data-feather="edit-2"></i>
228
  </button>
229
  <button class="task-action" title="Löschen">
 
231
  </button>
232
  </div>
233
  </div>
234
+
235
+ <div class="task-info">
236
  <span class="time-info">${formatTime(spentTime)} / ${formatTime(estimatedTime)}</span>
237
  <div class="tags">${tagElements}</div>
238
  </div>
 
270
  icon.outerHTML = feather.icons[iconName].toSvg({ width: 16, height: 16 });
271
  });
272
  }
273
+
274
  setupEventListeners() {
275
+ this.shadowRoot.addEventListener('click', (e) => {
276
+ const target = e.target.closest('button');
277
+ if (target) {
278
+ const action = target.getAttribute('title');
279
+ if (action === 'Bearbeiten') {
280
+ this.handleEdit(e);
281
+ } else if (action === 'Löschen') {
282
+ this.handleDelete(e);
283
+ } else if (action === 'Pomodoro starten') {
284
+ this.handleFocus(e);
285
+ }
286
+ }
287
+ });
288
 
289
+ this.shadowRoot.addEventListener('change', (e) => {
290
+ if (e.target.classList.contains('task-checkbox')) {
291
+ this.handleToggleComplete(e);
292
+ }
293
+ });
 
 
 
 
 
 
 
294
  }
295
+
296
+ handleToggleComplete(e) {
297
  const completed = e.target.checked;
298
  this.dispatchEvent(new CustomEvent('toggle-complete', {
299
  detail: { taskId: this.getAttribute('task-id'), completed },
index.html CHANGED
@@ -6,6 +6,7 @@
6
  <title>TaskForge Pro</title>
7
  <link rel="stylesheet" href="style.css">
8
  <script src="https://cdn.tailwindcss.com"></script>
 
9
  <script src="https://unpkg.com/feather-icons"></script>
10
  </head>
11
  <body class="bg-gray-900 text-gray-100 min-h-screen">
@@ -15,14 +16,14 @@
15
  <div class="flex items-center justify-between">
16
  <h1 class="text-2xl font-bold text-orange-500">TaskForge Pro</h1>
17
  <nav class="flex items-center space-x-4">
18
- <a href="#" id="view-home" class="nav-btn active" data-view="home">
19
  <i data-feather="home"></i> Übersicht
20
- </a>
21
- <a href="#" id="view-settings" class="nav-btn" data-view="settings">
22
  <i data-feather="settings"></i> Einstellungen
23
- </a>
24
  </nav>
25
- </div>
26
  </div>
27
  </header>
28
  <!-- Main Content -->
@@ -192,20 +193,18 @@
192
  <!-- FAB Buttons -->
193
  <div class="fixed bottom-6 right-6 flex flex-col space-y-3">
194
  <button id="focus-fab" class="p-4 bg-orange-500 hover:bg-orange-600 rounded-full shadow-lg transition transform hover:scale-110">
195
- <i data-feather="clock"></i>
196
  </button>
197
  <button id="add-task-fab" class="p-4 bg-emerald-500 hover:bg-emerald-600 rounded-full shadow-lg transition transform hover:scale-110">
198
  <i data-feather="plus"></i>
199
  </button>
200
  </div>
 
201
  <script src="components/task-item.js"></script>
202
  <script src="components/tag-item.js"></script>
 
203
  <script src="script.js"></script>
204
- <script>
205
- document.addEventListener('DOMContentLoaded', function() {
206
- feather.replace();
207
- });
208
- </script>
209
  <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
210
  </body>
211
  </html>
 
6
  <title>TaskForge Pro</title>
7
  <link rel="stylesheet" href="style.css">
8
  <script src="https://cdn.tailwindcss.com"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
10
  <script src="https://unpkg.com/feather-icons"></script>
11
  </head>
12
  <body class="bg-gray-900 text-gray-100 min-h-screen">
 
16
  <div class="flex items-center justify-between">
17
  <h1 class="text-2xl font-bold text-orange-500">TaskForge Pro</h1>
18
  <nav class="flex items-center space-x-4">
19
+ <button id="view-home" class="nav-btn active" data-view="home">
20
  <i data-feather="home"></i> Übersicht
21
+ </button>
22
+ <button id="view-settings" class="nav-btn" data-view="settings">
23
  <i data-feather="settings"></i> Einstellungen
24
+ </button>
25
  </nav>
26
+ </div>
27
  </div>
28
  </header>
29
  <!-- Main Content -->
 
193
  <!-- FAB Buttons -->
194
  <div class="fixed bottom-6 right-6 flex flex-col space-y-3">
195
  <button id="focus-fab" class="p-4 bg-orange-500 hover:bg-orange-600 rounded-full shadow-lg transition transform hover:scale-110">
196
+ <i data-feather="focus"></i>
197
  </button>
198
  <button id="add-task-fab" class="p-4 bg-emerald-500 hover:bg-emerald-600 rounded-full shadow-lg transition transform hover:scale-110">
199
  <i data-feather="plus"></i>
200
  </button>
201
  </div>
202
+ <timeline-sidebar id="timeline-sidebar"></timeline-sidebar>
203
  <script src="components/task-item.js"></script>
204
  <script src="components/tag-item.js"></script>
205
+ <script src="components/timeline-tasks.js"></script>
206
  <script src="script.js"></script>
207
+ <script>feather.replace();</script>
 
 
 
 
208
  <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
209
  </body>
210
  </html>
script.js CHANGED
@@ -21,7 +21,6 @@ document.addEventListener('DOMContentLoaded', () => {
21
  initializeUI();
22
  setupEventListeners();
23
  render();
24
- feather.replace();
25
  });
26
  // Local Storage
27
  function loadFromLocalStorage() {
@@ -83,20 +82,22 @@ function updateCurrentTime() {
83
  document.getElementById('current-time').textContent = timeString;
84
  }
85
  function setupEventListeners() {
86
- // Navigation
87
  document.querySelectorAll('.nav-btn').forEach(btn => {
88
  btn.addEventListener('click', (e) => {
89
- e.preventDefault();
90
  const view = e.currentTarget.dataset.view;
91
  switchView(view);
92
  });
93
  });
94
- // FAB buttons
 
95
  document.getElementById('add-task-fab').addEventListener('click', openAddTaskModal);
96
  document.getElementById('focus-fab').addEventListener('click', enterFocusMode);
 
97
  // Add task modal
98
  document.getElementById('add-task-form').addEventListener('submit', handleAddTask);
99
  document.getElementById('cancel-task').addEventListener('click', closeAddTaskModal);
 
100
  // Settings
101
  document.getElementById('import-btn').addEventListener('click', handleImport);
102
  document.getElementById('export-btn').addEventListener('click', handleExport);
@@ -104,11 +105,13 @@ function setupEventListeners() {
104
 
105
  document.getElementById('pomodoro-work').addEventListener('change', savePomodoroSettings);
106
  document.getElementById('pomodoro-break').addEventListener('change', savePomodoroSettings);
 
107
  // Focus mode
108
  document.getElementById('focus-pause').addEventListener('click', pausePomodoro);
109
  document.getElementById('focus-play').addEventListener('click', resumePomodoro);
110
  document.getElementById('focus-stop').addEventListener('click', stopPomodoro);
111
- // Event delegation for task item events
 
112
  document.addEventListener('delete-task', (e) => {
113
  deleteTask(e.detail.taskId);
114
  });
@@ -124,7 +127,8 @@ function setupEventListeners() {
124
  document.addEventListener('add-time', (e) => {
125
  addTimeToTask(e.detail.taskId, e.detail.minutes);
126
  });
127
- // Timeline sidebar events
 
128
  const timelineSidebar = document.getElementById('timeline-sidebar');
129
  if (timelineSidebar) {
130
  timelineSidebar.addEventListener('task-dropped', (e) => {
@@ -208,6 +212,7 @@ function closeAddTaskModal() {
208
  modal.classList.add('hidden');
209
  document.getElementById('add-task-form').reset();
210
  }
 
211
  function handleAddTask(e) {
212
  e.preventDefault();
213
 
@@ -226,6 +231,7 @@ function handleAddTask(e) {
226
 
227
  closeAddTaskModal();
228
  }
 
229
  function renderModalTags() {
230
  const container = document.getElementById('modal-tags-list');
231
  container.innerHTML = state.tags.map(tag => `
@@ -394,9 +400,6 @@ function renderTasks() {
394
 
395
  // Replace feather icons
396
  feather.replace();
397
-
398
- // Re-attach event listeners to task items after render
399
- reattachTaskEventListeners();
400
  }
401
  function renderProgressBars() {
402
  // Overall progress
@@ -649,8 +652,8 @@ function savePomodoroSettings() {
649
  function initializeTimeline() {
650
  // Setup drag start for task items
651
  document.addEventListener('dragstart', (e) => {
652
- if (e.target.tagName === 'TASK-ITEM') {
653
- const taskId = e.target.getAttribute('task-id');
654
  e.dataTransfer.setData('text/plain', taskId);
655
  }
656
  });
@@ -711,10 +714,12 @@ function formatTime(minutes) {
711
  const m = minutes % 60;
712
  return `${h}h${m > 0 ? ` ${m}m` : ''}`;
713
  }
 
714
  // Request notification permission
715
  if ('Notification' in window && Notification.permission === 'default') {
716
  Notification.requestPermission();
717
  }
 
718
  // New functions for task management
719
  function addTimeToTask(taskId, minutes) {
720
  const task = state.tasks.find(t => t.id === taskId);
@@ -725,9 +730,6 @@ function addTimeToTask(taskId, minutes) {
725
  }
726
  }
727
 
728
- // Fix missing global functions
729
- window.startFocusModeWithId = startFocusModeWithId;
730
- window.formatTime = formatTime;
731
  function setupTaskDragAndDrop() {
732
  const openContainer = document.getElementById('open-tasks');
733
  const completedContainer = document.getElementById('completed-tasks');
@@ -750,22 +752,6 @@ function setupTaskDragAndDrop() {
750
  });
751
  }
752
 
753
- function reattachTaskEventListeners() {
754
- document.querySelectorAll('task-item').forEach(taskEl => {
755
- // Remove existing listeners and re-add
756
- const taskId = taskEl.getAttribute('task-id');
757
-
758
- // Add event listeners for checkbox toggle
759
- const checkbox = taskEl.shadowRoot?.querySelector('.task-checkbox');
760
- if (checkbox) {
761
- checkbox.addEventListener('change', (e) => {
762
- const completed = e.target.checked;
763
- toggleTaskComplete(taskId, completed);
764
- });
765
-
766
- }
767
- });
768
- }
769
  function getDragAfterElement(container, y) {
770
  const draggableElements = [...container.querySelectorAll('task-item:not(.dragging)'));
771
 
 
21
  initializeUI();
22
  setupEventListeners();
23
  render();
 
24
  });
25
  // Local Storage
26
  function loadFromLocalStorage() {
 
82
  document.getElementById('current-time').textContent = timeString;
83
  }
84
  function setupEventListeners() {
85
+ // Navigation
86
  document.querySelectorAll('.nav-btn').forEach(btn => {
87
  btn.addEventListener('click', (e) => {
 
88
  const view = e.currentTarget.dataset.view;
89
  switchView(view);
90
  });
91
  });
92
+
93
+ // FAB buttons
94
  document.getElementById('add-task-fab').addEventListener('click', openAddTaskModal);
95
  document.getElementById('focus-fab').addEventListener('click', enterFocusMode);
96
+
97
  // Add task modal
98
  document.getElementById('add-task-form').addEventListener('submit', handleAddTask);
99
  document.getElementById('cancel-task').addEventListener('click', closeAddTaskModal);
100
+
101
  // Settings
102
  document.getElementById('import-btn').addEventListener('click', handleImport);
103
  document.getElementById('export-btn').addEventListener('click', handleExport);
 
105
 
106
  document.getElementById('pomodoro-work').addEventListener('change', savePomodoroSettings);
107
  document.getElementById('pomodoro-break').addEventListener('change', savePomodoroSettings);
108
+
109
  // Focus mode
110
  document.getElementById('focus-pause').addEventListener('click', pausePomodoro);
111
  document.getElementById('focus-play').addEventListener('click', resumePomodoro);
112
  document.getElementById('focus-stop').addEventListener('click', stopPomodoro);
113
+
114
+ // Event delegation for task item events
115
  document.addEventListener('delete-task', (e) => {
116
  deleteTask(e.detail.taskId);
117
  });
 
127
  document.addEventListener('add-time', (e) => {
128
  addTimeToTask(e.detail.taskId, e.detail.minutes);
129
  });
130
+
131
+ // Timeline sidebar events
132
  const timelineSidebar = document.getElementById('timeline-sidebar');
133
  if (timelineSidebar) {
134
  timelineSidebar.addEventListener('task-dropped', (e) => {
 
212
  modal.classList.add('hidden');
213
  document.getElementById('add-task-form').reset();
214
  }
215
+
216
  function handleAddTask(e) {
217
  e.preventDefault();
218
 
 
231
 
232
  closeAddTaskModal();
233
  }
234
+
235
  function renderModalTags() {
236
  const container = document.getElementById('modal-tags-list');
237
  container.innerHTML = state.tags.map(tag => `
 
400
 
401
  // Replace feather icons
402
  feather.replace();
 
 
 
403
  }
404
  function renderProgressBars() {
405
  // Overall progress
 
652
  function initializeTimeline() {
653
  // Setup drag start for task items
654
  document.addEventListener('dragstart', (e) => {
655
+ if (e.target.tagName === 'TASK-ITEM') {
656
+ const taskId = e.target.getAttribute('task-id');
657
  e.dataTransfer.setData('text/plain', taskId);
658
  }
659
  });
 
714
  const m = minutes % 60;
715
  return `${h}h${m > 0 ? ` ${m}m` : ''}`;
716
  }
717
+
718
  // Request notification permission
719
  if ('Notification' in window && Notification.permission === 'default') {
720
  Notification.requestPermission();
721
  }
722
+
723
  // New functions for task management
724
  function addTimeToTask(taskId, minutes) {
725
  const task = state.tasks.find(t => t.id === taskId);
 
730
  }
731
  }
732
 
 
 
 
733
  function setupTaskDragAndDrop() {
734
  const openContainer = document.getElementById('open-tasks');
735
  const completedContainer = document.getElementById('completed-tasks');
 
752
  });
753
  }
754
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
755
  function getDragAfterElement(container, y) {
756
  const draggableElements = [...container.querySelectorAll('task-item:not(.dragging)'));
757