From bcf92cd034793579cabd18e777888567aea4adf9 Mon Sep 17 00:00:00 2001 From: jjangminii Date: Thu, 16 Jul 2026 17:09:06 +0900 Subject: [PATCH 1/2] =?UTF-8?q?fix(web):=20=EC=99=84=EB=A3=8C=20=EB=AA=A8?= =?UTF-8?q?=EB=8B=AC=EC=9D=98=20"=EA=B3=84=ED=9A=8D"=20=EA=B0=92=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=97=B0=EC=9E=A5=20=EC=8B=9C=EA=B0=84=EC=9D=84=20?= =?UTF-8?q?=EC=A0=9C=EC=99=B8=ED=95=9C=EB=8B=A4=20(#258)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 완료 모달에 전달되는 계획 시간에서 연장 시간을 제외했습니다 - Focus/사이드바는 타이머 서클 라벨(연장 포함 유지)과 완료 모달(계획만) 값을 분리했습니다 --- .../home/_containers/HomeTodoContainer.tsx | 4 +--- .../today/_containers/TodayTodoListContainer.tsx | 4 +--- .../(main)/focus/_containers/FocusSessionContainer.tsx | 2 +- .../app/[locale]/(main)/focus/_hooks/use-focus-session.ts | 5 +++++ apps/timo-web/components/layout/sidebar/time/TimerPanel.tsx | 6 +++++- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/home/_containers/HomeTodoContainer.tsx b/apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/home/_containers/HomeTodoContainer.tsx index 208eba98..efa73bef 100644 --- a/apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/home/_containers/HomeTodoContainer.tsx +++ b/apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/home/_containers/HomeTodoContainer.tsx @@ -98,9 +98,7 @@ export const HomeTodoContainer = () => { }, [isWeekView, scrollRef]); const plannedMinutes = activeTimer - ? convertDurationToMinutes( - activeTimer.plannedSeconds + activeTimer.extendedSeconds, - ) + ? convertDurationToMinutes(activeTimer.plannedSeconds) : 0; const actualMinutes = activeTimer ? convertDurationToMinutes(activeTimer.elapsedSeconds) diff --git a/apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/_containers/TodayTodoListContainer.tsx b/apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/_containers/TodayTodoListContainer.tsx index 7f568744..c878be44 100644 --- a/apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/_containers/TodayTodoListContainer.tsx +++ b/apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/_containers/TodayTodoListContainer.tsx @@ -83,9 +83,7 @@ export const TodayTodoListContainer = () => { const completedCount = todos.filter((todo) => todo.completed).length; const plannedMinutes = activeTimer - ? convertDurationToMinutes( - activeTimer.plannedSeconds + activeTimer.extendedSeconds, - ) + ? convertDurationToMinutes(activeTimer.plannedSeconds) : 0; const actualMinutes = activeTimer ? convertDurationToMinutes(activeTimer.elapsedSeconds) diff --git a/apps/timo-web/app/[locale]/(main)/focus/_containers/FocusSessionContainer.tsx b/apps/timo-web/app/[locale]/(main)/focus/_containers/FocusSessionContainer.tsx index 39feabbb..ff5cf58e 100644 --- a/apps/timo-web/app/[locale]/(main)/focus/_containers/FocusSessionContainer.tsx +++ b/apps/timo-web/app/[locale]/(main)/focus/_containers/FocusSessionContainer.tsx @@ -121,7 +121,7 @@ export const FocusSessionContainer = () => { ref={focusSessionState.timerSessionControlsRef} isRunning={focusSessionState.isRunning} onTogglePlay={focusSessionActions.onTogglePlay} - plannedMinutes={focusSessionState.plannedMinutes} + plannedMinutes={focusSessionState.basePlannedMinutes} actualMinutes={focusSessionState.actualMinutes} feedbackText={feedbackText} isTimeUp={focusSessionState.isTimeUp} diff --git a/apps/timo-web/app/[locale]/(main)/focus/_hooks/use-focus-session.ts b/apps/timo-web/app/[locale]/(main)/focus/_hooks/use-focus-session.ts index 66230d81..7de03803 100644 --- a/apps/timo-web/app/[locale]/(main)/focus/_hooks/use-focus-session.ts +++ b/apps/timo-web/app/[locale]/(main)/focus/_hooks/use-focus-session.ts @@ -236,6 +236,10 @@ export const useFocusSession = ({ ) : 0; const plannedMinutes = convertDurationToMinutes(plannedSeconds); + // 완료 모달의 "계획"은 연장 시간을 제외한 순수 계획 시간만 보여줘야 한다 + const basePlannedMinutes = convertDurationToMinutes( + timer ? timer.plannedSeconds : (todo?.durationSeconds ?? 0), + ); const actualMinutes = convertDurationToMinutes(timer?.elapsedSeconds ?? 0); return { @@ -253,6 +257,7 @@ export const useFocusSession = ({ isOvertime, overtimeProgress, plannedMinutes, + basePlannedMinutes, actualMinutes, }, focusSessionActions: { diff --git a/apps/timo-web/components/layout/sidebar/time/TimerPanel.tsx b/apps/timo-web/components/layout/sidebar/time/TimerPanel.tsx index 10ca10f6..2f4bc03d 100644 --- a/apps/timo-web/components/layout/sidebar/time/TimerPanel.tsx +++ b/apps/timo-web/components/layout/sidebar/time/TimerPanel.tsx @@ -157,6 +157,10 @@ export const TimerPanel = () => { ) : 0; const plannedMinutes = convertDurationToMinutes(plannedSeconds); + // 완료 모달의 "계획"은 연장 시간을 제외한 순수 계획 시간만 보여줘야 한다 + const basePlannedMinutes = convertDurationToMinutes( + activeTimer?.plannedSeconds ?? 0, + ); const actualMinutes = convertDurationToMinutes( activeTimer?.elapsedSeconds ?? 0, ); @@ -177,7 +181,7 @@ export const TimerPanel = () => { ref={timerSessionControlsRef} isRunning={isRunning} onTogglePlay={handleTogglePlay} - plannedMinutes={plannedMinutes} + plannedMinutes={basePlannedMinutes} actualMinutes={actualMinutes} feedbackText={feedbackText} isTimeUp={isTimeUp} From e96900803618960e419df1f698f4e97c1d78feed Mon Sep 17 00:00:00 2001 From: jjangminii Date: Thu, 16 Jul 2026 17:10:01 +0900 Subject: [PATCH 2/2] =?UTF-8?q?fix(web):=20=EC=A7=91=EC=A4=91=20=EB=AA=A8?= =?UTF-8?q?=EB=93=9C=20TODO=20=EC=A1=B0=ED=9A=8C=20=EC=9D=91=EB=8B=B5?= =?UTF-8?q?=EC=9D=98=20BaseResponse=20=EB=9E=98=ED=8D=BC=20=EB=88=84?= =?UTF-8?q?=EB=9D=BD=EC=9D=84=20=EC=88=98=EC=A0=95=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 실제 응답은 여전히 BaseResponse로 감싸져 있는데 이전 재생성에서 래퍼 없는 타입으로 잘못 바뀌어 있던 것을 실제 동작 기준으로 복원했습니다 --- .../api/generated/endpoints/focus/focus.ts | 4 +- .../generated/endpoints/focus/focus.zod.ts | 50 +++++++++++-------- apps/timo-web/api/generated/models/index.ts | 1 + .../focus/_queries/use-focus-todo-query.ts | 2 +- 4 files changed, 32 insertions(+), 25 deletions(-) diff --git a/apps/timo-web/api/generated/endpoints/focus/focus.ts b/apps/timo-web/api/generated/endpoints/focus/focus.ts index 26989958..0c767fec 100644 --- a/apps/timo-web/api/generated/endpoints/focus/focus.ts +++ b/apps/timo-web/api/generated/endpoints/focus/focus.ts @@ -10,7 +10,7 @@ import { useQuery } from "@tanstack/react-query"; import { customInstance } from "../../../client/custom-instance"; import type { ErrorType } from "../../../client/custom-instance"; -import type { ErrorDto, FocusTodoResponse } from "../../models"; +import type { BaseResponseFocusTodoResponse, ErrorDto } from "../../models"; import type { DataTag, DefinedInitialDataOptions, @@ -57,7 +57,7 @@ export const getFocusTodo = ( options?: SecondParameter, signal?: AbortSignal, ) => { - return customInstance( + return customInstance( { url: `/api/v1/focus`, method: "GET", signal }, options, ); diff --git a/apps/timo-web/api/generated/endpoints/focus/focus.zod.ts b/apps/timo-web/api/generated/endpoints/focus/focus.zod.ts index d403820a..814851cc 100644 --- a/apps/timo-web/api/generated/endpoints/focus/focus.zod.ts +++ b/apps/timo-web/api/generated/endpoints/focus/focus.zod.ts @@ -18,32 +18,38 @@ import * as zod from "zod"; * @summary 집중 모드 TODO 조회 */ export const GetFocusTodoResponse = zod.object({ - date: zod.iso.date(), - dayOfWeek: zod.enum(["MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"]), - hasTodo: zod.boolean(), - todo: zod + status: zod.number().optional(), + message: zod.string().optional(), + data: zod .object({ - todoId: zod.number(), - icon: zod.string().optional(), - title: zod.string(), - completed: zod.boolean(), - durationSeconds: zod.number().optional(), - priority: zod.string().optional(), - tag: zod + date: zod.iso.date(), + dayOfWeek: zod.enum(["MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"]), + hasTodo: zod.boolean(), + todo: zod .object({ - tagId: zod.number(), - name: zod.string(), + todoId: zod.number(), + icon: zod.string().optional(), + title: zod.string(), + completed: zod.boolean(), + durationSeconds: zod.number().optional(), + priority: zod.string().optional(), + tag: zod + .object({ + tagId: zod.number(), + name: zod.string(), + }) + .optional(), + isRepeated: zod.boolean(), + memo: zod.string().optional(), + subtasks: zod.array( + zod.object({ + subtaskId: zod.number(), + content: zod.string(), + completed: zod.boolean(), + }), + ), }) .optional(), - isRepeated: zod.boolean(), - memo: zod.string().optional(), - subtasks: zod.array( - zod.object({ - subtaskId: zod.number(), - content: zod.string(), - completed: zod.boolean(), - }), - ), }) .optional(), }); diff --git a/apps/timo-web/api/generated/models/index.ts b/apps/timo-web/api/generated/models/index.ts index e632f371..3e76db97 100644 --- a/apps/timo-web/api/generated/models/index.ts +++ b/apps/timo-web/api/generated/models/index.ts @@ -16,6 +16,7 @@ export * from "./baseResponseCalendarAuthorizeResponse"; export * from "./baseResponseCalendarConnectResponse"; export * from "./baseResponseCalendarDisconnectResponse"; export * from "./baseResponseCalendarEventsResponse"; +export * from "./baseResponseFocusTodoResponse"; export * from "./baseResponseHomeResponse"; export * from "./baseResponseListTimeBoxResponse"; export * from "./baseResponseObject"; diff --git a/apps/timo-web/app/[locale]/(main)/focus/_queries/use-focus-todo-query.ts b/apps/timo-web/app/[locale]/(main)/focus/_queries/use-focus-todo-query.ts index 5e4d597e..d0329ca0 100644 --- a/apps/timo-web/app/[locale]/(main)/focus/_queries/use-focus-todo-query.ts +++ b/apps/timo-web/app/[locale]/(main)/focus/_queries/use-focus-todo-query.ts @@ -12,5 +12,5 @@ export const useFocusTodoQuery = () => useSuspenseQuery({ queryKey: getGetFocusTodoQueryKey(), queryFn: ({ signal }) => getFocusTodo(undefined, signal), - select: (data) => focusViewSchema.parse(data), + select: ({ data }) => focusViewSchema.parse(data), });