From 210fba60270923c875041743f43eff56c07f7978 Mon Sep 17 00:00:00 2001 From: Hammer Date: Thu, 29 Jan 2026 00:59:21 +0000 Subject: [PATCH] feat: editable task fields in detail panel - Click-to-edit title and description (inline editing) - Clickable priority selector (toggle between critical/high/medium/low) - Clickable source selector (toggle between all sources) - Saving indicator - EditableText component with Escape to cancel, Enter/blur to save - Pass token and onTaskUpdated props from App --- frontend/src/App.tsx | 2 + frontend/src/components/TaskDetailPanel.tsx | 196 ++++++++++++++++++-- 2 files changed, 178 insertions(+), 20 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 80c491d..a7665e8 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -288,7 +288,9 @@ function Dashboard() { handleStatusChange(id, status); setSelectedTask(null); }} + onTaskUpdated={refresh} hasToken={hasToken} + token={token} /> )} diff --git a/frontend/src/components/TaskDetailPanel.tsx b/frontend/src/components/TaskDetailPanel.tsx index 07359a6..98d8b6e 100644 --- a/frontend/src/components/TaskDetailPanel.tsx +++ b/frontend/src/components/TaskDetailPanel.tsx @@ -1,5 +1,6 @@ -import { useState, useEffect } from "react"; -import type { Task, TaskStatus, TaskPriority } from "../lib/types"; +import { useState, useEffect, useRef } from "react"; +import type { Task, TaskStatus, TaskPriority, TaskSource } from "../lib/types"; +import { updateTask } from "../lib/api"; const priorityColors: Record = { critical: "bg-red-500 text-white", @@ -61,6 +62,9 @@ const statusActions: Record void; + multiline?: boolean; + className?: string; + placeholder?: string; +}) { + const [editing, setEditing] = useState(false); + const [draft, setDraft] = useState(value); + const ref = useRef(null); + + useEffect(() => { setDraft(value); }, [value]); + useEffect(() => { if (editing) ref.current?.focus(); }, [editing]); + + const save = () => { + setEditing(false); + if (draft.trim() !== value) onSave(draft.trim()); + }; + + if (!editing) { + return ( +
setEditing(true)} + className={`cursor-pointer rounded-md px-2 py-1 -mx-2 -my-1 hover:bg-gray-100 transition group ${className}`} + title="Click to edit" + > + {value || {placeholder}} + ✏️ +
+ ); + } + + if (multiline) { + return ( +