From 2585b13dff3307499d077490f46c3f322ed23b73 Mon Sep 17 00:00:00 2001 From: Lee Hye Won Date: Wed, 15 Jul 2026 11:47:06 +0900 Subject: [PATCH 1/4] =?UTF-8?q?fix(web):=20=EC=83=81=EC=84=B8=20=ED=88=AC?= =?UTF-8?q?=EB=91=90=20=EC=88=98=EC=A0=95=20=EC=8B=9C=20Today=20=EC=BF=BC?= =?UTF-8?q?=EB=A6=AC=EB=A5=BC=20invalidate=ED=95=9C=EB=8B=A4=20(#211)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit use-update-todo-submit의 onSuccess에서 getGetTodayQueryKey invalidation이 누락되어 Today 화면의 TodayTodoCard가 갱신되지 않는 버그를 수정했습니다. Co-Authored-By: Claude Sonnet 4.6 --- .../hooks/todo-modal/detail/use-update-todo-submit.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/timo-web/hooks/todo-modal/detail/use-update-todo-submit.ts b/apps/timo-web/hooks/todo-modal/detail/use-update-todo-submit.ts index ae7b1f4a..b145e719 100644 --- a/apps/timo-web/hooks/todo-modal/detail/use-update-todo-submit.ts +++ b/apps/timo-web/hooks/todo-modal/detail/use-update-todo-submit.ts @@ -5,7 +5,10 @@ import { useQueryClient } from "@tanstack/react-query"; import type { ErrorType } from "@/api/client/custom-instance"; import type { ErrorDto, TodoUpdateRequest } from "@/api/generated/models"; -import { getGetHomeQueryKey } from "@/api/generated/endpoints/home/home"; +import { + getGetHomeQueryKey, + getGetTodayQueryKey, +} from "@/api/generated/endpoints/home/home"; import { getGetTodoDetailQueryKey, useUpdateTodo, @@ -35,6 +38,7 @@ export const useUpdateTodoSubmit = () => { { onSuccess: () => { queryClient.invalidateQueries({ queryKey: getGetHomeQueryKey() }); + queryClient.invalidateQueries({ queryKey: getGetTodayQueryKey() }); queryClient.invalidateQueries({ queryKey: getGetTodoDetailQueryKey(todoId, { date }), }); From add69b6cf3cf9bfc3e038a67459f58ef8931d878 Mon Sep 17 00:00:00 2001 From: Lee Hye Won Date: Wed, 15 Jul 2026 11:52:21 +0900 Subject: [PATCH 2/4] =?UTF-8?q?fix(web):=20=EC=83=81=EC=84=B8=20=ED=88=AC?= =?UTF-8?q?=EB=91=90=20=EC=82=AD=EC=A0=9C=20=EC=8B=9C=20Today=20=EC=BF=BC?= =?UTF-8?q?=EB=A6=AC=EB=A5=BC=20invalidate=ED=95=9C=EB=8B=A4=20(#211)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit use-delete-todo-submit의 onSuccess에서 getGetTodayQueryKey invalidation이 누락되어 서버 동기화 없이 로컬 state만 제거되던 문제를 수정했습니다. Co-Authored-By: Claude Sonnet 4.6 --- .../hooks/todo-modal/detail/use-delete-todo-submit.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/timo-web/hooks/todo-modal/detail/use-delete-todo-submit.ts b/apps/timo-web/hooks/todo-modal/detail/use-delete-todo-submit.ts index ac141940..626a7a6a 100644 --- a/apps/timo-web/hooks/todo-modal/detail/use-delete-todo-submit.ts +++ b/apps/timo-web/hooks/todo-modal/detail/use-delete-todo-submit.ts @@ -2,7 +2,10 @@ import { useQueryClient } from "@tanstack/react-query"; -import { getGetHomeQueryKey } from "@/api/generated/endpoints/home/home"; +import { + getGetHomeQueryKey, + getGetTodayQueryKey, +} from "@/api/generated/endpoints/home/home"; import { useDeleteTodo } from "@/api/generated/endpoints/todo/todo"; export interface DeleteTodoSubmitHandlers { @@ -23,6 +26,7 @@ export const useDeleteTodoSubmit = () => { { onSuccess: () => { queryClient.invalidateQueries({ queryKey: getGetHomeQueryKey() }); + queryClient.invalidateQueries({ queryKey: getGetTodayQueryKey() }); onSuccess(); }, onError, From 658b5f949e82e010debb042fdeb2acf5a7341e1e Mon Sep 17 00:00:00 2001 From: Lee Hye Won Date: Wed, 15 Jul 2026 12:11:18 +0900 Subject: [PATCH 3/4] =?UTF-8?q?fix(web):=20Today=20=EC=84=9C=EB=B8=8C?= =?UTF-8?q?=ED=83=9C=EC=8A=A4=ED=81=AC=20=EC=99=84=EB=A3=8C=20=EC=8B=9C=20?= =?UTF-8?q?API=EB=A5=BC=20=ED=98=B8=EC=B6=9C=ED=95=9C=EB=8B=A4=20(#211)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit handleSubTodoCheck가 로컬 state만 변경하고 서버에 반영하지 않아 새로고침 시 체크 상태가 초기화되는 문제를 수정했습니다. Home과 동일하게 optimistic update 후 실패 시 롤백하는 구조로 변경했습니다. Co-Authored-By: Claude Sonnet 4.6 --- .../today/_hooks/useTodayTodoList.ts | 39 ++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/_hooks/useTodayTodoList.ts b/apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/_hooks/useTodayTodoList.ts index e0788a80..835b1fd2 100644 --- a/apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/_hooks/useTodayTodoList.ts +++ b/apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/_hooks/useTodayTodoList.ts @@ -15,6 +15,7 @@ import { } from "@/api/generated/endpoints/timer/timer"; import { getGetTodoDetailQueryKey, + useChangeSubtaskStatus, useChangeTodoStatus, } from "@/api/generated/endpoints/todo/todo"; import { useActiveTimer } from "@/hooks/use-active-timer"; @@ -42,6 +43,7 @@ export const useTodayTodoList = ( const queryClient = useQueryClient(); const { data: activeTimer } = useActiveTimer(); const { mutate: changeTodoStatus } = useChangeTodoStatus(); + const { mutate: changeSubtaskStatus } = useChangeSubtaskStatus(); const { mutate: stopTimer } = useStopTimer(); const { invalidateTimerState, invalidateTimeBoxes } = useTimerQueryInvalidation(); @@ -177,21 +179,40 @@ export const useTodayTodoList = ( }; const handleSubTodoCheck = (todoId: number, subtaskId: number) => { - // TODO: API + const todo = todos.find((t) => t.todoId === todoId); + const subtask = todo?.subtasks.find((s) => s.subtaskId === subtaskId); + if (!subtask) return; + + const completed = !subtask.completed; + const dateKey = todo?.date; + if (!dateKey) return; + + const previous = todos; setTodos((prev) => - prev.map((todo) => - todo.todoId === todoId + prev.map((t) => + t.todoId === todoId ? { - ...todo, - subtasks: todo.subtasks.map((s) => - s.subtaskId === subtaskId - ? { ...s, completed: !s.completed } - : s, + ...t, + subtasks: t.subtasks.map((s) => + s.subtaskId === subtaskId ? { ...s, completed } : s, ), } - : todo, + : t, ), ); + + changeSubtaskStatus( + { todoId, subtaskId, data: { isCompleted: completed } }, + { + onSuccess: () => { + invalidateTodayView(); + invalidateTodoDetail(todoId, dateKey); + }, + onError: () => { + setTodos(previous); + }, + }, + ); }; return { From 50e98166224a710257d83c06e6639dd3fa587d6b Mon Sep 17 00:00:00 2001 From: Lee Hye Won Date: Wed, 15 Jul 2026 12:11:59 +0900 Subject: [PATCH 4/4] =?UTF-8?q?fix(web):=20Today=20=EC=B9=B4=EB=93=9C=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C=20=EB=B0=8F=20=EC=84=9C=EB=B8=8C=ED=83=9C?= =?UTF-8?q?=EC=8A=A4=ED=81=AC=20=EC=99=84=EB=A3=8C=20=EC=8B=9C=20=EC=A6=89?= =?UTF-8?q?=EC=8B=9C=20dimmed=20=EC=B2=98=EB=A6=AC=ED=95=9C=EB=8B=A4=20(#2?= =?UTF-8?q?11)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 체크박스 클릭 시 마우스가 카드 위에 있어 isHovered가 true인 상태라 isCompleted가 true여도 isDimmed가 false로 계산되는 문제를 수정했습니다. isCompleted가 true로 바뀌면 isHovered를 즉시 초기화합니다. 서브태스크는 isDone 상태에 따라 텍스트 색상을 즉시 변경합니다. Co-Authored-By: Claude Sonnet 4.6 --- .../today/_containers/TodayTodoCardContainer.tsx | 6 +++++- .../[locale]/(main)/today/_components/TodayTodoCard.tsx | 8 +++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/_containers/TodayTodoCardContainer.tsx b/apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/_containers/TodayTodoCardContainer.tsx index e222ec28..b327112f 100644 --- a/apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/_containers/TodayTodoCardContainer.tsx +++ b/apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/_containers/TodayTodoCardContainer.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import type { TodoTimerStatusTypes } from "@/api/common/todo-schema"; import type { ReactNode } from "react"; @@ -38,6 +38,10 @@ export const TodayTodoCardContainer = ({ }: TodayTodoCardContainerProps) => { const [isHovered, setIsHovered] = useState(false); + useEffect(() => { + if (isCompleted) setIsHovered(false); + }, [isCompleted]); + const isPlaying = timerStatus === "RUNNING"; const isDimmed = isCompleted && !isHovered; diff --git a/apps/timo-web/app/[locale]/(main)/today/_components/TodayTodoCard.tsx b/apps/timo-web/app/[locale]/(main)/today/_components/TodayTodoCard.tsx index 6003adc2..5bd06eb9 100644 --- a/apps/timo-web/app/[locale]/(main)/today/_components/TodayTodoCard.tsx +++ b/apps/timo-web/app/[locale]/(main)/today/_components/TodayTodoCard.tsx @@ -142,6 +142,7 @@ export const TodayTodoCard = ({
  • @@ -150,7 +151,12 @@ export const TodayTodoCard = ({ onChange={() => onSubTodoCheck(sub.id)} />
    - + {sub.text}