WEBLEB
Startseite
Editor
Anmelden
Pro
Deutsch
English
Français
Español
Português
Deutsch
Italiano
हिंदी
HTML
CSS
JS
TaskMaster Pro - Dynamic Smart Task Management by TheDoc
TaskMaster Pro - TheDoc's DS Edition
0
Tasks |
0
Done Successfully
Difficulty Status:
Low
Default Standard
Superior
Display All
Started
Done Successfully
No tasks available
Deliver your first task & Start now!
Edit Dynamic Task
Difficulty Status:
Low
Default Standard
Superior
Delete Selected task?
Are you Sure you want to delete this task?
This action cannot be undone Successfully.
/* Reset und Basis Styles */ * { margin: 0; padding: 0; box-sizing: border-box; } :root { /* Light Theme */ --bg-primary: #f8fafc; --bg-secondary: #ffffff; --bg-tertiary: #f1f5f9; --text-primary: #1e293b; --text-secondary: #64748b; --accent-primary: #3b82f6; --accent-secondary: #06b6d4; --success: #10b981; --warning: #f59e0b; --error: #ef4444; --border: #e2e8f0; --shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); } [data-theme="dark"], .dark-theme { --bg-primary: #0f172a; --bg-secondary: #1e293b; --bg-tertiary: #334155; --text-primary: #f8fafc; --text-secondary: #cbd5e1; --accent-primary: #60a5fa; --accent-secondary: #22d3ee; --border: #475569; --shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.3), 0 1px 2px 0 rgba(0, 0, 0, 0.2); --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.3), 0 4px 6px -2px rgba(0, 0, 0, 0.2); } body { font-family: 'Inter', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, var(--bg-primary) 0%, var(--bg-tertiary) 100%); color: var(--text-primary); line-height: 1.6; min-height: 100vh; transition: all 0.3s ease; } .container { max-width: 1200px; margin: 0 auto; padding: 20px; min-height: 100vh; } /* Header */ .header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 2rem; padding: 1.5rem 2rem; background: var(--bg-secondary); border-radius: 16px; box-shadow: var(--shadow); border: 1px solid var(--border); } .header h1 { font-size: 2rem; font-weight: 700; color: var(--accent-primary); display: flex; align-items: center; gap: 0.5rem; } .header-controls { display: flex; align-items: center; gap: 1rem; } .theme-toggle { background: var(--bg-tertiary); border: 1px solid var(--border); border-radius: 50%; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: all 0.3s ease; color: var(--text-primary); } .theme-toggle:hover { background: var(--accent-primary); color: white; transform: scale(1.1); } .stats { color: var(--text-secondary); font-weight: 500; } /* Add Task Section */ .add-task-section { margin-bottom: 2rem; } .input-group { display: flex; flex-wrap: wrap; gap: 1rem; background: var(--bg-secondary); padding: 1.5rem; border-radius: 12px; box-shadow: var(--shadow); border: 1px solid var(--border); align-items: flex-end; } #taskInput { flex: 1; min-width: 250px; border: none; background: var(--bg-tertiary); color: var(--text-primary); padding: 0.75rem 1rem; border-radius: 8px; font-size: 1rem; outline: none; transition: all 0.3s ease; } #taskInput:focus { background: var(--bg-primary); box-shadow: 0 0 0 2px var(--accent-primary); } #addTaskBtn { background: var(--accent-primary); color: white; border: none; padding: 0.75rem 1rem; border-radius: 8px; cursor: pointer; transition: all 0.3s ease; display: flex; align-items: center; justify-content: center; } #addTaskBtn:hover { background: var(--accent-secondary); transform: translateY(-2px); } /* Filter Section */ .filter-section { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem; background: var(--bg-secondary); padding: 1rem; border-radius: 12px; box-shadow: var(--shadow); border: 1px solid var(--border); } .filter-buttons { display: flex; gap: 0.5rem; } .filter-btn { background: var(--bg-tertiary); color: var(--text-secondary); border: 1px solid var(--border); padding: 0.5rem 1rem; border-radius: 8px; cursor: pointer; transition: all 0.3s ease; display: flex; align-items: center; gap: 0.5rem; } .filter-btn:hover { background: var(--accent-primary); color: white; } .filter-btn.active { background: var(--accent-primary); color: white; border-color: var(--accent-primary); } .search-box { position: relative; display: flex; align-items: center; } .search-box i { position: absolute; left: 0.75rem; color: var(--text-secondary); } #searchInput { background: var(--bg-tertiary); border: 1px solid var(--border); color: var(--text-primary); padding: 0.5rem 0.5rem 0.5rem 2.5rem; border-radius: 8px; outline: none; width: 200px; transition: all 0.3s ease; } #searchInput:focus { border-color: var(--accent-primary); box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1); } /* Tasks Container */ .tasks-container { background: var(--bg-secondary); border-radius: 12px; box-shadow: var(--shadow); border: 1px solid var(--border); min-height: 400px; overflow: hidden; } .tasks-list { padding: 1rem; } .task-item { display: flex; align-items: center; gap: 1rem; padding: 1rem; margin-bottom: 0.5rem; background: var(--bg-tertiary); border-radius: 8px; border: 1px solid var(--border); cursor: grab; transition: all 0.3s ease; } .task-item:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); } .task-item.dragging { opacity: 0.5; cursor: grabbing; } .task-item.completed { opacity: 0.6; } .task-item.completed .task-text { text-decoration: line-through; } .task-checkbox { width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--border); cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.3s ease; } .task-checkbox.checked { background: var(--success); border-color: var(--success); color: white; } .task-content { flex: 1; display: flex; flex-direction: column; gap: 0.25rem; } .task-text { font-weight: 500; word-break: break-word; } .task-meta { display: flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; color: var(--text-secondary); } .priority-badge { padding: 0.25rem 0.5rem; border-radius: 4px; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; } .priority-high { background: rgba(239, 68, 68, 0.1); color: var(--error); } .priority-medium { background: rgba(245, 158, 11, 0.1); color: var(--warning); } .priority-low { background: rgba(16, 185, 129, 0.1); color: var(--success); } .task-actions { display: flex; gap: 0.5rem; } .action-btn { background: none; border: none; color: var(--text-secondary); cursor: pointer; padding: 0.5rem; border-radius: 4px; transition: all 0.3s ease; } .action-btn:hover { color: var(--accent-primary); background: var(--bg-primary); } .action-btn.delete:hover { color: var(--error); } /* Empty State */ .empty-state { text-align: center; padding: 3rem 2rem; color: var(--text-secondary); } .empty-state i { font-size: 4rem; margin-bottom: 1rem; opacity: 0.5; } .empty-state h3 { margin-bottom: 0.5rem; color: var(--text-primary); } /* Modal */ .modal { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); backdrop-filter: blur(4px); z-index: 1000; animation: fadeIn 0.3s ease; } .modal.show { display: flex; align-items: center; justify-content: center; } .modal-content { background: var(--bg-secondary); border-radius: 12px; box-shadow: var(--shadow-lg); border: 1px solid var(--border); width: 90%; max-width: 500px; animation: slideIn 0.3s ease; } .modal-header { display: flex; justify-content: space-between; align-items: center; padding: 1.5rem; border-bottom: 1px solid var(--border); } .modal-header h3 { display: flex; align-items: center; gap: 0.5rem; color: var(--accent-primary); } .close-btn { background: none; border: none; color: var(--text-secondary); cursor: pointer; padding: 0.5rem; border-radius: 4px; transition: all 0.3s ease; } .close-btn:hover { color: var(--error); background: var(--bg-tertiary); } .modal-body { padding: 1.5rem; display: flex; flex-direction: column; gap: 1rem; } .modal-body input, .modal-body select { background: var(--bg-tertiary); border: 1px solid var(--border); color: var(--text-primary); padding: 0.75rem; border-radius: 8px; outline: none; transition: all 0.3s ease; } .modal-body input:focus, .modal-body select:focus { border-color: var(--accent-primary); box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1); } .modal-footer { display: flex; justify-content: flex-end; gap: 0.5rem; padding: 1.5rem; border-top: 1px solid var(--border); } .btn-primary, .btn-secondary { padding: 0.75rem 1.5rem; border: none; border-radius: 8px; cursor: pointer; font-weight: 500; transition: all 0.3s ease; } .btn-primary { background: var(--accent-primary); color: white; } .btn-primary:hover { background: var(--accent-secondary); } .btn-secondary { background: var(--bg-tertiary); color: var(--text-primary); border: 1px solid var(--border); } .btn-secondary:hover { background: var(--bg-primary); } /* Priority Selector Styles */ .priority-selector { display: flex; flex-direction: column; gap: 0.5rem; min-width: 200px; } .priority-label { font-size: 0.875rem; font-weight: 600; color: var(--text-secondary); margin-bottom: 0.25rem; } .priority-options { display: flex; gap: 0.5rem; background: var(--bg-tertiary); padding: 0.5rem; border-radius: 8px; border: 1px solid var(--border); } .priority-option { display: flex; flex-direction: column; align-items: center; gap: 0.25rem; padding: 0.75rem 0.5rem; border-radius: 6px; cursor: pointer; transition: all 0.3s ease; background: transparent; border: 2px solid transparent; min-width: 60px; position: relative; } .priority-option:hover { background: var(--bg-secondary); transform: translateY(-2px); box-shadow: var(--shadow); } .priority-option.active { background: var(--bg-secondary); box-shadow: var(--shadow); } .priority-option[data-priority="low"] { color: var(--success); } .priority-option[data-priority="low"].active { border-color: var(--success); background: rgba(16, 185, 129, 0.1); } .priority-option[data-priority="medium"] { color: var(--warning); } .priority-option[data-priority="medium"].active { border-color: var(--warning); background: rgba(245, 158, 11, 0.1); } .priority-option[data-priority="high"] { color: var(--error); } .priority-option[data-priority="high"].active { border-color: var(--error); background: rgba(239, 68, 68, 0.1); } .priority-option i { font-size: 1.25rem; margin-bottom: 0.125rem; } .priority-option span { font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; } /* Priority Animation */ .priority-option::before { content: ''; position: absolute; top: 50%; left: 50%; width: 0; height: 0; background: currentColor; border-radius: 50%; opacity: 0.3; transform: translate(-50%, -50%); transition: all 0.3s ease; } .priority-option:active::before { width: 100%; height: 100%; } /* Animations */ @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes slideIn { from { opacity: 0; transform: translateY(-50px) scale(0.9); } to { opacity: 1; transform: translateY(0) scale(1); } } @keyframes slideInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .task-item { animation: slideInUp 0.3s ease; } /* Delete Modal Styles */ .delete-modal .modal-content { max-width: 450px; border: 2px solid var(--error); } .delete-header { background: linear-gradient(135deg, rgba(239, 68, 68, 0.1), rgba(239, 68, 68, 0.05)); border-bottom: 1px solid rgba(239, 68, 68, 0.2); flex-direction: column; align-items: center; text-align: center; padding: 2rem 1.5rem 1rem; position: relative; } .delete-icon { width: 60px; height: 60px; background: var(--error); border-radius: 50%; display: flex; align-items: center; justify-content: center; margin-bottom: 1rem; color: white; font-size: 1.5rem; animation: pulse 2s infinite; } @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.1); } 100% { transform: scale(1); } } .delete-header h3 { color: var(--error); font-size: 1.25rem; margin: 0; } .delete-header .close-btn { position: absolute; top: 1rem; right: 1rem; } .delete-body { padding: 1.5rem; text-align: center; } .delete-body p { color: var(--text-primary); font-size: 1rem; margin-bottom: 1.5rem; line-height: 1.6; } .task-preview { background: var(--bg-tertiary); border: 1px solid var(--border); border-radius: 8px; padding: 1rem; margin: 1rem 0; text-align: left; } .task-preview .preview-text { font-weight: 500; color: var(--text-primary); margin-bottom: 0.5rem; word-break: break-word; } .task-preview .preview-meta { display: flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; color: var(--text-secondary); } .warning-note { display: flex; align-items: center; justify-content: center; gap: 0.5rem; background: rgba(245, 158, 11, 0.1); color: var(--warning); padding: 0.75rem; border-radius: 6px; font-size: 0.875rem; border: 1px solid rgba(245, 158, 11, 0.2); } .delete-footer { padding: 1.5rem; gap: 1rem; } .btn-danger { background: var(--error); color: white; border: none; padding: 0.75rem 1.5rem; border-radius: 8px; cursor: pointer; font-weight: 500; transition: all 0.3s ease; display: flex; align-items: center; gap: 0.5rem; } .btn-danger:hover { background: #dc2626; transform: translateY(-1px); box-shadow: 0 4px 12px rgba(239, 68, 68, 0.3); } .btn-danger:active { transform: translateY(0); } .delete-footer .btn-secondary { display: flex; align-items: center; gap: 0.5rem; } /* Animation für das Delete Modal */ .delete-modal.show .modal-content { animation: shakeIn 0.5s ease; } @keyframes shakeIn { 0% { opacity: 0; transform: scale(0.8) rotate(-2deg); } 50% { transform: scale(1.05) rotate(1deg); } 100% { opacity: 1; transform: scale(1) rotate(0deg); } } /* Responsive Design */ @media (max-width: 768px) { .container { padding: 10px; } .header { flex-direction: column; gap: 1rem; text-align: center; } .filter-section { flex-direction: column; gap: 1rem; } .filter-buttons { justify-content: center; flex-wrap: wrap; } .input-group { flex-direction: column; gap: 1rem; align-items: stretch; } #taskInput { min-width: auto; width: 100%; } .priority-selector { order: 2; } #addTaskBtn { order: 3; align-self: center; min-width: 120px; } .task-item { flex-direction: column; align-items: flex-start; gap: 0.5rem; } .task-actions { align-self: flex-end; } .priority-selector { min-width: auto; width: 100%; } .priority-options { justify-content: space-between; } .priority-option { flex: 1; min-width: auto; } .delete-modal .modal-content { margin: 20px; max-width: calc(100vw - 40px); } .delete-header { padding: 1.5rem 1rem 0.5rem; } .delete-icon { width: 50px; height: 50px; font-size: 1.25rem; } .delete-footer { flex-direction: column; gap: 0.5rem; } .delete-footer button { width: 100%; justify-content: center; } }
// TaskMaster Pro - JavaScript Functionality class TaskManager { constructor() { this.tasks = this.loadTasks(); this.currentFilter = 'all'; this.currentEditId = null; this.currentDeleteId = null; this.draggedItem = null; this.initializeElements(); this.bindEvents(); this.renderTasks(); this.updateStats(); } initializeElements() { // Input elements this.taskInput = document.getElementById('taskInput'); this.addTaskBtn = document.getElementById('addTaskBtn'); this.searchInput = document.getElementById('searchInput'); // Priority selectors this.priorityOptions = document.querySelectorAll('.priority-option'); this.editPriorityOptions = document.getElementById('editPriorityOptions'); // Display elements this.tasksList = document.getElementById('tasksList'); this.emptyState = document.getElementById('emptyState'); this.totalTasksSpan = document.getElementById('totalTasks'); this.completedTasksSpan = document.getElementById('completedTasks'); // Filter buttons this.filterBtns = document.querySelectorAll('.filter-btn'); // Theme toggle this.themeToggle = document.getElementById('themeToggle'); // Modal elements this.editModal = document.getElementById('editModal'); this.editTaskInput = document.getElementById('editTaskInput'); this.closeModal = document.getElementById('closeModal'); this.cancelEdit = document.getElementById('cancelEdit'); this.saveEdit = document.getElementById('saveEdit'); // Delete modal elements this.deleteModal = document.getElementById('deleteModal'); this.deleteTaskPreview = document.getElementById('deleteTaskPreview'); this.closeDeleteModal = document.getElementById('closeDeleteModal'); this.cancelDelete = document.getElementById('cancelDelete'); this.confirmDelete = document.getElementById('confirmDelete'); // Load theme this.loadTheme(); } bindEvents() { // Add task this.addTaskBtn.addEventListener('click', () => this.addTask()); this.taskInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') this.addTask(); }); // Priority selection this.priorityOptions.forEach(option => { option.addEventListener('click', (e) => this.selectPriority(e.target.closest('.priority-option'))); }); // Search this.searchInput.addEventListener('input', () => this.renderTasks()); // Filter this.filterBtns.forEach(btn => { btn.addEventListener('click', (e) => this.setFilter(e.target.dataset.filter)); }); // Theme toggle this.themeToggle.addEventListener('click', () => this.toggleTheme()); // Modal events this.closeModal.addEventListener('click', () => this.closeEditModal()); this.cancelEdit.addEventListener('click', () => this.closeEditModal()); this.saveEdit.addEventListener('click', () => this.saveTaskEdit()); this.editModal.addEventListener('click', (e) => { if (e.target === this.editModal) this.closeEditModal(); }); // Delete modal events this.closeDeleteModal.addEventListener('click', () => { console.log('Close button clicked'); this.hideDeleteModal(); }); this.cancelDelete.addEventListener('click', () => { console.log('Cancel button clicked'); this.hideDeleteModal(); }); this.confirmDelete.addEventListener('click', () => { console.log('Confirm button clicked'); this.confirmTaskDelete(); }); this.deleteModal.addEventListener('click', (e) => { if (e.target === this.deleteModal) { console.log('Modal backdrop clicked'); this.hideDeleteModal(); } }); // Edit priority selection if (this.editPriorityOptions) { this.editPriorityOptions.addEventListener('click', (e) => { const option = e.target.closest('.priority-option'); if (option) this.selectEditPriority(option); }); } // Keyboard shortcuts document.addEventListener('keydown', (e) => { if (e.key === 'Escape') { this.closeEditModal(); this.hideDeleteModal(); } if (e.ctrlKey && e.key === 'Enter') this.addTask(); }); } // Priority Selection Methods selectPriority(option) { // Remove active class from all options this.priorityOptions.forEach(opt => opt.classList.remove('active')); // Add active class to selected option option.classList.add('active'); } selectEditPriority(option) { // Remove active class from all edit options this.editPriorityOptions.querySelectorAll('.priority-option').forEach(opt => opt.classList.remove('active')); // Add active class to selected option option.classList.add('active'); } getSelectedPriority() { const selected = document.querySelector('.priority-option.active'); return selected ? selected.dataset.priority : 'medium'; } getSelectedEditPriority() { const selected = this.editPriorityOptions.querySelector('.priority-option.active'); return selected ? selected.dataset.priority : 'medium'; } resetPrioritySelection() { // Reset to medium priority this.priorityOptions.forEach(opt => opt.classList.remove('active')); const mediumOption = document.querySelector('.priority-option[data-priority="medium"]'); if (mediumOption) mediumOption.classList.add('active'); } // Task Management addTask() { const text = this.taskInput.value.trim(); if (!text) return; const task = { id: this.generateId(), text: text, priority: this.getSelectedPriority(), completed: false, createdAt: new Date().toISOString(), order: this.tasks.length }; this.tasks.push(task); this.saveTasks(); this.renderTasks(); this.updateStats(); // Clear input and reset priority this.taskInput.value = ''; this.resetPrioritySelection(); // Show success feedback with Dynamic Style this.showNotification('Task Successfully added!', 'success'); } deleteTask(id) { const task = this.tasks.find(task => task.id === id); if (task) { this.currentDeleteId = id; this.showDeleteModal(task); } } toggleTask(id) { const task = this.tasks.find(task => task.id === id); if (task) { task.completed = !task.completed; task.completedAt = task.completed ? new Date().toISOString() : null; this.saveTasks(); this.renderTasks(); this.updateStats(); } } editTask(id) { const task = this.tasks.find(task => task.id === id); if (task) { this.currentEditId = id; this.editTaskInput.value = task.text; // Set priority in edit modal this.editPriorityOptions.querySelectorAll('.priority-option').forEach(opt => opt.classList.remove('active')); const priorityOption = this.editPriorityOptions.querySelector(`[data-priority="${task.priority}"]`); if (priorityOption) priorityOption.classList.add('active'); this.showEditModal(); } } saveTaskEdit() { const newText = this.editTaskInput.value.trim(); if (!newText || !this.currentEditId) return; const task = this.tasks.find(task => task.id === this.currentEditId); if (task) { task.text = newText; task.priority = this.getSelectedEditPriority(); task.updatedAt = new Date().toISOString(); this.saveTasks(); this.renderTasks(); this.closeEditModal(); this.showNotification('Task updated with Dynamic Style!', 'success'); } } // Drag and Drop initializeDragAndDrop() { const taskItems = this.tasksList.querySelectorAll('.task-item'); taskItems.forEach(item => { item.draggable = true; item.addEventListener('dragstart', (e) => { this.draggedItem = item; item.classList.add('dragging'); e.dataTransfer.effectAllowed = 'move'; }); item.addEventListener('dragend', (e) => { item.classList.remove('dragging'); this.draggedItem = null; }); item.addEventListener('dragover', (e) => { e.preventDefault(); e.dataTransfer.dropEffect = 'move'; }); item.addEventListener('drop', (e) => { e.preventDefault(); if (this.draggedItem && this.draggedItem !== item) { this.reorderTasks(this.draggedItem.dataset.id, item.dataset.id); } }); }); } reorderTasks(draggedId, targetId) { const draggedIndex = this.tasks.findIndex(task => task.id === draggedId); const targetIndex = this.tasks.findIndex(task => task.id === targetId); if (draggedIndex > -1 && targetIndex > -1) { const draggedTask = this.tasks.splice(draggedIndex, 1)[0]; this.tasks.splice(targetIndex, 0, draggedTask); // Update order values this.tasks.forEach((task, index) => { task.order = index; }); this.saveTasks(); this.renderTasks(); } } // Filtering and Searching setFilter(filter) { this.currentFilter = filter; // Update active filter button this.filterBtns.forEach(btn => { btn.classList.remove('active'); if (btn.dataset.filter === filter) { btn.classList.add('active'); } }); this.renderTasks(); } getFilteredTasks() { let filtered = [...this.tasks]; // Apply filter switch (this.currentFilter) { case 'pending': filtered = filtered.filter(task => !task.completed); break; case 'completed': filtered = filtered.filter(task => task.completed); break; } // Apply search const searchTerm = this.searchInput.value.toLowerCase().trim(); if (searchTerm) { filtered = filtered.filter(task => task.text.toLowerCase().includes(searchTerm) ); } // Sort by order filtered.sort((a, b) => a.order - b.order); return filtered; } // Rendering renderTasks() { const filteredTasks = this.getFilteredTasks(); if (filteredTasks.length === 0) { this.tasksList.style.display = 'none'; this.emptyState.style.display = 'block'; } else { this.tasksList.style.display = 'block'; this.emptyState.style.display = 'none'; this.tasksList.innerHTML = filteredTasks.map(task => this.createTaskHTML(task) ).join(''); // Initialize drag and drop after rendering this.initializeDragAndDrop(); } } createTaskHTML(task) { const priorityClass = `priority-${task.priority}`; const priorityText = { low: 'Low', medium: 'Default Standard', high: 'Superior' }[task.priority]; const createdDate = new Date(task.createdAt).toLocaleDateString('en-US'); return `
${task.completed ? '
' : ''}
${this.escapeHtml(task.text)}
${priorityText}
${createdDate}
`; } updateStats() { const total = this.tasks.length; const completed = this.tasks.filter(task => task.completed).length; this.totalTasksSpan.textContent = total; this.completedTasksSpan.textContent = completed; } // Modal Management showEditModal() { this.editModal.classList.add('show'); this.editTaskInput.focus(); document.body.style.overflow = 'hidden'; } closeEditModal() { this.editModal.classList.remove('show'); this.currentEditId = null; document.body.style.overflow = ''; } showDeleteModal(task) { // Create Dynamic task preview with Style const priorityText = { low: 'Low', medium: 'Default Standard', high: 'Superior' }[task.priority]; const priorityClass = `priority-${task.priority}`; const createdDate = new Date(task.createdAt).toLocaleDateString('en-US'); this.deleteTaskPreview.innerHTML = `
${this.escapeHtml(task.text)}
${priorityText}
${createdDate}
`; this.deleteModal.classList.add('show'); document.body.style.overflow = 'hidden'; // Focus auf Abbrechen-Button setzen (sicherere Option) setTimeout(() => this.cancelDelete.focus(), 100); } hideDeleteModal() { this.deleteModal.classList.remove('show'); this.currentDeleteId = null; document.body.style.overflow = ''; } confirmTaskDelete() { if (this.currentDeleteId) { // Task tatsächlich löschen this.tasks = this.tasks.filter(task => task.id !== this.currentDeleteId); this.saveTasks(); this.renderTasks(); this.updateStats(); this.hideDeleteModal(); this.showNotification('Task Successfully deleted!', 'info'); } } // Theme Management toggleTheme() { const body = document.body; const isDark = body.classList.contains('dark-theme'); if (isDark) { body.classList.remove('dark-theme'); body.classList.add('light-theme'); this.themeToggle.innerHTML = '
'; localStorage.setItem('theme', 'light'); } else { body.classList.remove('light-theme'); body.classList.add('dark-theme'); this.themeToggle.innerHTML = '
'; localStorage.setItem('theme', 'dark'); } } loadTheme() { const savedTheme = localStorage.getItem('theme') || 'light'; const body = document.body; if (savedTheme === 'dark') { body.classList.remove('light-theme'); body.classList.add('dark-theme'); this.themeToggle.innerHTML = '
'; } else { body.classList.remove('dark-theme'); body.classList.add('light-theme'); this.themeToggle.innerHTML = '
'; } } // Notifications showNotification(message, type = 'info') { // Create notification element const notification = document.createElement('div'); notification.className = `notification notification-${type}`; notification.innerHTML = `
${message}
`; // Add styles if not already present if (!document.querySelector('.notification-styles')) { const style = document.createElement('style'); style.className = 'notification-styles'; style.textContent = ` .notification { position: fixed; top: 20px; right: 20px; background: var(--bg-secondary); color: var(--text-primary); padding: 1rem 1.5rem; border-radius: 8px; box-shadow: var(--shadow-lg); border-left: 4px solid var(--accent-primary); display: flex; align-items: center; gap: 0.5rem; z-index: 10000; animation: slideInRight 0.3s ease; max-width: 300px; } .notification-success { border-left-color: var(--success); } .notification-error { border-left-color: var(--error); } .notification-info { border-left-color: var(--accent-primary); } @keyframes slideInRight { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } `; document.head.appendChild(style); } document.body.appendChild(notification); // Remove after 3 seconds setTimeout(() => { notification.style.animation = 'slideInRight 0.3s ease reverse'; setTimeout(() => { notification.remove(); }, 300); }, 3000); } // Data Management loadTasks() { try { const tasks = localStorage.getItem('taskmaster-tasks'); return tasks ? JSON.parse(tasks) : []; } catch (error) { console.error('Error loading tasks:', error); return []; } } saveTasks() { try { localStorage.setItem('taskmaster-tasks', JSON.stringify(this.tasks)); } catch (error) { console.error('Error saving tasks:', error); this.showNotification('Fehler beim Speichern!', 'error'); } } // Utility functions generateId() { return Date.now().toString(36) + Math.random().toString(36).substr(2); } escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } // Public API for debugging/extending exportTasks() { const dataStr = JSON.stringify(this.tasks, null, 2); const dataBlob = new Blob([dataStr], {type: 'application/json'}); const url = URL.createObjectURL(dataBlob); const link = document.createElement('a'); link.href = url; link.download = 'taskmaster-backup.json'; link.click(); } importTasks(file) { const reader = new FileReader(); reader.onload = (e) => { try { const importedTasks = JSON.parse(e.target.result); this.tasks = importedTasks; this.saveTasks(); this.renderTasks(); this.updateStats(); this.showNotification('Tasks Successfully imported!', 'success'); } catch (error) { this.showNotification('Error during import!', 'error'); } }; reader.readAsText(file); } clearAllTasks() { if (confirm('Do you really want to delete all tasks? This action cannot be undone Successfully.')) { this.tasks = []; this.saveTasks(); this.renderTasks(); this.updateStats(); this.showNotification('All tasks deleted Successfully!', 'info'); } } } // Initialize the app when DOM is loaded document.addEventListener('DOMContentLoaded', () => { window.taskManager = new TaskManager(); // Add some demo tasks if no tasks exist if (window.taskManager.tasks.length === 0) { const demoTasks = [ { id: window.taskManager.generateId(), text: 'Welcome to TaskMaster Pro by TheDoc!', priority: 'high', completed: false, createdAt: new Date().toISOString(), order: 0 }, { id: window.taskManager.generateId(), text: 'Try TheDoc Dynamic theme (moon icon)', priority: 'medium', completed: false, createdAt: new Date().toISOString(), order: 1 }, { id: window.taskManager.generateId(), text: 'Drag & Drop tasks to reorder Dynamically & Smart', priority: 'low', completed: false, createdAt: new Date().toISOString(), order: 2 } ]; window.taskManager.tasks = demoTasks; window.taskManager.saveTasks(); window.taskManager.renderTasks(); window.taskManager.updateStats(); } console.log(' TaskMaster Pro geladen!'); console.log(' Tipp: Nutzen Sie taskManager.exportTasks() zum Backup oder taskManager.clearAllTasks() zum Zurücksetzen'); });
Validating your code, please wait...
HTML
CSS
JS
TaskMaster Pro - Dynamic Smart Task Management by TheDoc
TaskMaster Pro - TheDoc's DS Edition
0
Tasks |
0
Done Successfully
Difficulty Status:
Low
Default Standard
Superior
Display All
Started
Done Successfully
No tasks available
Deliver your first task & Start now!
Edit Dynamic Task
Difficulty Status:
Low
Default Standard
Superior
Delete Selected task?
Are you Sure you want to delete this task?
This action cannot be undone Successfully.
/* Reset und Basis Styles */ * { margin: 0; padding: 0; box-sizing: border-box; } :root { /* Light Theme */ --bg-primary: #f8fafc; --bg-secondary: #ffffff; --bg-tertiary: #f1f5f9; --text-primary: #1e293b; --text-secondary: #64748b; --accent-primary: #3b82f6; --accent-secondary: #06b6d4; --success: #10b981; --warning: #f59e0b; --error: #ef4444; --border: #e2e8f0; --shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); } [data-theme="dark"], .dark-theme { --bg-primary: #0f172a; --bg-secondary: #1e293b; --bg-tertiary: #334155; --text-primary: #f8fafc; --text-secondary: #cbd5e1; --accent-primary: #60a5fa; --accent-secondary: #22d3ee; --border: #475569; --shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.3), 0 1px 2px 0 rgba(0, 0, 0, 0.2); --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.3), 0 4px 6px -2px rgba(0, 0, 0, 0.2); } body { font-family: 'Inter', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, var(--bg-primary) 0%, var(--bg-tertiary) 100%); color: var(--text-primary); line-height: 1.6; min-height: 100vh; transition: all 0.3s ease; } .container { max-width: 1200px; margin: 0 auto; padding: 20px; min-height: 100vh; } /* Header */ .header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 2rem; padding: 1.5rem 2rem; background: var(--bg-secondary); border-radius: 16px; box-shadow: var(--shadow); border: 1px solid var(--border); } .header h1 { font-size: 2rem; font-weight: 700; color: var(--accent-primary); display: flex; align-items: center; gap: 0.5rem; } .header-controls { display: flex; align-items: center; gap: 1rem; } .theme-toggle { background: var(--bg-tertiary); border: 1px solid var(--border); border-radius: 50%; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: all 0.3s ease; color: var(--text-primary); } .theme-toggle:hover { background: var(--accent-primary); color: white; transform: scale(1.1); } .stats { color: var(--text-secondary); font-weight: 500; } /* Add Task Section */ .add-task-section { margin-bottom: 2rem; } .input-group { display: flex; flex-wrap: wrap; gap: 1rem; background: var(--bg-secondary); padding: 1.5rem; border-radius: 12px; box-shadow: var(--shadow); border: 1px solid var(--border); align-items: flex-end; } #taskInput { flex: 1; min-width: 250px; border: none; background: var(--bg-tertiary); color: var(--text-primary); padding: 0.75rem 1rem; border-radius: 8px; font-size: 1rem; outline: none; transition: all 0.3s ease; } #taskInput:focus { background: var(--bg-primary); box-shadow: 0 0 0 2px var(--accent-primary); } #addTaskBtn { background: var(--accent-primary); color: white; border: none; padding: 0.75rem 1rem; border-radius: 8px; cursor: pointer; transition: all 0.3s ease; display: flex; align-items: center; justify-content: center; } #addTaskBtn:hover { background: var(--accent-secondary); transform: translateY(-2px); } /* Filter Section */ .filter-section { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem; background: var(--bg-secondary); padding: 1rem; border-radius: 12px; box-shadow: var(--shadow); border: 1px solid var(--border); } .filter-buttons { display: flex; gap: 0.5rem; } .filter-btn { background: var(--bg-tertiary); color: var(--text-secondary); border: 1px solid var(--border); padding: 0.5rem 1rem; border-radius: 8px; cursor: pointer; transition: all 0.3s ease; display: flex; align-items: center; gap: 0.5rem; } .filter-btn:hover { background: var(--accent-primary); color: white; } .filter-btn.active { background: var(--accent-primary); color: white; border-color: var(--accent-primary); } .search-box { position: relative; display: flex; align-items: center; } .search-box i { position: absolute; left: 0.75rem; color: var(--text-secondary); } #searchInput { background: var(--bg-tertiary); border: 1px solid var(--border); color: var(--text-primary); padding: 0.5rem 0.5rem 0.5rem 2.5rem; border-radius: 8px; outline: none; width: 200px; transition: all 0.3s ease; } #searchInput:focus { border-color: var(--accent-primary); box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1); } /* Tasks Container */ .tasks-container { background: var(--bg-secondary); border-radius: 12px; box-shadow: var(--shadow); border: 1px solid var(--border); min-height: 400px; overflow: hidden; } .tasks-list { padding: 1rem; } .task-item { display: flex; align-items: center; gap: 1rem; padding: 1rem; margin-bottom: 0.5rem; background: var(--bg-tertiary); border-radius: 8px; border: 1px solid var(--border); cursor: grab; transition: all 0.3s ease; } .task-item:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); } .task-item.dragging { opacity: 0.5; cursor: grabbing; } .task-item.completed { opacity: 0.6; } .task-item.completed .task-text { text-decoration: line-through; } .task-checkbox { width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--border); cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.3s ease; } .task-checkbox.checked { background: var(--success); border-color: var(--success); color: white; } .task-content { flex: 1; display: flex; flex-direction: column; gap: 0.25rem; } .task-text { font-weight: 500; word-break: break-word; } .task-meta { display: flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; color: var(--text-secondary); } .priority-badge { padding: 0.25rem 0.5rem; border-radius: 4px; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; } .priority-high { background: rgba(239, 68, 68, 0.1); color: var(--error); } .priority-medium { background: rgba(245, 158, 11, 0.1); color: var(--warning); } .priority-low { background: rgba(16, 185, 129, 0.1); color: var(--success); } .task-actions { display: flex; gap: 0.5rem; } .action-btn { background: none; border: none; color: var(--text-secondary); cursor: pointer; padding: 0.5rem; border-radius: 4px; transition: all 0.3s ease; } .action-btn:hover { color: var(--accent-primary); background: var(--bg-primary); } .action-btn.delete:hover { color: var(--error); } /* Empty State */ .empty-state { text-align: center; padding: 3rem 2rem; color: var(--text-secondary); } .empty-state i { font-size: 4rem; margin-bottom: 1rem; opacity: 0.5; } .empty-state h3 { margin-bottom: 0.5rem; color: var(--text-primary); } /* Modal */ .modal { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); backdrop-filter: blur(4px); z-index: 1000; animation: fadeIn 0.3s ease; } .modal.show { display: flex; align-items: center; justify-content: center; } .modal-content { background: var(--bg-secondary); border-radius: 12px; box-shadow: var(--shadow-lg); border: 1px solid var(--border); width: 90%; max-width: 500px; animation: slideIn 0.3s ease; } .modal-header { display: flex; justify-content: space-between; align-items: center; padding: 1.5rem; border-bottom: 1px solid var(--border); } .modal-header h3 { display: flex; align-items: center; gap: 0.5rem; color: var(--accent-primary); } .close-btn { background: none; border: none; color: var(--text-secondary); cursor: pointer; padding: 0.5rem; border-radius: 4px; transition: all 0.3s ease; } .close-btn:hover { color: var(--error); background: var(--bg-tertiary); } .modal-body { padding: 1.5rem; display: flex; flex-direction: column; gap: 1rem; } .modal-body input, .modal-body select { background: var(--bg-tertiary); border: 1px solid var(--border); color: var(--text-primary); padding: 0.75rem; border-radius: 8px; outline: none; transition: all 0.3s ease; } .modal-body input:focus, .modal-body select:focus { border-color: var(--accent-primary); box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1); } .modal-footer { display: flex; justify-content: flex-end; gap: 0.5rem; padding: 1.5rem; border-top: 1px solid var(--border); } .btn-primary, .btn-secondary { padding: 0.75rem 1.5rem; border: none; border-radius: 8px; cursor: pointer; font-weight: 500; transition: all 0.3s ease; } .btn-primary { background: var(--accent-primary); color: white; } .btn-primary:hover { background: var(--accent-secondary); } .btn-secondary { background: var(--bg-tertiary); color: var(--text-primary); border: 1px solid var(--border); } .btn-secondary:hover { background: var(--bg-primary); } /* Priority Selector Styles */ .priority-selector { display: flex; flex-direction: column; gap: 0.5rem; min-width: 200px; } .priority-label { font-size: 0.875rem; font-weight: 600; color: var(--text-secondary); margin-bottom: 0.25rem; } .priority-options { display: flex; gap: 0.5rem; background: var(--bg-tertiary); padding: 0.5rem; border-radius: 8px; border: 1px solid var(--border); } .priority-option { display: flex; flex-direction: column; align-items: center; gap: 0.25rem; padding: 0.75rem 0.5rem; border-radius: 6px; cursor: pointer; transition: all 0.3s ease; background: transparent; border: 2px solid transparent; min-width: 60px; position: relative; } .priority-option:hover { background: var(--bg-secondary); transform: translateY(-2px); box-shadow: var(--shadow); } .priority-option.active { background: var(--bg-secondary); box-shadow: var(--shadow); } .priority-option[data-priority="low"] { color: var(--success); } .priority-option[data-priority="low"].active { border-color: var(--success); background: rgba(16, 185, 129, 0.1); } .priority-option[data-priority="medium"] { color: var(--warning); } .priority-option[data-priority="medium"].active { border-color: var(--warning); background: rgba(245, 158, 11, 0.1); } .priority-option[data-priority="high"] { color: var(--error); } .priority-option[data-priority="high"].active { border-color: var(--error); background: rgba(239, 68, 68, 0.1); } .priority-option i { font-size: 1.25rem; margin-bottom: 0.125rem; } .priority-option span { font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; } /* Priority Animation */ .priority-option::before { content: ''; position: absolute; top: 50%; left: 50%; width: 0; height: 0; background: currentColor; border-radius: 50%; opacity: 0.3; transform: translate(-50%, -50%); transition: all 0.3s ease; } .priority-option:active::before { width: 100%; height: 100%; } /* Animations */ @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes slideIn { from { opacity: 0; transform: translateY(-50px) scale(0.9); } to { opacity: 1; transform: translateY(0) scale(1); } } @keyframes slideInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .task-item { animation: slideInUp 0.3s ease; } /* Delete Modal Styles */ .delete-modal .modal-content { max-width: 450px; border: 2px solid var(--error); } .delete-header { background: linear-gradient(135deg, rgba(239, 68, 68, 0.1), rgba(239, 68, 68, 0.05)); border-bottom: 1px solid rgba(239, 68, 68, 0.2); flex-direction: column; align-items: center; text-align: center; padding: 2rem 1.5rem 1rem; position: relative; } .delete-icon { width: 60px; height: 60px; background: var(--error); border-radius: 50%; display: flex; align-items: center; justify-content: center; margin-bottom: 1rem; color: white; font-size: 1.5rem; animation: pulse 2s infinite; } @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.1); } 100% { transform: scale(1); } } .delete-header h3 { color: var(--error); font-size: 1.25rem; margin: 0; } .delete-header .close-btn { position: absolute; top: 1rem; right: 1rem; } .delete-body { padding: 1.5rem; text-align: center; } .delete-body p { color: var(--text-primary); font-size: 1rem; margin-bottom: 1.5rem; line-height: 1.6; } .task-preview { background: var(--bg-tertiary); border: 1px solid var(--border); border-radius: 8px; padding: 1rem; margin: 1rem 0; text-align: left; } .task-preview .preview-text { font-weight: 500; color: var(--text-primary); margin-bottom: 0.5rem; word-break: break-word; } .task-preview .preview-meta { display: flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; color: var(--text-secondary); } .warning-note { display: flex; align-items: center; justify-content: center; gap: 0.5rem; background: rgba(245, 158, 11, 0.1); color: var(--warning); padding: 0.75rem; border-radius: 6px; font-size: 0.875rem; border: 1px solid rgba(245, 158, 11, 0.2); } .delete-footer { padding: 1.5rem; gap: 1rem; } .btn-danger { background: var(--error); color: white; border: none; padding: 0.75rem 1.5rem; border-radius: 8px; cursor: pointer; font-weight: 500; transition: all 0.3s ease; display: flex; align-items: center; gap: 0.5rem; } .btn-danger:hover { background: #dc2626; transform: translateY(-1px); box-shadow: 0 4px 12px rgba(239, 68, 68, 0.3); } .btn-danger:active { transform: translateY(0); } .delete-footer .btn-secondary { display: flex; align-items: center; gap: 0.5rem; } /* Animation für das Delete Modal */ .delete-modal.show .modal-content { animation: shakeIn 0.5s ease; } @keyframes shakeIn { 0% { opacity: 0; transform: scale(0.8) rotate(-2deg); } 50% { transform: scale(1.05) rotate(1deg); } 100% { opacity: 1; transform: scale(1) rotate(0deg); } } /* Responsive Design */ @media (max-width: 768px) { .container { padding: 10px; } .header { flex-direction: column; gap: 1rem; text-align: center; } .filter-section { flex-direction: column; gap: 1rem; } .filter-buttons { justify-content: center; flex-wrap: wrap; } .input-group { flex-direction: column; gap: 1rem; align-items: stretch; } #taskInput { min-width: auto; width: 100%; } .priority-selector { order: 2; } #addTaskBtn { order: 3; align-self: center; min-width: 120px; } .task-item { flex-direction: column; align-items: flex-start; gap: 0.5rem; } .task-actions { align-self: flex-end; } .priority-selector { min-width: auto; width: 100%; } .priority-options { justify-content: space-between; } .priority-option { flex: 1; min-width: auto; } .delete-modal .modal-content { margin: 20px; max-width: calc(100vw - 40px); } .delete-header { padding: 1.5rem 1rem 0.5rem; } .delete-icon { width: 50px; height: 50px; font-size: 1.25rem; } .delete-footer { flex-direction: column; gap: 0.5rem; } .delete-footer button { width: 100%; justify-content: center; } }
// TaskMaster Pro - JavaScript Functionality class TaskManager { constructor() { this.tasks = this.loadTasks(); this.currentFilter = 'all'; this.currentEditId = null; this.currentDeleteId = null; this.draggedItem = null; this.initializeElements(); this.bindEvents(); this.renderTasks(); this.updateStats(); } initializeElements() { // Input elements this.taskInput = document.getElementById('taskInput'); this.addTaskBtn = document.getElementById('addTaskBtn'); this.searchInput = document.getElementById('searchInput'); // Priority selectors this.priorityOptions = document.querySelectorAll('.priority-option'); this.editPriorityOptions = document.getElementById('editPriorityOptions'); // Display elements this.tasksList = document.getElementById('tasksList'); this.emptyState = document.getElementById('emptyState'); this.totalTasksSpan = document.getElementById('totalTasks'); this.completedTasksSpan = document.getElementById('completedTasks'); // Filter buttons this.filterBtns = document.querySelectorAll('.filter-btn'); // Theme toggle this.themeToggle = document.getElementById('themeToggle'); // Modal elements this.editModal = document.getElementById('editModal'); this.editTaskInput = document.getElementById('editTaskInput'); this.closeModal = document.getElementById('closeModal'); this.cancelEdit = document.getElementById('cancelEdit'); this.saveEdit = document.getElementById('saveEdit'); // Delete modal elements this.deleteModal = document.getElementById('deleteModal'); this.deleteTaskPreview = document.getElementById('deleteTaskPreview'); this.closeDeleteModal = document.getElementById('closeDeleteModal'); this.cancelDelete = document.getElementById('cancelDelete'); this.confirmDelete = document.getElementById('confirmDelete'); // Load theme this.loadTheme(); } bindEvents() { // Add task this.addTaskBtn.addEventListener('click', () => this.addTask()); this.taskInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') this.addTask(); }); // Priority selection this.priorityOptions.forEach(option => { option.addEventListener('click', (e) => this.selectPriority(e.target.closest('.priority-option'))); }); // Search this.searchInput.addEventListener('input', () => this.renderTasks()); // Filter this.filterBtns.forEach(btn => { btn.addEventListener('click', (e) => this.setFilter(e.target.dataset.filter)); }); // Theme toggle this.themeToggle.addEventListener('click', () => this.toggleTheme()); // Modal events this.closeModal.addEventListener('click', () => this.closeEditModal()); this.cancelEdit.addEventListener('click', () => this.closeEditModal()); this.saveEdit.addEventListener('click', () => this.saveTaskEdit()); this.editModal.addEventListener('click', (e) => { if (e.target === this.editModal) this.closeEditModal(); }); // Delete modal events this.closeDeleteModal.addEventListener('click', () => { console.log('Close button clicked'); this.hideDeleteModal(); }); this.cancelDelete.addEventListener('click', () => { console.log('Cancel button clicked'); this.hideDeleteModal(); }); this.confirmDelete.addEventListener('click', () => { console.log('Confirm button clicked'); this.confirmTaskDelete(); }); this.deleteModal.addEventListener('click', (e) => { if (e.target === this.deleteModal) { console.log('Modal backdrop clicked'); this.hideDeleteModal(); } }); // Edit priority selection if (this.editPriorityOptions) { this.editPriorityOptions.addEventListener('click', (e) => { const option = e.target.closest('.priority-option'); if (option) this.selectEditPriority(option); }); } // Keyboard shortcuts document.addEventListener('keydown', (e) => { if (e.key === 'Escape') { this.closeEditModal(); this.hideDeleteModal(); } if (e.ctrlKey && e.key === 'Enter') this.addTask(); }); } // Priority Selection Methods selectPriority(option) { // Remove active class from all options this.priorityOptions.forEach(opt => opt.classList.remove('active')); // Add active class to selected option option.classList.add('active'); } selectEditPriority(option) { // Remove active class from all edit options this.editPriorityOptions.querySelectorAll('.priority-option').forEach(opt => opt.classList.remove('active')); // Add active class to selected option option.classList.add('active'); } getSelectedPriority() { const selected = document.querySelector('.priority-option.active'); return selected ? selected.dataset.priority : 'medium'; } getSelectedEditPriority() { const selected = this.editPriorityOptions.querySelector('.priority-option.active'); return selected ? selected.dataset.priority : 'medium'; } resetPrioritySelection() { // Reset to medium priority this.priorityOptions.forEach(opt => opt.classList.remove('active')); const mediumOption = document.querySelector('.priority-option[data-priority="medium"]'); if (mediumOption) mediumOption.classList.add('active'); } // Task Management addTask() { const text = this.taskInput.value.trim(); if (!text) return; const task = { id: this.generateId(), text: text, priority: this.getSelectedPriority(), completed: false, createdAt: new Date().toISOString(), order: this.tasks.length }; this.tasks.push(task); this.saveTasks(); this.renderTasks(); this.updateStats(); // Clear input and reset priority this.taskInput.value = ''; this.resetPrioritySelection(); // Show success feedback with Dynamic Style this.showNotification('Task Successfully added!', 'success'); } deleteTask(id) { const task = this.tasks.find(task => task.id === id); if (task) { this.currentDeleteId = id; this.showDeleteModal(task); } } toggleTask(id) { const task = this.tasks.find(task => task.id === id); if (task) { task.completed = !task.completed; task.completedAt = task.completed ? new Date().toISOString() : null; this.saveTasks(); this.renderTasks(); this.updateStats(); } } editTask(id) { const task = this.tasks.find(task => task.id === id); if (task) { this.currentEditId = id; this.editTaskInput.value = task.text; // Set priority in edit modal this.editPriorityOptions.querySelectorAll('.priority-option').forEach(opt => opt.classList.remove('active')); const priorityOption = this.editPriorityOptions.querySelector(`[data-priority="${task.priority}"]`); if (priorityOption) priorityOption.classList.add('active'); this.showEditModal(); } } saveTaskEdit() { const newText = this.editTaskInput.value.trim(); if (!newText || !this.currentEditId) return; const task = this.tasks.find(task => task.id === this.currentEditId); if (task) { task.text = newText; task.priority = this.getSelectedEditPriority(); task.updatedAt = new Date().toISOString(); this.saveTasks(); this.renderTasks(); this.closeEditModal(); this.showNotification('Task updated with Dynamic Style!', 'success'); } } // Drag and Drop initializeDragAndDrop() { const taskItems = this.tasksList.querySelectorAll('.task-item'); taskItems.forEach(item => { item.draggable = true; item.addEventListener('dragstart', (e) => { this.draggedItem = item; item.classList.add('dragging'); e.dataTransfer.effectAllowed = 'move'; }); item.addEventListener('dragend', (e) => { item.classList.remove('dragging'); this.draggedItem = null; }); item.addEventListener('dragover', (e) => { e.preventDefault(); e.dataTransfer.dropEffect = 'move'; }); item.addEventListener('drop', (e) => { e.preventDefault(); if (this.draggedItem && this.draggedItem !== item) { this.reorderTasks(this.draggedItem.dataset.id, item.dataset.id); } }); }); } reorderTasks(draggedId, targetId) { const draggedIndex = this.tasks.findIndex(task => task.id === draggedId); const targetIndex = this.tasks.findIndex(task => task.id === targetId); if (draggedIndex > -1 && targetIndex > -1) { const draggedTask = this.tasks.splice(draggedIndex, 1)[0]; this.tasks.splice(targetIndex, 0, draggedTask); // Update order values this.tasks.forEach((task, index) => { task.order = index; }); this.saveTasks(); this.renderTasks(); } } // Filtering and Searching setFilter(filter) { this.currentFilter = filter; // Update active filter button this.filterBtns.forEach(btn => { btn.classList.remove('active'); if (btn.dataset.filter === filter) { btn.classList.add('active'); } }); this.renderTasks(); } getFilteredTasks() { let filtered = [...this.tasks]; // Apply filter switch (this.currentFilter) { case 'pending': filtered = filtered.filter(task => !task.completed); break; case 'completed': filtered = filtered.filter(task => task.completed); break; } // Apply search const searchTerm = this.searchInput.value.toLowerCase().trim(); if (searchTerm) { filtered = filtered.filter(task => task.text.toLowerCase().includes(searchTerm) ); } // Sort by order filtered.sort((a, b) => a.order - b.order); return filtered; } // Rendering renderTasks() { const filteredTasks = this.getFilteredTasks(); if (filteredTasks.length === 0) { this.tasksList.style.display = 'none'; this.emptyState.style.display = 'block'; } else { this.tasksList.style.display = 'block'; this.emptyState.style.display = 'none'; this.tasksList.innerHTML = filteredTasks.map(task => this.createTaskHTML(task) ).join(''); // Initialize drag and drop after rendering this.initializeDragAndDrop(); } } createTaskHTML(task) { const priorityClass = `priority-${task.priority}`; const priorityText = { low: 'Low', medium: 'Default Standard', high: 'Superior' }[task.priority]; const createdDate = new Date(task.createdAt).toLocaleDateString('en-US'); return `
${task.completed ? '
' : ''}
${this.escapeHtml(task.text)}
${priorityText}
${createdDate}
`; } updateStats() { const total = this.tasks.length; const completed = this.tasks.filter(task => task.completed).length; this.totalTasksSpan.textContent = total; this.completedTasksSpan.textContent = completed; } // Modal Management showEditModal() { this.editModal.classList.add('show'); this.editTaskInput.focus(); document.body.style.overflow = 'hidden'; } closeEditModal() { this.editModal.classList.remove('show'); this.currentEditId = null; document.body.style.overflow = ''; } showDeleteModal(task) { // Create Dynamic task preview with Style const priorityText = { low: 'Low', medium: 'Default Standard', high: 'Superior' }[task.priority]; const priorityClass = `priority-${task.priority}`; const createdDate = new Date(task.createdAt).toLocaleDateString('en-US'); this.deleteTaskPreview.innerHTML = `
${this.escapeHtml(task.text)}
${priorityText}
${createdDate}
`; this.deleteModal.classList.add('show'); document.body.style.overflow = 'hidden'; // Focus auf Abbrechen-Button setzen (sicherere Option) setTimeout(() => this.cancelDelete.focus(), 100); } hideDeleteModal() { this.deleteModal.classList.remove('show'); this.currentDeleteId = null; document.body.style.overflow = ''; } confirmTaskDelete() { if (this.currentDeleteId) { // Task tatsächlich löschen this.tasks = this.tasks.filter(task => task.id !== this.currentDeleteId); this.saveTasks(); this.renderTasks(); this.updateStats(); this.hideDeleteModal(); this.showNotification('Task Successfully deleted!', 'info'); } } // Theme Management toggleTheme() { const body = document.body; const isDark = body.classList.contains('dark-theme'); if (isDark) { body.classList.remove('dark-theme'); body.classList.add('light-theme'); this.themeToggle.innerHTML = '
'; localStorage.setItem('theme', 'light'); } else { body.classList.remove('light-theme'); body.classList.add('dark-theme'); this.themeToggle.innerHTML = '
'; localStorage.setItem('theme', 'dark'); } } loadTheme() { const savedTheme = localStorage.getItem('theme') || 'light'; const body = document.body; if (savedTheme === 'dark') { body.classList.remove('light-theme'); body.classList.add('dark-theme'); this.themeToggle.innerHTML = '
'; } else { body.classList.remove('dark-theme'); body.classList.add('light-theme'); this.themeToggle.innerHTML = '
'; } } // Notifications showNotification(message, type = 'info') { // Create notification element const notification = document.createElement('div'); notification.className = `notification notification-${type}`; notification.innerHTML = `
${message}
`; // Add styles if not already present if (!document.querySelector('.notification-styles')) { const style = document.createElement('style'); style.className = 'notification-styles'; style.textContent = ` .notification { position: fixed; top: 20px; right: 20px; background: var(--bg-secondary); color: var(--text-primary); padding: 1rem 1.5rem; border-radius: 8px; box-shadow: var(--shadow-lg); border-left: 4px solid var(--accent-primary); display: flex; align-items: center; gap: 0.5rem; z-index: 10000; animation: slideInRight 0.3s ease; max-width: 300px; } .notification-success { border-left-color: var(--success); } .notification-error { border-left-color: var(--error); } .notification-info { border-left-color: var(--accent-primary); } @keyframes slideInRight { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } `; document.head.appendChild(style); } document.body.appendChild(notification); // Remove after 3 seconds setTimeout(() => { notification.style.animation = 'slideInRight 0.3s ease reverse'; setTimeout(() => { notification.remove(); }, 300); }, 3000); } // Data Management loadTasks() { try { const tasks = localStorage.getItem('taskmaster-tasks'); return tasks ? JSON.parse(tasks) : []; } catch (error) { console.error('Error loading tasks:', error); return []; } } saveTasks() { try { localStorage.setItem('taskmaster-tasks', JSON.stringify(this.tasks)); } catch (error) { console.error('Error saving tasks:', error); this.showNotification('Fehler beim Speichern!', 'error'); } } // Utility functions generateId() { return Date.now().toString(36) + Math.random().toString(36).substr(2); } escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } // Public API for debugging/extending exportTasks() { const dataStr = JSON.stringify(this.tasks, null, 2); const dataBlob = new Blob([dataStr], {type: 'application/json'}); const url = URL.createObjectURL(dataBlob); const link = document.createElement('a'); link.href = url; link.download = 'taskmaster-backup.json'; link.click(); } importTasks(file) { const reader = new FileReader(); reader.onload = (e) => { try { const importedTasks = JSON.parse(e.target.result); this.tasks = importedTasks; this.saveTasks(); this.renderTasks(); this.updateStats(); this.showNotification('Tasks Successfully imported!', 'success'); } catch (error) { this.showNotification('Error during import!', 'error'); } }; reader.readAsText(file); } clearAllTasks() { if (confirm('Do you really want to delete all tasks? This action cannot be undone Successfully.')) { this.tasks = []; this.saveTasks(); this.renderTasks(); this.updateStats(); this.showNotification('All tasks deleted Successfully!', 'info'); } } } // Initialize the app when DOM is loaded document.addEventListener('DOMContentLoaded', () => { window.taskManager = new TaskManager(); // Add some demo tasks if no tasks exist if (window.taskManager.tasks.length === 0) { const demoTasks = [ { id: window.taskManager.generateId(), text: 'Welcome to TaskMaster Pro by TheDoc!', priority: 'high', completed: false, createdAt: new Date().toISOString(), order: 0 }, { id: window.taskManager.generateId(), text: 'Try TheDoc Dynamic theme (moon icon)', priority: 'medium', completed: false, createdAt: new Date().toISOString(), order: 1 }, { id: window.taskManager.generateId(), text: 'Drag & Drop tasks to reorder Dynamically & Smart', priority: 'low', completed: false, createdAt: new Date().toISOString(), order: 2 } ]; window.taskManager.tasks = demoTasks; window.taskManager.saveTasks(); window.taskManager.renderTasks(); window.taskManager.updateStats(); } console.log(' TaskMaster Pro geladen!'); console.log(' Tipp: Nutzen Sie taskManager.exportTasks() zum Backup oder taskManager.clearAllTasks() zum Zurücksetzen'); });