feat(ux): enhance n-depth tree DND reordering, full i18n localization, admin live stats & sidebar redesign
Build and Push Docker Image / build-and-push (push) Successful in 9m22s

This commit is contained in:
2026-08-22 09:08:10 +09:00
parent 06d5344aef
commit 0f44090210
18 changed files with 1307 additions and 651 deletions
+16 -4
View File
@@ -21,6 +21,7 @@ import {
getAllTrashTasks,
filterTasksByTag,
filterActiveTree,
removeTaskFromTree,
} from "@/lib/mockData";
interface AppShellProps {
@@ -342,7 +343,7 @@ export function AppShell({ user, isDemo = false }: AppShellProps) {
const [undoToast, setUndoToast] = useState<{ task: Task; title: string } | null>(null);
const undoTimerRef = useRef<NodeJS.Timeout | null>(null);
// Unified task delete handler with immediate Undo Toast
// Unified task delete handler with immediate Undo Toast (recursively removes task & all descendants)
const handleDeleteTaskWithUndo = useCallback((task: Task) => {
if (undoTimerRef.current) clearTimeout(undoTimerRef.current);
@@ -361,15 +362,26 @@ export function AppShell({ user, isDemo = false }: AppShellProps) {
}
if (selectedTask?.id === task.id) setSelectedTask(null);
} else {
setTasks((prev) => prev.filter((t) => t.id !== task.id));
// API Mode: Optimistically strip target task and all its subtasks from active tree immediately
setTasks((prev) => removeTaskFromTree(prev as MockTask[], task.id) as Task[]);
setApiTrashCount((c) => c + 1);
if (selectedTask?.id === task.id) setSelectedTask(null);
fetch(`/api/tasks/${task.id}`, { method: "DELETE" }).catch((e) => console.error(e));
fetch(`/api/tasks/${task.id}`, { method: "DELETE" })
.then(() => {
// Re-sync trash count in background
fetch("/api/tasks?countTrash=true")
.then((r) => (r.ok ? r.json() : { count: 0 }))
.then((data) => setApiTrashCount(data.count || 0))
.catch(() => {});
})
.catch((e) => console.error(e));
}
undoTimerRef.current = setTimeout(() => {
setUndoToast(null);
}, 6000);
}, [isDemo, selectedTask]);
}, [isDemo, selectedTask, isTrashActive, selectedListId, selectedTag, showCompleted]);
// Undo delete (Restores exact soft-deleted task hierarchy)
const handleUndoDelete = useCallback(async () => {