From 18eab022f523f941745a31f59ec545a4fd9c5682 Mon Sep 17 00:00:00 2001 From: Prashant Parmar Date: Tue, 19 May 2026 12:57:51 +0530 Subject: [PATCH 1/3] fix: resolve syntax errors and production issues - Fix missing closing brace in DOMContentLoaded - Fix signup endpoint to return email - Remove duplicate CSS rules - Fix indentation consistency - Fix string concatenation error --- css/index.css | 2 -- js/app.js | 39 +++++++++++++++------------------------ package-lock.json | 13 ------------- server.js | 2 +- 4 files changed, 16 insertions(+), 40 deletions(-) diff --git a/css/index.css b/css/index.css index 24a20f7..1721320 100644 --- a/css/index.css +++ b/css/index.css @@ -794,8 +794,6 @@ body { #new-subject-modal .subject-color-swatch--selected { box-shadow: 0 0 0 2px #0f172a, 0 0 0 4px #a5b4fc; } -/* css/index.css */ -*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } :root { --color-background-primary: #ffffff; diff --git a/js/app.js b/js/app.js index 9bfd993..67523a4 100644 --- a/js/app.js +++ b/js/app.js @@ -562,7 +562,7 @@ function renderTasks() { : ''; tasksSection.innerHTML = actionBar + - renderGroup(titlePrefix + '⚠ Due soon', dueSoon, 'var(--color-text-danger)', true) + renderGroup(titlePrefix + '⚠ Due soon', dueSoon, 'var(--color-text-danger)', true) + renderGroup(titlePrefix + 'This week', thisWeek, 'var(--color-text-secondary)', true) + renderGroup(titlePrefix + 'Completed', completed, 'var(--color-text-tertiary)') + emptyState; @@ -971,9 +971,8 @@ document.addEventListener('DOMContentLoaded', () => { renderCalendar(); }); - -//NEw Task addition event listeners -newTaskBtn.addEventListener('click', () => { + // New Task addition event listeners + newTaskBtn.addEventListener('click', () => { if (!store.subjects || store.subjects.length === 0) { alert('Subjects are still loading. Please try again in a moment.'); @@ -1036,15 +1035,6 @@ newTaskSave.addEventListener('click', async () => { newTaskModal.style.display = 'none'; }); -addItemsBtn.addEventListener('click', () => { - if (store.currentPaste) { - store.addTasks(store.currentPaste); - store.clearExtracted(); - pasteInput.value = ''; - } -}); -}); - extractBtn.addEventListener('click', async () => { const text = pasteInput.value; if (!text.trim()) return; @@ -1060,19 +1050,20 @@ extractBtn.addEventListener('click', async () => { store.setExtracted(items); }); -clearBtn.addEventListener('click', () => { - pasteInput.value = ''; - store.clearExtracted(); -}); - -addItemsBtn.addEventListener('click', () => { - if (store.currentPaste) { - store.addTasks(store.currentPaste); - store.clearExtracted(); + clearBtn.addEventListener('click', () => { pasteInput.value = ''; - } -}); + store.clearExtracted(); + }); + + addItemsBtn.addEventListener('click', () => { + if (store.currentPaste) { + store.addTasks(store.currentPaste); + store.clearExtracted(); + pasteInput.value = ''; + } + }); downloadBtn.addEventListener('click', () => { downloadData(); }); +}); // Close DOMContentLoaded event listener \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index d4124c7..bdeb26a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1312,19 +1312,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/prebuild-install": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", diff --git a/server.js b/server.js index 877f766..9374ec8 100644 --- a/server.js +++ b/server.js @@ -456,7 +456,7 @@ app.post('/api/auth/signup', (req, res) => { return res.status(400).json({ error: 'User already exists' }); } users[email] = { email, password }; - res.json({ success: true, message: 'Account created successfully' }); + res.json({ success: true, email: email, message: 'Account created successfully' }); }); app.post('/api/auth/login', (req, res) => { From a12d029d2dd1ad9e681db5871eea784bf8486584 Mon Sep 17 00:00:00 2001 From: Prashant Parmar Date: Tue, 19 May 2026 13:28:44 +0530 Subject: [PATCH 2/3] fix: improve CSV export reliability and correct Gemini model name --- README.md | 5 +++++ backend/controllers/csvDownload.controller.js | 4 ++-- server.js | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7103879..8703939 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,11 @@ Planner + Calendar Update - SQLite-based local database - Structured task + subject mapping +### 📥 Data Export +- Export your study plan to CSV +- Includes task details, subjects, and deadlines +- Compatible with Excel, Google Sheets, and other tools + --- ## 🧠 System Architecture diff --git a/backend/controllers/csvDownload.controller.js b/backend/controllers/csvDownload.controller.js index 5ad0b63..54f30d9 100644 --- a/backend/controllers/csvDownload.controller.js +++ b/backend/controllers/csvDownload.controller.js @@ -34,8 +34,8 @@ async function downloadData(req, res) { task.status, task.priority, task.confidence_score, - `"${(task.notes || '').replace(/"/g, '""')}"` - ]) + task.notes || '' + ].map(val => `"${String(val).replace(/"/g, '""')}"`)) ]; const csvString = rows.map(row => row.join(',')).join('\n'); diff --git a/server.js b/server.js index 9374ec8..72a5cc5 100644 --- a/server.js +++ b/server.js @@ -425,7 +425,7 @@ Each object must have: title (string), subject_name (string), due_at (ISO 8601 d Text: "${text}" `; const response = await ai.models.generateContent({ - model: 'gemini-2.5-flash', + model: 'gemini-1.5-flash', contents: prompt }); From 552b26d4f47272a4a65c45b1d18033cc6037fbb3 Mon Sep 17 00:00:00 2001 From: Prashant Parmar Date: Tue, 19 May 2026 20:35:32 +0530 Subject: [PATCH 3/3] fix: ensure progress tracker updates instantly when tasks are completed --- js/app.js | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/js/app.js b/js/app.js index 67523a4..8b83c36 100644 --- a/js/app.js +++ b/js/app.js @@ -14,8 +14,14 @@ function generateSummary(tasks, subjects) { let weekCount = 0; let subjectCount = {}; - tasks.forEach(t => { - if (t.archived || t.status === 'Done' || !t.due_at) return; + // Progress calculation + const activeTasks = tasks.filter(t => !t.archived); + const totalActive = activeTasks.length; + const completedTasks = activeTasks.filter(t => t.status === 'Done').length; + const completionPercentage = totalActive > 0 ? Math.round((completedTasks / totalActive) * 100) : 0; + + activeTasks.forEach(t => { + if (t.status === 'Done' || !t.due_at) return; const d = new Date(t.due_at); @@ -41,6 +47,14 @@ function generateSummary(tasks, subjects) { : 'no specific subject'; return ` + 📊 Overall Progress
+
+
+
+
+ ${completionPercentage}% completed (${completedTasks}/${totalActive} tasks) +
+ 📅 Daily
Today you have ${todayCount} task(s).
Focus on ${topSubject}.

@@ -123,7 +137,7 @@ function renderSidebarSubjects() { countBySubject[s.id] = 0; }); tasks.forEach(t => { - if (t.archived || !t.subject_id || countBySubject[t.subject_id] === undefined) return; + if (t.archived || t.status === 'Done' || !t.subject_id || countBySubject[t.subject_id] === undefined) return; countBySubject[t.subject_id]++; }); @@ -397,7 +411,9 @@ function renderTasks() { // Update badges const allTasksBadge = document.querySelector('#all-tasks-btn .badge'); if (allTasksBadge) { - allTasksBadge.textContent = activeTasks.length; + const pendingCount = activeTasks.filter(t => t.status !== 'Done').length; + allTasksBadge.textContent = pendingCount; + allTasksBadge.setAttribute('aria-label', `${pendingCount} pending tasks`); } const archivedBadge = document.querySelector('#archived-tasks-btn .badge'); if (archivedBadge) { @@ -663,9 +679,11 @@ function renderTasks() { } -const summaryBox = document.getElementById('summary-box'); -if (summaryBox) { - summaryBox.innerHTML = generateSummary(store.tasks, store.subjects); +function renderSummary() { + const summaryBox = document.getElementById('summary-box'); + if (summaryBox) { + summaryBox.innerHTML = generateSummary(store.tasks, store.subjects); + } } function renderCalendar() { @@ -855,6 +873,7 @@ store.subscribe(renderExtraction); store.subscribe(renderCalendar); store.subscribe(renderFocusTasks); store.subscribe(renderSidebarSubjects); +store.subscribe(renderSummary); document.addEventListener('DOMContentLoaded', () => { if (newSubjectColorsEl) {