aufgabenmeister / script.js
Multimedix's picture
🐳 22/02 - 01:58 - IMPROVE
f515bfd verified
// Initial data structure with enhanced features
const todos = [
{
id: 1,
text: 'Beispielaufgabe erstellen',
completed: true,
priority: 'medium',
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
},
{
id: 2,
text: 'Todo-App mit neuen Features verbessern',
completed: false,
priority: 'high',
dueDate: new Date(Date.now() + 86400000).toISOString().split('T')[0], // Morgen
createdAt: new Date(Date.now() - 86400000).toISOString(),
updatedAt: new Date(Date.now() - 86400000).toISOString()
},
{
id: 3,
text: 'Dokumentation für das Team erstellen',
completed: false,
priority: 'low',
createdAt: new Date(Date.now() - 172800000).toISOString(), // Vorgestern
updatedAt: new Date(Date.now() - 172800000).toISOString()
}
];
function todoApp() {
return {
todos: [],
newTodo: '',
newPriority: 'medium',
newDueDate: '',
filter: 'all',
sortBy: 'priority',
searchQuery: '',
showToast: false,
toastMessage: '',
toastType: 'success',
editingId: null,
editingText: '',
editingPriority: 'medium',
editingDueDate: '',
dragStartIndex: null,
dragOverIndex: null,
// Initialize from localStorage or default
init() {
const savedTodos = localStorage.getItem('todos');
this.todos = savedTodos ? JSON.parse(savedTodos) : todos;
this.updateLocalStorage();
// Initialize Feather icons after content loads
setTimeout(() => {
if (typeof feather !== 'undefined') {
feather.replace();
}
}, 100);
},
// Filtered and sorted todos based on current settings
get filteredTodos() {
let filtered = this.todos;
// Apply search filter
if (this.searchQuery.trim() !== '') {
const query = this.searchQuery.toLowerCase();
filtered = filtered.filter(todo =>
todo.text.toLowerCase().includes(query)
);
}
// Apply status filter
if (this.filter === 'active') {
filtered = filtered.filter(todo => !todo.completed);
} else if (this.filter === 'completed') {
filtered = filtered.filter(todo => todo.completed);
}
// Apply sorting
filtered = [...filtered]; // Create a copy
if (this.sortBy === 'priority') {
const priorityOrder = { high: 0, medium: 1, low: 2, undefined: 3 };
filtered.sort((a, b) => {
const aPriority = priorityOrder[a.priority || 'undefined'];
const bPriority = priorityOrder[b.priority || 'undefined'];
return aPriority - bPriority;
});
} else {
filtered.sort((a, b) => {
const aDate = new Date(a.createdAt);
const bDate = new Date(b.createdAt);
return bDate - aDate; // Newest first
});
}
return filtered;
},
// Enhanced statistics
get completedCount() {
return this.todos.filter(todo => todo.completed).length;
},
get activeCount() {
return this.todos.filter(todo => !todo.completed).length;
},
get totalCount() {
return this.todos.length;
},
get overdueCount() {
const today = new Date().toISOString().split('T')[0];
return this.todos.filter(todo =>
!todo.completed &&
todo.dueDate &&
todo.dueDate < today
).length;
},
// Check if a todo is overdue
isOverdue(dueDate) {
if (!dueDate) return false;
const today = new Date().toISOString().split('T')[0];
return dueDate < today;
},
// Add new todo with enhanced features
addTodo() {
if (this.newTodo.trim() === '') {
this.showNotification('Bitte gib eine Aufgabe ein', 'error');
return;
}
const newTodo = {
id: Date.now(),
text: this.newTodo.trim(),
completed: false,
priority: this.newPriority,
dueDate: this.newDueDate || null,
overdue: this.isOverdue(this.newDueDate),
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
};
this.todos.unshift(newTodo);
this.newTodo = '';
this.newDueDate = '';
this.newPriority = 'medium';
this.updateLocalStorage();
this.showNotification('Aufgabe hinzugefügt', 'success');
},
// Toggle todo completion
toggleTodo(id) {
const todo = this.todos.find(t => t.id === id);
if (todo) {
todo.completed = !todo.completed;
todo.updatedAt = new Date().toISOString();
this.updateLocalStorage();
const message = todo.completed ? 'Aufgabe erledigt!' : 'Aufgabe wieder geöffnet';
this.showNotification(message, 'success');
}
},
// Delete todo
deleteTodo(id) {
this.todos = this.todos.filter(t => t.id !== id);
this.updateLocalStorage();
this.showNotification('Aufgabe gelöscht', 'success');
},
// Clear completed todos
clearCompleted() {
const completedCount = this.completedCount;
this.todos = this.todos.filter(t => !t.completed);
this.updateLocalStorage();
this.showNotification(`${completedCount} erledigte Aufgabe(n) gelöscht`, 'success');
},
// Edit todo with enhanced features
startEdit(id, text, priority = 'medium', dueDate = '') {
this.editingId = id;
this.editingText = text;
this.editingPriority = priority || 'medium';
this.editingDueDate = dueDate || '';
},
saveEdit() {
if (this.editingText.trim() === '') {
this.showNotification('Aufgabe darf nicht leer sein', 'error');
return;
}
const todo = this.todos.find(t => t.id === this.editingId);
if (todo) {
todo.text = this.editingText.trim();
todo.priority = this.editingPriority;
todo.dueDate = this.editingDueDate || null;
todo.overdue = this.isOverdue(this.editingDueDate);
todo.updatedAt = new Date().toISOString();
this.updateLocalStorage();
this.cancelEdit();
this.showNotification('Aufgabe aktualisiert', 'success');
}
},
cancelEdit() {
this.editingId = null;
this.editingText = '';
this.editingPriority = 'medium';
this.editingDueDate = '';
},
// Drag and drop functionality
dragStart(index) {
this.dragStartIndex = index;
this.dragOverIndex = null;
},
dragOver(event) {
event.preventDefault();
},
setDragOver(index) {
if (index !== this.dragStartIndex) {
this.dragOverIndex = index;
}
},
clearDragOver() {
this.dragOverIndex = null;
},
dropOn(targetIndex) {
if (this.dragStartIndex === null || this.dragStartIndex === targetIndex) {
this.clearDragOver();
return;
}
const draggedTodo = this.todos[this.dragStartIndex];
this.todos.splice(this.dragStartIndex, 1);
this.todos.splice(targetIndex, 0, draggedTodo);
this.dragStartIndex = null;
this.dragOverIndex = null;
this.updateLocalStorage();
this.showNotification('Aufgabe verschoben', 'success');
},
drop() {
this.dragStartIndex = null;
this.dragOverIndex = null;
},
// Format date for display
formatDate(dateString) {
const date = new Date(dateString);
return date.toLocaleDateString('de-DE', {
day: '2-digit',
month: '2-digit',
year: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
},
// Format due date
formatDueDate(dateString) {
if (!dateString) return '';
const date = new Date(dateString);
const today = new Date();
const tomorrow = new Date(today);
tomorrow.setDate(tomorrow.getDate() + 1);
if (date.toDateString() === today.toDateString()) {
return 'Heute';
} else if (date.toDateString() === tomorrow.toDateString()) {
return 'Morgen';
} else {
return date.toLocaleDateString('de-DE', {
day: '2-digit',
month: '2-digit',
year: 'numeric'
});
}
},
// Show notification toast
showNotification(message, type = 'success') {
this.toastMessage = message;
this.toastType = type;
this.showToast = true;
setTimeout(() => {
this.showToast = false;
}, 3000);
},
// Update localStorage
updateLocalStorage() {
localStorage.setItem('todos', JSON.stringify(this.todos));
},
// Update Feather icons when needed
updateIcons() {
if (typeof feather !== 'undefined') {
feather.replace();
}
}
};
}