From d7cb00171c12834efdf6cef8b243a0ea47b0e638 Mon Sep 17 00:00:00 2001 From: kRyxar87t Date: Wed, 1 Jul 2026 23:09:40 +0530 Subject: [PATCH 1/2] feat: add manual task entry shortcut to Smart Paste workflow --- index.html | 1 + js/app.js | 7 +++++++ package-lock.json | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index 8fe1303d..653650e6 100644 --- a/index.html +++ b/index.html @@ -342,6 +342,7 @@

Account overview

+
diff --git a/js/app.js b/js/app.js index 6842db4e..53b36777 100644 --- a/js/app.js +++ b/js/app.js @@ -98,6 +98,7 @@ const addItemsBtn = document.getElementById('add-btn'); const downloadBtn = document.getElementById('download-btn'); const calendarDownloadBtn = document.getElementById('calendar-download-btn'); const newTaskBtn = document.getElementById('add-task-btn'); +const manualTaskBtn = document.getElementById('manual-task-btn'); const labelFilterSelect = document.getElementById('label-filter'); const profileSection = document.getElementById('profile-section'); const profileBtn = document.getElementById('profile-btn'); @@ -1837,6 +1838,12 @@ newTaskBtn.addEventListener('click', () => { newTaskModal.style.display = 'flex'; }); +if (manualTaskBtn && newTaskBtn) { + manualTaskBtn.addEventListener('click', () => { + newTaskBtn.click(); + }); +} + newTaskCancel.addEventListener('click', () => { newTaskModal.style.display = 'none'; }); diff --git a/package-lock.json b/package-lock.json index 56528823..e9685a4e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "sqlite3": "^6.0.1" }, "engines": { - "node": "20.x" + "node": ">=20.x" } }, "node_modules/@google/genai": { From 99ec515879e9d1fa8a1b237a1a871d9e9f13fdc4 Mon Sep 17 00:00:00 2001 From: kRyxar87t Date: Wed, 1 Jul 2026 23:36:00 +0530 Subject: [PATCH 2/2] feat: add manual task entry fallback for AI extraction --- index.html | 26 ++++++++++++++++++- js/app.js | 72 +++++++++++++++++++++++++++++++++++++++++++++++------ js/store.js | 4 ++- 3 files changed, 93 insertions(+), 9 deletions(-) diff --git a/index.html b/index.html index 653650e6..7a0fdb21 100644 --- a/index.html +++ b/index.html @@ -342,10 +342,34 @@

Account overview

-
+
+
+
Manual Task Entry
+
Use this form when AI extraction isn't needed.
+
+ + + + + + + + + + + + + +
+ +
+
+
diff --git a/js/app.js b/js/app.js index 53b36777..92fff46f 100644 --- a/js/app.js +++ b/js/app.js @@ -98,7 +98,6 @@ const addItemsBtn = document.getElementById('add-btn'); const downloadBtn = document.getElementById('download-btn'); const calendarDownloadBtn = document.getElementById('calendar-download-btn'); const newTaskBtn = document.getElementById('add-task-btn'); -const manualTaskBtn = document.getElementById('manual-task-btn'); const labelFilterSelect = document.getElementById('label-filter'); const profileSection = document.getElementById('profile-section'); const profileBtn = document.getElementById('profile-btn'); @@ -358,8 +357,29 @@ const newTaskEstimatedDuration = document.getElementById('new-task-estimated-dur const newTaskDurationSwitch = document.getElementById('new-task-duration-switch'); const newTaskDurationMin = document.getElementById('new-task-duration-min'); const newTaskDurationHr = document.getElementById('new-task-duration-hr'); +const manualTaskSubject = document.getElementById('manual-task-subject'); +const manualTaskTitle = document.getElementById('manual-task-title'); +const manualTaskDate = document.getElementById('manual-task-date'); +const manualTaskNotes = document.getElementById('manual-task-notes'); +const manualTaskSubmit = document.getElementById('manual-task-submit'); let selectedTaskDurationUnit = 'minutes'; +function renderManualTaskSubjects() { + if (!manualTaskSubject) return; + + manualTaskSubject.innerHTML = ` + + ${store.subjects.map(s => ``).join('')} + `; +} + +function clearManualTaskForm() { + if (manualTaskSubject) manualTaskSubject.value = ''; + if (manualTaskTitle) manualTaskTitle.value = ''; + if (manualTaskDate) manualTaskDate.value = ''; + if (manualTaskNotes) manualTaskNotes.value = ''; +} + // Timer elements const timerText = document.getElementById('timer-text'); const timerPathRemaining = document.getElementById('timer-path-remaining'); @@ -1648,6 +1668,7 @@ store.subscribe(renderFocusTasks); store.subscribe(renderProfileSection); store.subscribe(renderSidebarSubjects); store.subscribe(renderStreak); +store.subscribe(renderManualTaskSubjects); document.addEventListener('DOMContentLoaded', () => { if (newSubjectColorsEl) { @@ -1838,12 +1859,6 @@ newTaskBtn.addEventListener('click', () => { newTaskModal.style.display = 'flex'; }); -if (manualTaskBtn && newTaskBtn) { - manualTaskBtn.addEventListener('click', () => { - newTaskBtn.click(); - }); -} - newTaskCancel.addEventListener('click', () => { newTaskModal.style.display = 'none'; }); @@ -1853,6 +1868,49 @@ newTaskModal.addEventListener('click', (e) => { newTaskModal.style.display = 'none'; } }); + +manualTaskSubmit?.addEventListener('click', async () => { + if (!manualTaskSubject || !manualTaskTitle || !manualTaskDate) return; + + const subject_id = manualTaskSubject.value; + const rawTitle = manualTaskTitle.value.trim(); + const dueDateValue = manualTaskDate.value; + const notes = manualTaskNotes ? manualTaskNotes.value.trim() : ''; + + if (!subject_id) { + Toast.show('Please select a subject', 'warning'); + return; + } + + if (!rawTitle) { + Toast.show('Please enter a task title', 'warning'); + return; + } + + if (!dueDateValue) { + Toast.show('Please select a due date', 'warning'); + return; + } + + const due_at = new Date(dueDateValue).toISOString(); + const { cleanTitle, labels } = extractLabels(rawTitle); + + const manualTask = { + title: cleanTitle || rawTitle, + subject_id, + due_at, + notes, + priority: 'medium', + status: 'Not Started', + archived: 0, + labels + }; + + const result = await store.addTasks([manualTask]); + if (result && result.inserted > 0) { + clearManualTaskForm(); + } +}); function setNewTaskDurationUnit(unit) { selectedTaskDurationUnit = unit; diff --git a/js/store.js b/js/store.js index 075bc62b..b72beaa6 100644 --- a/js/store.js +++ b/js/store.js @@ -125,7 +125,7 @@ export const store = { // Backend error Toast.show(`❌ ${data.message || "Failed to add tasks"}`, 'error'); console.error('Add task error:', data); - return; + return data; } // ================= USER MESSAGES ================= @@ -151,9 +151,11 @@ export const store = { this.tasks = await tasksRes.json(); this.notify(); + return data; } catch (e) { console.error('Failed to add tasks', e); Toast.show("❌ Network error. Please try again.", 'error'); + return null; } },