1 changed files with 34 additions and 18 deletions
|
|
@ -9,6 +9,7 @@ import {
|
|||
Calendar,
|
||||
Repeat,
|
||||
Check,
|
||||
Search,
|
||||
} from "lucide-react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import type { Task } from "@/lib/types";
|
||||
|
|
@ -40,6 +41,7 @@ export function TaskItem({ task, subtasks = [], depth = 0 }: TaskItemProps) {
|
|||
const { t } = useTranslation();
|
||||
const router = useRouter();
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
const [detailOpen, setDetailOpen] = useState(false);
|
||||
const [editing, setEditing] = useState(false);
|
||||
const [title, setTitle] = useState(task.title);
|
||||
const [notes, setNotes] = useState(task.notes || "");
|
||||
|
|
@ -123,17 +125,21 @@ export function TaskItem({ task, subtasks = [], depth = 0 }: TaskItemProps) {
|
|||
>
|
||||
{/* Main row */}
|
||||
<div className="flex items-center gap-2 px-3 py-2">
|
||||
{/* Expand toggle */}
|
||||
<button
|
||||
onClick={() => setExpanded(!expanded)}
|
||||
className="p-0.5 text-foreground/40 hover:text-foreground shrink-0"
|
||||
>
|
||||
{expanded ? (
|
||||
<ChevronDown size={14} />
|
||||
) : (
|
||||
<ChevronRight size={14} />
|
||||
)}
|
||||
</button>
|
||||
{/* Expand subtasks toggle — only shown when subtasks exist */}
|
||||
{subtasks.length > 0 ? (
|
||||
<button
|
||||
onClick={() => setExpanded(!expanded)}
|
||||
className="p-0.5 text-foreground/40 hover:text-foreground shrink-0"
|
||||
>
|
||||
{expanded ? (
|
||||
<ChevronDown size={14} />
|
||||
) : (
|
||||
<ChevronRight size={14} />
|
||||
)}
|
||||
</button>
|
||||
) : (
|
||||
<span className="w-[18px] shrink-0" />
|
||||
)}
|
||||
|
||||
{/* Checkbox */}
|
||||
<button
|
||||
|
|
@ -147,12 +153,12 @@ export function TaskItem({ task, subtasks = [], depth = 0 }: TaskItemProps) {
|
|||
{task.completed && <Check size={12} />}
|
||||
</button>
|
||||
|
||||
{/* Title */}
|
||||
{/* Title — click opens detail */}
|
||||
<span
|
||||
className={`flex-1 text-sm cursor-pointer ${
|
||||
task.completed ? "line-through text-foreground/50" : ""
|
||||
}`}
|
||||
onClick={() => setExpanded(!expanded)}
|
||||
onClick={() => setDetailOpen(!detailOpen)}
|
||||
>
|
||||
{task.title}
|
||||
</span>
|
||||
|
|
@ -174,10 +180,20 @@ export function TaskItem({ task, subtasks = [], depth = 0 }: TaskItemProps) {
|
|||
{subtasks.filter((s) => s.completed).length}/{subtasks.length}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{/* Detail view toggle */}
|
||||
<button
|
||||
onClick={() => setDetailOpen(!detailOpen)}
|
||||
className={`p-0.5 shrink-0 transition-colors ${
|
||||
detailOpen ? "text-bleu" : "text-foreground/30 hover:text-foreground/60"
|
||||
}`}
|
||||
>
|
||||
<Search size={14} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Expanded view */}
|
||||
{expanded && (
|
||||
{/* Detail view */}
|
||||
{detailOpen && (
|
||||
<div className="px-3 pb-3 pt-1 border-t border-border-light dark:border-border-dark">
|
||||
{editing ? (
|
||||
<div className="space-y-2">
|
||||
|
|
@ -284,7 +300,7 @@ export function TaskItem({ task, subtasks = [], depth = 0 }: TaskItemProps) {
|
|||
</div>
|
||||
|
||||
{/* Subtask form */}
|
||||
{showSubtaskForm && expanded && (
|
||||
{showSubtaskForm && detailOpen && (
|
||||
<div style={{ marginLeft: 24 }} className="mb-1.5">
|
||||
<TaskForm
|
||||
listId={task.listId}
|
||||
|
|
@ -294,8 +310,8 @@ export function TaskItem({ task, subtasks = [], depth = 0 }: TaskItemProps) {
|
|||
</div>
|
||||
)}
|
||||
|
||||
{/* Subtasks */}
|
||||
{subtasks.map((sub) => (
|
||||
{/* Subtasks — toggled by chevron */}
|
||||
{expanded && subtasks.map((sub) => (
|
||||
<TaskItem key={sub.id} task={sub} depth={depth + 1} />
|
||||
))}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue