From 7f5384d0bc36b6785ab426163a0387aa6d658877 Mon Sep 17 00:00:00 2001 From: Honey Date: Tue, 17 Feb 2026 18:45:16 +0100 Subject: [PATCH] Color on right - Better Handling --- public/app.js | 782 ++++++++++++++++++-------------------- public/img/background.jpg | Bin 0 -> 49394 bytes public/index.html | 31 +- public/styles.css | 662 ++++++++++++++++++++------------ readme.me | 69 ++-- server/server.js | 86 ++--- 6 files changed, 884 insertions(+), 746 deletions(-) create mode 100644 public/img/background.jpg diff --git a/public/app.js b/public/app.js index b8e16e7..7299aef 100644 --- a/public/app.js +++ b/public/app.js @@ -9,6 +9,8 @@ class Task { this.reward = reward; this.completed = false; this.expandDescription = false; + this.dueDate = null; + this.color = '#6366f1'; this.subtasks = []; } @@ -18,15 +20,9 @@ class Task { } calculateProgress() { - if (this.subtasks.length === 0) { - return this.completed ? 100 : 0; - } - + if (this.subtasks.length === 0) return this.completed ? 100 : 0; const totalWeight = this.subtasks.reduce((sum, st) => sum + st.getProgressWeight(), 0); - const completedWeight = this.subtasks.reduce((sum, st) => { - return sum + (st.completed ? st.getProgressWeight() : 0); - }, 0); - + const completedWeight = this.subtasks.reduce((sum, st) => sum + (st.completed ? st.getProgressWeight() : 0), 0); return totalWeight > 0 ? Math.round((completedWeight / totalWeight) * 100) : 0; } } @@ -35,7 +31,7 @@ class App { constructor() { this.tasks = []; this.archivedTasks = []; - this.viewMode = 'active'; // 'active' or 'archive' + this.viewMode = 'active'; this.draggedTask = null; this.draggedSubtask = null; this.draggedParent = null; @@ -44,15 +40,50 @@ class App { this.contextMenuTarget = null; this.contextMenuType = null; this.contextMenuParent = null; + this._previousOverallProgress = 0; + this._celebrateTaskId = null; + this._initialized = false; + this._collapsedTasks = new Set(JSON.parse(localStorage.getItem('collapsedTasks') || '[]')); this.init(); } async init() { + this.setupGreeting(); this.setupEventListeners(); await this.loadTasks(); await this.loadArchivedCount(); } + // ─── Greeting ─── + + setupGreeting() { + const hour = new Date().getHours(); + let emoji, greeting, sub; + + if (hour >= 5 && hour < 12) { + emoji = '☀️'; + greeting = 'Good morning, Marc'; + sub = 'Ready to learn something new today?'; + } else if (hour >= 12 && hour < 17) { + emoji = '🌞'; + greeting = 'Good afternoon, Marc'; + sub = 'Keep up the momentum!'; + } else if (hour >= 17 && hour < 21) { + emoji = '🌇'; + greeting = 'Good evening, Marc'; + sub = 'Great time to wrap up some goals.'; + } else { + emoji = '🌙'; + greeting = 'Hey there, Marc'; + sub = 'Burning the midnight oil?'; + } + + document.getElementById('greeting-banner').innerHTML = ` +
${emoji} ${greeting}
+
${sub}
+ `; + } + setupEventListeners() { const form = document.getElementById('task-form'); const openModal = document.getElementById('open-modal'); @@ -63,12 +94,8 @@ class App { form.addEventListener('submit', (e) => this.handleSubmit(e)); openModal.addEventListener('click', () => this.openCreateModal()); closeModal.addEventListener('click', () => this.toggleModal(false)); + modal.addEventListener('click', (e) => { if (e.target === modal) this.toggleModal(false); }); - modal.addEventListener('click', (e) => { - if (e.target === modal) this.toggleModal(false); - }); - - // Context menu actions document.getElementById('context-edit').addEventListener('click', () => this.handleContextEdit()); document.getElementById('context-delete').addEventListener('click', () => this.handleContextDelete()); document.getElementById('context-promote').addEventListener('click', () => this.handleContextPromote()); @@ -78,9 +105,74 @@ class App { document.addEventListener('click', () => this.hideContextMenu()); contextMenu.addEventListener('click', (e) => e.stopPropagation()); - // View toggle document.getElementById('view-active').addEventListener('click', () => this.switchView('active')); document.getElementById('view-archive').addEventListener('click', () => this.switchView('archive')); + + // Color preset dots + document.getElementById('color-presets').addEventListener('click', (e) => { + const dot = e.target.closest('.color-dot'); + if (!dot) return; + const color = dot.dataset.color; + document.getElementById('task-color').value = color; + this._updateColorDotActive(color); + }); + + document.getElementById('task-color').addEventListener('input', (e) => { + this._updateColorDotActive(e.target.value); + }); + } + + _updateColorDotActive(color) { + document.querySelectorAll('#color-presets .color-dot').forEach(d => { + d.classList.toggle('active', d.dataset.color === color); + }); + } + + // ─── Due Date Helpers ─── + + getDueDateInfo(dueDate) { + if (!dueDate) return null; + const now = new Date(); + now.setHours(0, 0, 0, 0); + const due = new Date(dueDate + 'T00:00:00'); + const diffMs = due - now; + const diffDays = Math.ceil(diffMs / (1000 * 60 * 60 * 24)); + + const opts = { month: 'short', day: 'numeric' }; + if (due.getFullYear() !== now.getFullYear()) opts.year = 'numeric'; + const label = due.toLocaleDateString(undefined, opts); + + if (diffDays < 0) return { label, className: 'due-overdue', text: `${label} (overdue)` }; + if (diffDays === 0) return { label, className: 'due-overdue', text: `${label} (today)` }; + if (diffDays <= 7) return { label, className: 'due-soon', text: `${label} (${diffDays}d)` }; + return { label, className: 'due-ok', text: `${label} (${diffDays}d)` }; + } + + renderDueBadge(dueDate, isCompleted) { + if (!dueDate) return ''; + if (isCompleted) { + const info = this.getDueDateInfo(dueDate); + return `${info.label}`; + } + const info = this.getDueDateInfo(dueDate); + return `${info.text}`; + } + + // ─── Animated Counter ─── + + animateCounter(element, from, to, suffix = '%', duration = 400) { + if (from === to) { element.textContent = to + suffix; return; } + const start = performance.now(); + const step = (now) => { + const elapsed = now - start; + const progress = Math.min(elapsed / duration, 1); + // ease out quad + const eased = 1 - (1 - progress) * (1 - progress); + const current = Math.round(from + (to - from) * eased); + element.textContent = current + suffix; + if (progress < 1) requestAnimationFrame(step); + }; + requestAnimationFrame(step); } // ─── View Switching ─── @@ -88,19 +180,12 @@ class App { async switchView(mode) { if (this.viewMode === mode) return; this.viewMode = mode; - document.getElementById('view-active').classList.toggle('active', mode === 'active'); document.getElementById('view-archive').classList.toggle('active', mode === 'archive'); - - // Show/hide elements based on view document.getElementById('overall-progress').classList.toggle('hidden', mode === 'archive'); document.getElementById('open-modal').style.display = mode === 'archive' ? 'none' : ''; - - if (mode === 'archive') { - await this.loadArchivedTasks(); - } else { - await this.loadTasks(); - } + if (mode === 'archive') await this.loadArchivedTasks(); + else await this.loadTasks(); } // ─── Modal ─── @@ -112,6 +197,9 @@ class App { document.getElementById('edit-task-id').value = ''; document.getElementById('edit-parent-id').value = ''; document.getElementById('task-expand-desc').checked = false; + document.getElementById('task-due-date').value = ''; + document.getElementById('task-color').value = '#6366f1'; + this._updateColorDotActive('#6366f1'); this.toggleModal(true); } @@ -125,6 +213,9 @@ class App { document.getElementById('task-size').value = task.size; document.getElementById('task-reward').value = task.reward || ''; document.getElementById('task-expand-desc').checked = !!task.expandDescription; + document.getElementById('task-due-date').value = task.dueDate || ''; + document.getElementById('task-color').value = task.color || '#6366f1'; + this._updateColorDotActive(task.color || '#6366f1'); this.toggleModal(true); } @@ -141,34 +232,22 @@ class App { e.stopPropagation(); const contextMenu = document.getElementById('context-menu'); - const promoteOption = document.getElementById('context-promote'); - const archiveOption = document.getElementById('context-archive'); - const restoreOption = document.getElementById('context-restore'); - this.contextMenuTarget = target; this.contextMenuType = type; this.contextMenuParent = parentTask; - // Show/hide context-specific options - promoteOption.style.display = (type === 'subtask' && this.viewMode === 'active') ? 'flex' : 'none'; - + document.getElementById('context-promote').style.display = (type === 'subtask' && this.viewMode === 'active') ? 'flex' : 'none'; const isCompleted = target.completed || target.calculateProgress() === 100; - archiveOption.style.display = (type === 'task' && this.viewMode === 'active' && isCompleted) ? 'flex' : 'none'; - restoreOption.style.display = (type === 'task' && this.viewMode === 'archive') ? 'flex' : 'none'; - - // Position using clientX/clientY for fixed menu, with viewport clamping - let x = e.clientX; - let y = e.clientY; + document.getElementById('context-archive').style.display = (type === 'task' && this.viewMode === 'active' && isCompleted) ? 'flex' : 'none'; + document.getElementById('context-restore').style.display = (type === 'task' && this.viewMode === 'archive') ? 'flex' : 'none'; + let x = e.clientX, y = e.clientY; contextMenu.style.left = '-9999px'; contextMenu.style.top = '-9999px'; contextMenu.classList.add('show'); - const menuWidth = contextMenu.offsetWidth; - const menuHeight = contextMenu.offsetHeight; - - if (x + menuWidth > window.innerWidth) x = window.innerWidth - menuWidth - 5; - if (y + menuHeight > window.innerHeight) y = window.innerHeight - menuHeight - 5; + if (x + contextMenu.offsetWidth > window.innerWidth) x = window.innerWidth - contextMenu.offsetWidth - 5; + if (y + contextMenu.offsetHeight > window.innerHeight) y = window.innerHeight - contextMenu.offsetHeight - 5; if (x < 0) x = 5; if (y < 0) y = 5; @@ -176,107 +255,60 @@ class App { contextMenu.style.top = y + 'px'; } - hideContextMenu() { - document.getElementById('context-menu').classList.remove('show'); - } + hideContextMenu() { document.getElementById('context-menu').classList.remove('show'); } handleContextEdit() { - if (this.contextMenuTarget) { - this.openEditModal(this.contextMenuTarget, this.contextMenuParent); - } + if (this.contextMenuTarget) this.openEditModal(this.contextMenuTarget, this.contextMenuParent); this.hideContextMenu(); } async handleContextDelete() { if (!this.contextMenuTarget) return; - - const label = this.contextMenuType === 'task' ? 'task' : 'subtask'; - if (!confirm(`Delete this ${label}?`)) { - this.hideContextMenu(); - return; - } - - if (this.contextMenuType === 'task') { - await this.deleteTask(this.contextMenuTarget.id); - } else if (this.contextMenuType === 'subtask' && this.contextMenuParent) { - await this.deleteSubtask(this.contextMenuParent.id, this.contextMenuTarget.id); - } - + if (!confirm(`Delete this ${this.contextMenuType}?`)) { this.hideContextMenu(); return; } + if (this.contextMenuType === 'task') await this.deleteTask(this.contextMenuTarget.id); + else if (this.contextMenuType === 'subtask' && this.contextMenuParent) await this.deleteSubtask(this.contextMenuParent.id, this.contextMenuTarget.id); this.hideContextMenu(); } async handleContextPromote() { - if (!this.contextMenuTarget || this.contextMenuType !== 'subtask' || !this.contextMenuParent) { - this.hideContextMenu(); - return; - } - + if (!this.contextMenuTarget || this.contextMenuType !== 'subtask' || !this.contextMenuParent) { this.hideContextMenu(); return; } const parentTask = this.getCurrentTasks().find(t => t.id === this.contextMenuParent.id); - if (!parentTask) { - this.hideContextMenu(); - return; - } - + if (!parentTask) { this.hideContextMenu(); return; } const subtask = this.contextMenuTarget; parentTask.subtasks = parentTask.subtasks.filter(st => st.id !== subtask.id); - try { - await fetch(`${API_URL}/tasks/${parentTask.id}`, { - method: 'PUT', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(parentTask) - }); - - await fetch(`${API_URL}/tasks`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - title: subtask.title, - description: subtask.description, - size: subtask.size, - reward: subtask.reward - }) - }); - + await fetch(`${API_URL}/tasks/${parentTask.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(parentTask) }); + await fetch(`${API_URL}/tasks`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ title: subtask.title, description: subtask.description, size: subtask.size, reward: subtask.reward, dueDate: subtask.dueDate, color: subtask.color }) }); await this.loadTasks(); - } catch (error) { - console.error('Error promoting subtask:', error); - } - + } catch (error) { console.error('Error promoting subtask:', error); } this.hideContextMenu(); } async handleContextArchive() { - if (!this.contextMenuTarget || this.contextMenuType !== 'task') { - this.hideContextMenu(); - return; - } + if (!this.contextMenuTarget || this.contextMenuType !== 'task') { this.hideContextMenu(); return; } await this.archiveTask(this.contextMenuTarget.id); this.hideContextMenu(); } async handleContextRestore() { - if (!this.contextMenuTarget || this.contextMenuType !== 'task') { - this.hideContextMenu(); - return; - } + if (!this.contextMenuTarget || this.contextMenuType !== 'task') { this.hideContextMenu(); return; } await this.unarchiveTask(this.contextMenuTarget.id); this.hideContextMenu(); } - // ─── Form Submit ─── + // ─── Form ─── async handleSubmit(e) { e.preventDefault(); - const title = document.getElementById('task-title').value.trim(); const description = document.getElementById('task-description').value.trim(); const size = document.getElementById('task-size').value; const reward = document.getElementById('task-reward').value.trim(); const expandDescription = document.getElementById('task-expand-desc').checked; + const dueDate = document.getElementById('task-due-date').value || null; + const color = document.getElementById('task-color').value || '#6366f1'; const editId = document.getElementById('edit-task-id').value; const parentId = document.getElementById('edit-parent-id').value; - const taskList = this.getCurrentTasks(); if (editId) { @@ -285,71 +317,67 @@ class App { if (parentTask) { const subtask = parentTask.subtasks.find(st => st.id === editId); if (subtask) { - subtask.title = title; - subtask.description = description; - subtask.size = size; - subtask.reward = reward; - subtask.expandDescription = expandDescription; + Object.assign(subtask, { title, description, size, reward, expandDescription, dueDate, color }); await this.updateTask(parentTask); } } } else { const task = taskList.find(t => t.id === editId); if (task) { - task.title = title; - task.description = description; - task.size = size; - task.reward = reward; - task.expandDescription = expandDescription; + Object.assign(task, { title, description, size, reward, expandDescription, dueDate, color }); await this.updateTask(task); } } } else { try { const response = await fetch(`${API_URL}/tasks`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ title, description, size, reward, expandDescription }) + method: 'POST', headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ title, description, size, reward, expandDescription, dueDate, color }) }); if (response.ok) await this.loadTasks(); - } catch (error) { - console.error('Error creating task:', error); - } + } catch (error) { console.error('Error creating task:', error); } } e.target.reset(); + document.getElementById('task-color').value = '#6366f1'; + this._updateColorDotActive('#6366f1'); this.toggleModal(false); } - // ─── Data Loading ─── + // ─── Data ─── - getCurrentTasks() { - return this.viewMode === 'archive' ? this.archivedTasks : this.tasks; + getCurrentTasks() { return this.viewMode === 'archive' ? this.archivedTasks : this.tasks; } + + _mapTaskData(taskData) { + const task = new Task(taskData.id, taskData.title, taskData.description, taskData.size, taskData.reward); + task.completed = taskData.completed; + task.expandDescription = !!taskData.expandDescription; + task.dueDate = taskData.dueDate || null; + task.color = taskData.color || '#6366f1'; + if (taskData.subtasks && Array.isArray(taskData.subtasks)) { + task.subtasks = taskData.subtasks.map(stData => { + const st = new Task(stData.id, stData.title, stData.description, stData.size, stData.reward); + st.completed = stData.completed; + st.expandDescription = !!stData.expandDescription; + st.dueDate = stData.dueDate || null; + st.color = stData.color || '#6366f1'; + return st; + }); + } + return task; } async loadTasks() { try { + const prevProgress = this._previousOverallProgress; const response = await fetch(`${API_URL}/tasks`); const data = await response.json(); - - this.tasks = data.map(taskData => { - const task = new Task(taskData.id, taskData.title, taskData.description, taskData.size, taskData.reward); - task.completed = taskData.completed; - task.expandDescription = !!taskData.expandDescription; - if (taskData.subtasks && Array.isArray(taskData.subtasks)) { - task.subtasks = taskData.subtasks.map(stData => { - const subtask = new Task(stData.id, stData.title, stData.description, stData.size, stData.reward); - subtask.completed = stData.completed; - subtask.expandDescription = !!stData.expandDescription; - return subtask; - }); - } - return task; - }); - + this.tasks = data.map(d => this._mapTaskData(d)); this.updateOverallProgress(); if (this.viewMode === 'active') this.render(); this.loadArchivedCount(); + if (this._initialized) this._checkCelebrations(prevProgress); + this._initialized = true; } catch (error) { console.error('Error loading tasks:', error); this.showError(); @@ -360,73 +388,56 @@ class App { try { const response = await fetch(`${API_URL}/tasks?archived=1`); const data = await response.json(); - - this.archivedTasks = data.map(taskData => { - const task = new Task(taskData.id, taskData.title, taskData.description, taskData.size, taskData.reward); - task.completed = taskData.completed; - task.expandDescription = !!taskData.expandDescription; - if (taskData.subtasks && Array.isArray(taskData.subtasks)) { - task.subtasks = taskData.subtasks.map(stData => { - const subtask = new Task(stData.id, stData.title, stData.description, stData.size, stData.reward); - subtask.completed = stData.completed; - subtask.expandDescription = !!stData.expandDescription; - return subtask; - }); - } - return task; - }); - + this.archivedTasks = data.map(d => this._mapTaskData(d)); if (this.viewMode === 'archive') this.renderArchive(); this.updateArchiveCount(); - } catch (error) { - console.error('Error loading archived tasks:', error); - this.showError(); - } + } catch (error) { console.error('Error loading archived tasks:', error); this.showError(); } } async loadArchivedCount() { try { const response = await fetch(`${API_URL}/tasks?archived=1`); const data = await response.json(); - this.archivedTasks = data.map(taskData => { - const task = new Task(taskData.id, taskData.title, taskData.description, taskData.size, taskData.reward); - task.completed = taskData.completed; - return task; - }); + this.archivedTasks = data.map(d => this._mapTaskData(d)); this.updateArchiveCount(); - } catch (error) { - // Silently fail — count is non-critical - } + } catch (error) { /* non-critical */ } } updateArchiveCount() { const badge = document.getElementById('archive-count'); - const count = this.archivedTasks.length; - badge.textContent = count; - badge.style.display = count > 0 ? 'inline-block' : 'none'; + badge.textContent = this.archivedTasks.length; + badge.style.display = this.archivedTasks.length > 0 ? 'inline-block' : 'none'; } updateOverallProgress() { const totalTasks = this.tasks.length; const completedTasks = this.tasks.filter(t => t.calculateProgress() === 100).length; - document.getElementById('completed-count').textContent = completedTasks; + // Animate completed count + const completedEl = document.getElementById('completed-count'); + const prevCompleted = parseInt(completedEl.textContent) || 0; + if (prevCompleted !== completedTasks) this.animateCounter(completedEl, prevCompleted, completedTasks, ''); + else completedEl.textContent = completedTasks; document.getElementById('total-count').textContent = totalTasks; if (totalTasks === 0) { - document.getElementById('overall-percentage').textContent = '0%'; + const pctEl = document.getElementById('overall-percentage'); + pctEl.textContent = '0%'; document.getElementById('overall-progress-fill').style.width = '0%'; + this._previousOverallProgress = 0; return; } const totalWeight = this.tasks.reduce((sum, t) => sum + t.getProgressWeight(), 0); - const completedWeight = this.tasks.reduce((sum, t) => { - const progress = t.calculateProgress(); - return sum + (t.getProgressWeight() * progress / 100); - }, 0); - + const completedWeight = this.tasks.reduce((sum, t) => sum + (t.getProgressWeight() * t.calculateProgress() / 100), 0); const overallProgress = totalWeight > 0 ? Math.round((completedWeight / totalWeight) * 100) : 0; - document.getElementById('overall-percentage').textContent = overallProgress + '%'; + + // Animate percentage + const pctEl = document.getElementById('overall-percentage'); + const prevPct = this._previousOverallProgress; + this.animateCounter(pctEl, prevPct, overallProgress, '%'); + + this._previousOverallProgress = overallProgress; document.getElementById('overall-progress-fill').style.width = overallProgress + '%'; } @@ -439,37 +450,36 @@ class App { if (this.viewMode === 'archive') await this.loadArchivedTasks(); else await this.loadTasks(); } - } catch (error) { - console.error('Error deleting task:', error); - } + } catch (error) { console.error('Error deleting task:', error); } } async toggleTaskComplete(taskId) { const task = this.getCurrentTasks().find(t => t.id === taskId); if (!task) return; - + const wasCompleted = task.completed || task.calculateProgress() === 100; task.completed = !task.completed; - if (task.subtasks.length > 0) { - task.subtasks.forEach(st => st.completed = task.completed); - } + if (task.subtasks.length > 0) task.subtasks.forEach(st => st.completed = task.completed); + const isNowCompleted = task.completed || task.calculateProgress() === 100; + if (!wasCompleted && isNowCompleted && task.reward) this._celebrateTaskId = taskId; await this.updateTask(task); } async toggleSubtaskComplete(taskId, subtaskId) { const task = this.getCurrentTasks().find(t => t.id === taskId); if (!task) return; - const subtask = task.subtasks.find(st => st.id === subtaskId); if (!subtask) return; - + const wasSubCompleted = subtask.completed; subtask.completed = !subtask.completed; + if (!wasSubCompleted && subtask.completed && subtask.reward) this._celebrateTaskId = taskId; + const parentWillComplete = task.calculateProgress() === 100; + if (parentWillComplete && task.reward && !task.completed) this._celebrateTaskId = taskId; await this.updateTask(task); } async deleteSubtask(taskId, subtaskId) { const task = this.getCurrentTasks().find(t => t.id === taskId); if (!task) return; - task.subtasks = task.subtasks.filter(st => st.id !== subtaskId); await this.updateTask(task); } @@ -477,57 +487,54 @@ class App { async updateTask(task) { try { const response = await fetch(`${API_URL}/tasks/${task.id}`, { - method: 'PUT', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(task) + method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(task) }); if (response.ok) { if (this.viewMode === 'archive') await this.loadArchivedTasks(); else await this.loadTasks(); } - } catch (error) { - console.error('Error updating task:', error); - } + } catch (error) { console.error('Error updating task:', error); } } async archiveTask(taskId) { try { const response = await fetch(`${API_URL}/tasks/${taskId}/archive`, { method: 'PUT' }); - if (response.ok) { - await this.loadTasks(); - await this.loadArchivedCount(); - } - } catch (error) { - console.error('Error archiving task:', error); - } + if (response.ok) { await this.loadTasks(); await this.loadArchivedCount(); } + } catch (error) { console.error('Error archiving task:', error); } } async unarchiveTask(taskId) { try { const response = await fetch(`${API_URL}/tasks/${taskId}/unarchive`, { method: 'PUT' }); - if (response.ok) { - await this.loadArchivedTasks(); - await this.loadTasks(); - } - } catch (error) { - console.error('Error restoring task:', error); + if (response.ok) { await this.loadArchivedTasks(); await this.loadTasks(); } + } catch (error) { console.error('Error restoring task:', error); } + } + + // ─── Collapse / Expand ─── + + toggleCollapse(taskId) { + if (this._collapsedTasks.has(taskId)) this._collapsedTasks.delete(taskId); + else this._collapsedTasks.add(taskId); + localStorage.setItem('collapsedTasks', JSON.stringify([...this._collapsedTasks])); + // Toggle inline without full re-render + const card = document.querySelector(`[data-task-id="${taskId}"]`); + if (!card) return; + const container = card.querySelector('.subtasks-container'); + const toggle = card.querySelector('.subtask-toggle'); + if (container) container.classList.toggle('collapsed'); + if (toggle) { + toggle.classList.toggle('collapsed'); + const count = toggle.dataset.count; + const isCollapsed = toggle.classList.contains('collapsed'); + toggle.querySelector('.toggle-label').textContent = isCollapsed ? `Show ${count} subtask${count > 1 ? 's' : ''}` : 'Hide subtasks'; } } // ─── Drag & Drop ─── handleDragStart(e, item, isSubtask = false, parentTask = null, index = null) { - if (isSubtask) { - this.draggedSubtask = item; - this.draggedParent = parentTask; - this.draggedSubtaskIndex = index; - this.draggedTask = null; - } else { - this.draggedTask = item; - this.draggedSubtask = null; - this.draggedParent = null; - this.draggedSubtaskIndex = null; - } + if (isSubtask) { this.draggedSubtask = item; this.draggedParent = parentTask; this.draggedSubtaskIndex = index; this.draggedTask = null; } + else { this.draggedTask = item; this.draggedSubtask = null; this.draggedParent = null; this.draggedSubtaskIndex = null; } e.currentTarget.classList.add('dragging'); } @@ -535,144 +542,82 @@ class App { e.currentTarget.classList.remove('dragging'); document.querySelectorAll('.drag-over').forEach(el => el.classList.remove('drag-over')); document.querySelectorAll('.drop-zone').forEach(el => el.classList.remove('visible')); - - if (this.dropZoneTimer) { - clearTimeout(this.dropZoneTimer); - this.dropZoneTimer = null; - } - - this.draggedTask = null; - this.draggedSubtask = null; - this.draggedParent = null; - this.draggedSubtaskIndex = null; + if (this.dropZoneTimer) { clearTimeout(this.dropZoneTimer); this.dropZoneTimer = null; } + this.draggedTask = null; this.draggedSubtask = null; this.draggedParent = null; this.draggedSubtaskIndex = null; } - handleCardDragOver(e) { - e.preventDefault(); - e.stopPropagation(); - e.currentTarget.classList.add('drag-over'); - } - - handleDragLeave(e) { - e.currentTarget.classList.remove('drag-over'); - } + handleCardDragOver(e) { e.preventDefault(); e.stopPropagation(); e.currentTarget.classList.add('drag-over'); } + handleDragLeave(e) { e.currentTarget.classList.remove('drag-over'); } handleDragEnter(e, taskId) { e.preventDefault(); if (!this.draggedTask && !this.draggedSubtask) return; if (this.dropZoneTimer) clearTimeout(this.dropZoneTimer); - this.dropZoneTimer = setTimeout(() => { const dropZone = document.querySelector(`[data-task-id="${taskId}"] .drop-zone`); - if (dropZone && (this.draggedTask || this.draggedSubtask)) { - dropZone.classList.add('visible'); - } + if (dropZone && (this.draggedTask || this.draggedSubtask)) dropZone.classList.add('visible'); }, 1000); } async handleDrop(e, targetTask) { - e.preventDefault(); - e.stopPropagation(); - e.currentTarget.classList.remove('drag-over'); - + e.preventDefault(); e.stopPropagation(); e.currentTarget.classList.remove('drag-over'); if (this.draggedTask && this.draggedTask.id !== targetTask.id) { targetTask.subtasks.push(this.draggedTask); - try { - await fetch(`${API_URL}/tasks/${this.draggedTask.id}`, { method: 'DELETE' }); - await this.updateTask(targetTask); - } catch (error) { - console.error('Error moving task:', error); - } + try { await fetch(`${API_URL}/tasks/${this.draggedTask.id}`, { method: 'DELETE' }); await this.updateTask(targetTask); } + catch (error) { console.error('Error moving task:', error); } } else if (this.draggedSubtask && this.draggedParent && targetTask.id !== this.draggedParent.id) { this.draggedParent.subtasks = this.draggedParent.subtasks.filter(st => st.id !== this.draggedSubtask.id); targetTask.subtasks.push(this.draggedSubtask); - try { - await this.updateTask(this.draggedParent); - await this.updateTask(targetTask); - } catch (error) { - console.error('Error moving subtask:', error); - } + try { await this.updateTask(this.draggedParent); await this.updateTask(targetTask); } + catch (error) { console.error('Error moving subtask:', error); } } } async handleTaskReorder(e, targetIndex) { - e.preventDefault(); - e.stopPropagation(); - e.currentTarget.classList.remove('drag-over'); - + e.preventDefault(); e.stopPropagation(); e.currentTarget.classList.remove('drag-over'); if (!this.draggedTask) return; - const currentIndex = this.tasks.findIndex(t => t.id === this.draggedTask.id); if (currentIndex === -1 || currentIndex === targetIndex) return; - this.tasks.splice(currentIndex, 1); this.tasks.splice(targetIndex, 0, this.draggedTask); - try { - await fetch(`${API_URL}/tasks/reorder`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(this.tasks.map(t => t.id)) - }); + await fetch(`${API_URL}/tasks/reorder`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(this.tasks.map(t => t.id)) }); this.render(); - } catch (error) { - console.error('Error reordering:', error); - await this.loadTasks(); - } + } catch (error) { console.error('Error reordering:', error); await this.loadTasks(); } } async handleSubtaskReorder(e, parentTask, targetIndex) { - e.preventDefault(); - e.stopPropagation(); - e.currentTarget.classList.remove('drag-over'); - - if (!this.draggedSubtask || !this.draggedParent) return; - if (this.draggedParent.id !== parentTask.id) return; + e.preventDefault(); e.stopPropagation(); e.currentTarget.classList.remove('drag-over'); + if (!this.draggedSubtask || !this.draggedParent || this.draggedParent.id !== parentTask.id) return; if (this.draggedSubtaskIndex === targetIndex) return; - - const currentIndex = this.draggedSubtaskIndex; - const subtask = parentTask.subtasks[currentIndex]; - - parentTask.subtasks.splice(currentIndex, 1); + const subtask = parentTask.subtasks[this.draggedSubtaskIndex]; + parentTask.subtasks.splice(this.draggedSubtaskIndex, 1); parentTask.subtasks.splice(targetIndex, 0, subtask); - await this.updateTask(parentTask); } - // ─── Render: Active Tasks ─── + // ─── Render: Active ─── renderTask(task, index) { const progress = task.calculateProgress(); const isCompleted = progress === 100 || task.completed; - const card = document.createElement('div'); card.className = `task-card ${isCompleted ? 'completed' : ''}`; card.draggable = true; card.setAttribute('data-task-id', task.id); + card.style.borderLeftColor = task.color || '#6366f1'; - // Drag events card.addEventListener('dragstart', (e) => this.handleDragStart(e, task, false)); card.addEventListener('dragend', (e) => this.handleDragEnd(e)); card.addEventListener('dragover', (e) => this.handleCardDragOver(e)); card.addEventListener('dragleave', (e) => this.handleDragLeave(e)); card.addEventListener('dragenter', (e) => this.handleDragEnter(e, task.id)); card.addEventListener('drop', (e) => { - if (e.target.closest('.drop-zone')) { - this.handleDrop(e, task); - } else if (this.draggedTask && this.draggedTask.id !== task.id) { - this.handleTaskReorder(e, index); - } - }); - card.addEventListener('contextmenu', (e) => { - if (!e.target.closest('.subtask')) { - this.showContextMenu(e, task, 'task'); - } - }); - card.addEventListener('dblclick', (e) => { - if (!e.target.closest('.subtask') && !e.target.closest('button')) { - this.openEditModal(task); - } + if (e.target.closest('.drop-zone')) this.handleDrop(e, task); + else if (this.draggedTask && this.draggedTask.id !== task.id) this.handleTaskReorder(e, index); }); + card.addEventListener('contextmenu', (e) => { if (!e.target.closest('.subtask')) this.showContextMenu(e, task, 'task'); }); + card.addEventListener('dblclick', (e) => { if (!e.target.closest('.subtask') && !e.target.closest('button')) this.openEditModal(task); }); const descClass = task.expandDescription ? 'task-description expanded' : 'task-description'; @@ -680,14 +625,13 @@ class App {
${this.escapeHtml(task.title)}
+ ${this.renderDueBadge(task.dueDate, isCompleted)}
${task.size}
${task.description ? `
${this.escapeHtml(task.description)}
` : ''}
-
-
-
+
${progress}%
${task.reward ? ` @@ -707,12 +651,23 @@ class App { `; - // Append subtasks as DOM nodes to preserve event listeners + // Subtasks with collapse toggle if (task.subtasks.length > 0) { - card.appendChild(this.renderSubtasks(task)); + const isCollapsed = this._collapsedTasks.has(task.id); + const count = task.subtasks.length; + + const toggleBtn = document.createElement('button'); + toggleBtn.className = `subtask-toggle ${isCollapsed ? 'collapsed' : ''}`; + toggleBtn.dataset.count = count; + toggleBtn.innerHTML = `▼ ${isCollapsed ? `Show ${count} subtask${count > 1 ? 's' : ''}` : 'Hide subtasks'}`; + toggleBtn.addEventListener('click', (e) => { e.stopPropagation(); this.toggleCollapse(task.id); }); + card.appendChild(toggleBtn); + + const subtasksEl = this.renderSubtasks(task); + if (isCollapsed) subtasksEl.classList.add('collapsed'); + card.appendChild(subtasksEl); } - // Drop zone const dropZone = document.createElement('div'); dropZone.className = 'drop-zone'; dropZone.textContent = 'Drop tasks here to add as subtasks'; @@ -731,59 +686,36 @@ class App { div.draggable = true; div.setAttribute('data-subtask-id', subtask.id); - div.addEventListener('dragstart', (e) => { - e.stopPropagation(); - this.handleDragStart(e, subtask, true, task, index); - }); - div.addEventListener('dragend', (e) => { - e.stopPropagation(); - this.handleDragEnd(e); - }); + div.addEventListener('dragstart', (e) => { e.stopPropagation(); this.handleDragStart(e, subtask, true, task, index); }); + div.addEventListener('dragend', (e) => { e.stopPropagation(); this.handleDragEnd(e); }); div.addEventListener('dragover', (e) => { - e.preventDefault(); - e.stopPropagation(); - if (this.draggedSubtask && this.draggedParent && this.draggedParent.id === task.id) { - e.currentTarget.classList.add('drag-over'); - } - }); - div.addEventListener('dragleave', (e) => { - e.stopPropagation(); - e.currentTarget.classList.remove('drag-over'); - }); - div.addEventListener('drop', (e) => { - e.stopPropagation(); - this.handleSubtaskReorder(e, task, index); - }); - div.addEventListener('contextmenu', (e) => { - e.stopPropagation(); - this.showContextMenu(e, subtask, 'subtask', task); - }); - div.addEventListener('dblclick', (e) => { - e.stopPropagation(); - if (!e.target.closest('button')) { - this.openEditModal(subtask, task); - } + e.preventDefault(); e.stopPropagation(); + if (this.draggedSubtask && this.draggedParent && this.draggedParent.id === task.id) e.currentTarget.classList.add('drag-over'); }); + div.addEventListener('dragleave', (e) => { e.stopPropagation(); e.currentTarget.classList.remove('drag-over'); }); + div.addEventListener('drop', (e) => { e.stopPropagation(); this.handleSubtaskReorder(e, task, index); }); + div.addEventListener('contextmenu', (e) => { e.stopPropagation(); this.showContextMenu(e, subtask, 'subtask', task); }); + div.addEventListener('dblclick', (e) => { e.stopPropagation(); if (!e.target.closest('button')) this.openEditModal(subtask, task); }); const progress = subtask.calculateProgress(); + const stIsCompleted = subtask.completed || progress === 100; const stDescClass = subtask.expandDescription ? 'task-description expanded' : 'task-description'; div.innerHTML = `
${this.escapeHtml(subtask.title)}
+ ${this.renderDueBadge(subtask.dueDate, stIsCompleted)}
${subtask.size}
${subtask.description ? `
${this.escapeHtml(subtask.description)}
` : ''}
-
-
-
+
${progress}%
${subtask.reward ? `
🎁 - ${subtask.completed + ${stIsCompleted ? `${this.escapeHtml(subtask.reward)}` : `Complete to reveal` } @@ -795,7 +727,6 @@ class App {
`; - container.appendChild(div); }); @@ -805,42 +736,25 @@ class App { render() { const container = document.getElementById('tasks-container'); container.innerHTML = ''; - if (this.tasks.length === 0) { - container.innerHTML = ` -
-

No goals yet

-

Click "+ New Goal" to get started

-
- `; + container.innerHTML = `

No goals yet

Click "+ New Goal" to get started

`; return; } - - this.tasks.forEach((task, index) => { - container.appendChild(this.renderTask(task, index)); - }); + this.tasks.forEach((task, index) => container.appendChild(this.renderTask(task, index))); } - // ─── Render: Archive View ─── + // ─── Render: Archive ─── renderArchivedTask(task) { const progress = task.calculateProgress(); const isCompleted = progress === 100 || task.completed; - const card = document.createElement('div'); card.className = `task-card archived-card ${isCompleted ? 'completed' : ''}`; card.setAttribute('data-task-id', task.id); + card.style.borderLeftColor = task.color || '#6366f1'; - card.addEventListener('contextmenu', (e) => { - if (!e.target.closest('.subtask')) { - this.showContextMenu(e, task, 'task'); - } - }); - card.addEventListener('dblclick', (e) => { - if (!e.target.closest('.subtask') && !e.target.closest('button')) { - this.openEditModal(task); - } - }); + card.addEventListener('contextmenu', (e) => { if (!e.target.closest('.subtask')) this.showContextMenu(e, task, 'task'); }); + card.addEventListener('dblclick', (e) => { if (!e.target.closest('.subtask') && !e.target.closest('button')) this.openEditModal(task); }); const descClass = task.expandDescription ? 'task-description expanded' : 'task-description'; @@ -848,14 +762,13 @@ class App {
${this.escapeHtml(task.title)}
+ ${this.renderDueBadge(task.dueDate, isCompleted)}
${task.size}
${task.description ? `
${this.escapeHtml(task.description)}
` : ''}
-
-
-
+
${progress}%
${task.reward ? ` @@ -873,95 +786,138 @@ class App { `; - // Subtasks (read-only, no drag) - if (task.subtasks.length > 0) { - card.appendChild(this.renderArchivedSubtasks(task)); - } - + if (task.subtasks.length > 0) card.appendChild(this.renderArchivedSubtasks(task)); return card; } renderArchivedSubtasks(task) { const container = document.createElement('div'); container.className = 'subtasks-container'; - task.subtasks.forEach((subtask) => { const div = document.createElement('div'); div.className = 'subtask'; div.style.cursor = 'default'; - - div.addEventListener('contextmenu', (e) => { - e.stopPropagation(); - this.showContextMenu(e, subtask, 'subtask', task); - }); - div.addEventListener('dblclick', (e) => { - e.stopPropagation(); - if (!e.target.closest('button')) { - this.openEditModal(subtask, task); - } - }); - + div.addEventListener('contextmenu', (e) => { e.stopPropagation(); this.showContextMenu(e, subtask, 'subtask', task); }); + div.addEventListener('dblclick', (e) => { e.stopPropagation(); if (!e.target.closest('button')) this.openEditModal(subtask, task); }); const progress = subtask.calculateProgress(); + const stIsCompleted = subtask.completed || progress === 100; const stDescClass = subtask.expandDescription ? 'task-description expanded' : 'task-description'; - div.innerHTML = `
${this.escapeHtml(subtask.title)}
+ ${this.renderDueBadge(subtask.dueDate, stIsCompleted)}
${subtask.size}
${subtask.description ? `
${this.escapeHtml(subtask.description)}
` : ''}
-
-
-
+
${progress}%
${subtask.reward ? `
🎁 - ${subtask.completed + ${stIsCompleted ? `${this.escapeHtml(subtask.reward)}` : `Complete to reveal` }
` : ''} `; - container.appendChild(div); }); - return container; } renderArchive() { const container = document.getElementById('tasks-container'); container.innerHTML = ''; - if (this.archivedTasks.length === 0) { - container.innerHTML = ` -
-

Archive is empty

-

Completed tasks you archive will appear here

-
- `; + container.innerHTML = `

Archive is empty

Completed tasks you archive will appear here

`; return; } + this.archivedTasks.forEach(task => container.appendChild(this.renderArchivedTask(task))); + } - this.archivedTasks.forEach(task => { - container.appendChild(this.renderArchivedTask(task)); - }); + // ─── Celebrations ─── + + _checkCelebrations(prevProgress) { + if (this._celebrateTaskId) { + const card = document.querySelector(`[data-task-id="${this._celebrateTaskId}"]`); + if (card) { + card.classList.add('just-completed'); + const rect = card.getBoundingClientRect(); + this.fireConfetti((rect.left + rect.width / 2) / window.innerWidth, (rect.top + rect.height / 2) / window.innerHeight, 35); + setTimeout(() => card.classList.remove('just-completed'), 700); + } + this._celebrateTaskId = null; + } + if (this.tasks.length > 0 && this._previousOverallProgress === 100 && prevProgress < 100) { + this.fireBigCelebration(); + } + } + + fireBigCelebration() { + this.fireConfetti(0.5, 0.4, 80); + setTimeout(() => this.fireConfetti(0.25, 0.5, 50), 300); + setTimeout(() => this.fireConfetti(0.75, 0.5, 50), 600); + const overlay = document.createElement('div'); + overlay.className = 'celebration-overlay'; + overlay.innerHTML = '
All Goals Complete!
'; + document.body.appendChild(overlay); + setTimeout(() => overlay.remove(), 3200); + } + + fireConfetti(originX = 0.5, originY = 0.5, count = 50) { + const canvas = document.createElement('canvas'); + canvas.className = 'confetti-canvas'; + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; + document.body.appendChild(canvas); + const ctx = canvas.getContext('2d'); + const colors = ['#6366f1', '#a78bfa', '#f59e0b', '#10b981', '#f43f5e', '#0ea5e9', '#ec4899', '#8b5cf6']; + const particles = []; + for (let i = 0; i < count; i++) { + const angle = Math.random() * Math.PI * 2; + const speed = 4 + Math.random() * 8; + particles.push({ + x: originX * canvas.width, y: originY * canvas.height, + vx: Math.cos(angle) * speed * (0.6 + Math.random() * 0.8), + vy: Math.sin(angle) * speed * (0.6 + Math.random() * 0.8) - 3, + color: colors[Math.floor(Math.random() * colors.length)], + size: 3 + Math.random() * 5, rotation: Math.random() * 360, + rotationSpeed: (Math.random() - 0.5) * 12, life: 1, + decay: 0.008 + Math.random() * 0.012, + shape: Math.random() > 0.5 ? 'rect' : 'circle' + }); + } + let frame; + const animate = () => { + ctx.clearRect(0, 0, canvas.width, canvas.height); + let alive = false; + for (const p of particles) { + if (p.life <= 0) continue; + alive = true; + p.x += p.vx; p.y += p.vy; p.vy += 0.18; p.vx *= 0.99; + p.rotation += p.rotationSpeed; p.life -= p.decay; + ctx.save(); + ctx.translate(p.x, p.y); + ctx.rotate(p.rotation * Math.PI / 180); + ctx.globalAlpha = Math.max(0, p.life); + ctx.fillStyle = p.color; + if (p.shape === 'rect') ctx.fillRect(-p.size / 2, -p.size / 2, p.size, p.size * 0.6); + else { ctx.beginPath(); ctx.arc(0, 0, p.size / 2, 0, Math.PI * 2); ctx.fill(); } + ctx.restore(); + } + if (alive) frame = requestAnimationFrame(animate); + else { cancelAnimationFrame(frame); canvas.remove(); } + }; + animate(); } // ─── Utility ─── showError() { - const container = document.getElementById('tasks-container'); - container.innerHTML = ` -
-

Connection Error

-

Cannot connect to server

-
- `; + document.getElementById('tasks-container').innerHTML = `

Connection Error

Cannot connect to server

`; } escapeHtml(text) { diff --git a/public/img/background.jpg b/public/img/background.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f5f6f72bf3b82114927e30182382d311c7f538d1 GIT binary patch literal 49394 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 LQ$I1C!*~DLDo*h8 literal 0 HcmV?d00001 diff --git a/public/index.html b/public/index.html index faea51f..a816fac 100644 --- a/public/index.html +++ b/public/index.html @@ -16,7 +16,7 @@
🗑 Delete
- +