Make due date click-to-edit, independent of series Edit toggle
Edit controlled fields across both sections — the series-level
note/interval and the task-level due date — which felt incoherent.
Due date now edits on click like the history dates.

Assisted-by: Claude Opus 4.6 via Claude Code
change lyulpqmlsmpxxslywzqvtqmqktlzxrnr
commit c792c8810adab726702b8d2540a46279fbd15da2
author Alpha Chen <alpha@kejadlen.dev>
date
parent wrntvvvz
diff --git a/lib/ketchup/views/series/show.rb b/lib/ketchup/views/series/show.rb
index 87c7f9c..b262260 100644
--- a/lib/ketchup/views/series/show.rb
+++ b/lib/ketchup/views/series/show.rb
@@ -94,22 +94,24 @@ module Views
                       end
                       button(type: "submit", class: "section-edit-btn") { "Complete" }
                     end
-                    dl(class: "detail-fields") do
+                    dl(class: "detail-fields", "x-data": "dueDateEditor(#{@series.id}, '#{active_task[:due_date]}')") do
                       dt { "Due date" }
-                      dd(
-                        "x-show": "!editing",
-                        "x-text": "new Date('#{active_task[:due_date]}T00:00').toLocaleDateString()"
-                      ) { active_task[:due_date].to_s }
-                      dd(
-                        "x-show": "editing",
-                        "x-cloak": true,
-                        "x-data": "dueDateEditor(#{@series.id}, '#{active_task[:due_date]}')"
-                      ) do
+                      dd do
+                        span(
+                          class: "task-history-date",
+                          "x-show": "!editingDate",
+                          "x-on:click": "editingDate = true; $nextTick(() => $refs.dateInput.focus())",
+                          "x-text": "new Date(dueDate + 'T00:00').toLocaleDateString()"
+                        ) { active_task[:due_date].to_s }
                         input(
                           type: "date",
                           class: "detail-input detail-input-date",
+                          "x-show": "editingDate",
+                          "x-cloak": true,
                           "x-model": "dueDate",
-                          "x-on:change": "save()"
+                          "x-ref": "dateInput",
+                          "x-on:change": "save()",
+                          "x-on:keydown.escape": "dueDate = '#{active_task[:due_date]}'; editingDate = false"
                         )
                       end
 
diff --git a/public/js/app.js b/public/js/app.js
index 99384a1..2575a91 100644
--- a/public/js/app.js
+++ b/public/js/app.js
@@ -146,9 +146,14 @@ document.addEventListener("alpine:init", () => {
   }))
 
   Alpine.data("dueDateEditor", (seriesId, initialDate) => ({
+    editingDate: false,
     dueDate: initialDate,
 
     save() {
+      if (this.dueDate === initialDate) {
+        this.editingDate = false
+        return
+      }
       saveSeriesField(seriesId, "due_date", this.dueDate)
         .then(() => location.reload())
     },