Fix: Context menu delete integration with recursive tree, added Created and Edited timestamps in detail panel footer

This commit is contained in:
2026-08-20 14:56:19 +09:00
parent 2913ba1889
commit fc90ca7d0b
4 changed files with 37 additions and 15 deletions
+4
View File
@@ -279,6 +279,10 @@ export function AppShell({ user, isDemo = false }: AppShellProps) {
onDemoToggleTask={handleDemoToggleTask} onDemoToggleTask={handleDemoToggleTask}
onUpdateTaskTitle={handleUpdateTaskTitle} onUpdateTaskTitle={handleUpdateTaskTitle}
onUpdateListName={handleUpdateListName} onUpdateListName={handleUpdateListName}
onDeleteTask={isDemo ? handleDemoDeleteTask : async (id: string) => {
await fetch(`/api/tasks/${id}`, { method: "DELETE" });
refresh();
}}
/> />
</div> </div>
+15 -2
View File
@@ -490,13 +490,14 @@ export function TaskDetail({
)} )}
</div> </div>
{/* Footer Info: Project Badge & Timestamp */} {/* Footer Info: Project Badge, Created & Edited Timestamps */}
<div style={{ fontSize: 11, color: "var(--text-tertiary)", display: "flex", justifyContent: "space-between", alignItems: "center", borderTop: "1px solid var(--border)", paddingTop: 8 }}> <div style={{ fontSize: 11, color: "var(--text-tertiary)", display: "flex", justifyContent: "space-between", alignItems: "center", borderTop: "1px solid var(--border)", paddingTop: 8, flexWrap: "wrap", gap: 6 }}>
{listName && ( {listName && (
<span className="tick-meta-chip" style={{ fontSize: 11, padding: "2px 8px" }}> <span className="tick-meta-chip" style={{ fontSize: 11, padding: "2px 8px" }}>
📁 {listName} 📁 {listName}
</span> </span>
)} )}
<div style={{ display: "flex", alignItems: "center", gap: 12, marginLeft: "auto", flexWrap: "wrap" }}>
<span> <span>
{t("created")}:{" "} {t("created")}:{" "}
{new Date(task.createdAt).toLocaleDateString(lang === "ko" ? "ko-KR" : lang === "ja" ? "ja-JP" : "en-US", { {new Date(task.createdAt).toLocaleDateString(lang === "ko" ? "ko-KR" : lang === "ja" ? "ja-JP" : "en-US", {
@@ -505,6 +506,18 @@ export function TaskDetail({
day: "numeric", day: "numeric",
})} })}
</span> </span>
{task.updatedAt && (
<span>
{t("edited")}:{" "}
{new Date(task.updatedAt).toLocaleTimeString(lang === "ko" ? "ko-KR" : lang === "ja" ? "ja-JP" : "en-US", {
month: "short",
day: "numeric",
hour: "2-digit",
minute: "2-digit",
})}
</span>
)}
</div>
</div> </div>
</div> </div>
</aside> </aside>
+6 -4
View File
@@ -1,4 +1,4 @@
"use client"; "use client";
import React, { useState, useEffect, useRef, useCallback } from "react"; import React, { useState, useEffect, useRef, useCallback } from "react";
import { useI18n } from "@/lib/i18n"; import { useI18n } from "@/lib/i18n";
import { ContextMenu, MenuItem } from "@/components/ui/ContextMenu"; import { ContextMenu, MenuItem } from "@/components/ui/ContextMenu";
@@ -340,6 +340,7 @@ interface Props {
onDemoToggleTask?: (id: string, completed: boolean) => void; onDemoToggleTask?: (id: string, completed: boolean) => void;
onUpdateTaskTitle?: (id: string, title: string) => void; onUpdateTaskTitle?: (id: string, title: string) => void;
onUpdateListName?: (id: string, name: string) => void; onUpdateListName?: (id: string, name: string) => void;
onDeleteTask?: (id: string) => void;
} }
export function TaskList({ export function TaskList({
@@ -359,6 +360,7 @@ export function TaskList({
onDemoToggleTask, onDemoToggleTask,
onUpdateTaskTitle, onUpdateTaskTitle,
onUpdateListName, onUpdateListName,
onDeleteTask,
}: Props) { }: Props) {
const { t } = useI18n(); const { t } = useI18n();
const [newTaskTitle, setNewTaskTitle] = useState(""); const [newTaskTitle, setNewTaskTitle] = useState("");
@@ -671,9 +673,9 @@ export function TaskList({
icon: "🗑️", icon: "🗑️",
danger: true, danger: true,
onClick: async () => { onClick: async () => {
if (isDemo) { if (onDeleteTask) {
setTasks((prev) => prev.filter((t) => t.id !== contextMenu.task.id)); onDeleteTask(contextMenu.task.id);
} else { } else if (!isDemo) {
await fetch(`/api/tasks/${contextMenu.task.id}`, { method: "DELETE" }); await fetch(`/api/tasks/${contextMenu.task.id}`, { method: "DELETE" });
onRefresh(); onRefresh();
} }
+4 -1
View File
@@ -1,4 +1,4 @@
"use client"; "use client";
import React, { createContext, useContext, useState, useEffect } from "react"; import React, { createContext, useContext, useState, useEffect } from "react";
export type Language = "en" | "ko" | "ja"; export type Language = "en" | "ko" | "ja";
@@ -76,6 +76,7 @@ export const translations = {
autoSaved: "Auto-saved", autoSaved: "Auto-saved",
saving: "Saving…", saving: "Saving…",
created: "Created", created: "Created",
edited: "Edited",
// Toolbars // Toolbars
bold: "Bold", bold: "Bold",
@@ -158,6 +159,7 @@ export const translations = {
autoSaved: "자동 저장됨", autoSaved: "자동 저장됨",
saving: "저장 중…", saving: "저장 중…",
created: "생성일", created: "생성일",
edited: "수정일",
// Toolbars // Toolbars
bold: "굵게", bold: "굵게",
@@ -240,6 +242,7 @@ export const translations = {
autoSaved: "自動保存済み", autoSaved: "自動保存済み",
saving: "保存中…", saving: "保存中…",
created: "作成日時", created: "作成日時",
edited: "更新日時",
// Toolbars // Toolbars
bold: "太字", bold: "太字",