From 9b8a12b5b08e6f9c2bdbaa5c8884d7683f9c5fdf Mon Sep 17 00:00:00 2001 From: yumin-kim4757 Date: Wed, 8 Jul 2026 23:52:53 +0900 Subject: [PATCH 01/12] =?UTF-8?q?feat(web):=20=ED=86=B5=EA=B3=84=20?= =?UTF-8?q?=EC=82=AC=EC=9D=B4=EB=93=9C=20=ED=8C=A8=EB=84=90=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=B6=94=EA=B0=80=20(#123)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../(main)/statistics/_types/statistics.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 apps/timo-web/app/[locale]/(main)/statistics/_types/statistics.ts diff --git a/apps/timo-web/app/[locale]/(main)/statistics/_types/statistics.ts b/apps/timo-web/app/[locale]/(main)/statistics/_types/statistics.ts new file mode 100644 index 00000000..a3f696a0 --- /dev/null +++ b/apps/timo-web/app/[locale]/(main)/statistics/_types/statistics.ts @@ -0,0 +1,27 @@ +export interface StatisticsMonthSummary { + totalRecordMinutes: number; + activeDayCount: number; + averageRecordedMinutes: number; + completedTodoCount: number; + totalTodoCount: number; +} + +export interface StatisticsDayDetail { + date: string; + totalRecordMinutes: number; + todos: StatisticsTodoRecord[]; +} + +export interface StatisticsTodoRecord { + todoId: number; + title: string; + actualTimeMinutes: number; + estimatedTimeMinutes: number; + tag: StatisticsTodoTag | null; +} + +export interface StatisticsTodoTag { + tagId: number; + name: string; + color: string; +} From ef2f104c9d3cc67a6040135462ac6ab6b5dd484a Mon Sep 17 00:00:00 2001 From: yumin-kim4757 Date: Thu, 9 Jul 2026 02:17:04 +0900 Subject: [PATCH 02/12] =?UTF-8?q?feat(web):=20=ED=86=B5=EA=B3=84=20?= =?UTF-8?q?=EC=9B=94=20=EC=9A=94=EC=95=BD=20=EC=82=AC=EC=9D=B4=EB=93=9C=20?= =?UTF-8?q?=ED=8C=A8=EB=84=90=20=EA=B5=AC=ED=98=84=20(#123)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_components/StatisticsSidePanel.tsx | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx diff --git a/apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx b/apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx new file mode 100644 index 00000000..c626ce95 --- /dev/null +++ b/apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx @@ -0,0 +1,44 @@ +import { StatisticsMonthSummary } from "../_types/statistics"; +import { formatStatisticsHourText } from "../_utils/formatStatisticsTime"; + +interface StatisticsMonthSummaryPanelProps { + summary: StatisticsMonthSummary; +} + +export const StatisticsSidePanel = ({ + summary, +}: StatisticsMonthSummaryPanelProps) => { + return ( + + ); +}; From ccef3155e9d3f1cc8a95acbab0bb77332ce51719 Mon Sep 17 00:00:00 2001 From: yumin-kim4757 Date: Thu, 9 Jul 2026 02:18:43 +0900 Subject: [PATCH 03/12] =?UTF-8?q?feat(web):=20=ED=86=B5=EA=B3=84=20?= =?UTF-8?q?=EC=8B=9C=EA=B0=84=20=ED=8F=AC=EB=A7=B7=20=EC=9C=A0=ED=8B=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20(#123)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../statistics/_utils/formatStatisticsTime.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 apps/timo-web/app/[locale]/(main)/statistics/_utils/formatStatisticsTime.ts diff --git a/apps/timo-web/app/[locale]/(main)/statistics/_utils/formatStatisticsTime.ts b/apps/timo-web/app/[locale]/(main)/statistics/_utils/formatStatisticsTime.ts new file mode 100644 index 00000000..3f85a461 --- /dev/null +++ b/apps/timo-web/app/[locale]/(main)/statistics/_utils/formatStatisticsTime.ts @@ -0,0 +1,14 @@ +export const formatStatisticsHourText = (minutes: number) => { + const hours = Math.floor(minutes / 60); + const restMinutes = minutes % 60; + + if (hours === 0) { + return `${restMinutes}m`; + } + + if (restMinutes === 0) { + return `${hours}h`; + } + + return `${hours}h ${restMinutes}m`; +}; From 5e0bd09b5b34c3da3f17172bf75ae5ca20869a8d Mon Sep 17 00:00:00 2001 From: yumin-kim4757 Date: Thu, 9 Jul 2026 22:38:22 +0900 Subject: [PATCH 04/12] =?UTF-8?q?feat(web):=20=ED=86=B5=EA=B3=84=20?= =?UTF-8?q?=EC=82=AC=EC=9D=B4=EB=93=9C=20=ED=8C=A8=EB=84=90=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=A0=95=EC=9D=98=20(#123)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/[locale]/(main)/statistics/_types/statistics.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/apps/timo-web/app/[locale]/(main)/statistics/_types/statistics.ts b/apps/timo-web/app/[locale]/(main)/statistics/_types/statistics.ts index a3f696a0..3e88d5c4 100644 --- a/apps/timo-web/app/[locale]/(main)/statistics/_types/statistics.ts +++ b/apps/timo-web/app/[locale]/(main)/statistics/_types/statistics.ts @@ -17,11 +17,5 @@ export interface StatisticsTodoRecord { title: string; actualTimeMinutes: number; estimatedTimeMinutes: number; - tag: StatisticsTodoTag | null; -} - -export interface StatisticsTodoTag { - tagId: number; - name: string; - color: string; + tagName: string | null; } From f8b478478dfde98561a377c2a4bb168819c9594e Mon Sep 17 00:00:00 2001 From: yumin-kim4757 Date: Thu, 9 Jul 2026 22:39:01 +0900 Subject: [PATCH 05/12] =?UTF-8?q?feat(web):=20=ED=86=B5=EA=B3=84=20?= =?UTF-8?q?=EC=8B=9C=EA=B0=84=20=ED=8F=AC=EB=A7=B7=20=EC=9C=A0=ED=8B=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20(#123)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../(main)/statistics/_utils/formatStatisticsTime.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/timo-web/app/[locale]/(main)/statistics/_utils/formatStatisticsTime.ts b/apps/timo-web/app/[locale]/(main)/statistics/_utils/formatStatisticsTime.ts index 3f85a461..13cbe8cb 100644 --- a/apps/timo-web/app/[locale]/(main)/statistics/_utils/formatStatisticsTime.ts +++ b/apps/timo-web/app/[locale]/(main)/statistics/_utils/formatStatisticsTime.ts @@ -12,3 +12,10 @@ export const formatStatisticsHourText = (minutes: number) => { return `${hours}h ${restMinutes}m`; }; + +export const formatStatisticsClockText = (minutes: number) => { + const hours = Math.floor(minutes / 60); + const restMinutes = minutes % 60; + + return `${hours}:${String(restMinutes).padStart(2, "0")}`; +}; From 56f3b57bee30e687bef41100245c2ff45fd590f5 Mon Sep 17 00:00:00 2001 From: yumin-kim4757 Date: Thu, 9 Jul 2026 22:40:09 +0900 Subject: [PATCH 06/12] =?UTF-8?q?feat(web):=20=ED=86=B5=EA=B3=84=20?= =?UTF-8?q?=EC=9D=BC=EB=B3=84=20=EC=83=81=EC=84=B8=20=EC=82=AC=EC=9D=B4?= =?UTF-8?q?=EB=93=9C=20=ED=8C=A8=EB=84=90=20=EA=B5=AC=ED=98=84=20(#123)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_components/StatisticsSidePanel.tsx | 145 ++++++++++++++---- 1 file changed, 112 insertions(+), 33 deletions(-) diff --git a/apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx b/apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx index c626ce95..55ac8d0c 100644 --- a/apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx +++ b/apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx @@ -1,44 +1,123 @@ -import { StatisticsMonthSummary } from "../_types/statistics"; -import { formatStatisticsHourText } from "../_utils/formatStatisticsTime"; +"use client"; -interface StatisticsMonthSummaryPanelProps { - summary: StatisticsMonthSummary; -} +import { TagIcon } from "@repo/timo-design-system/ui"; + +import { + formatStatisticsClockText, + formatStatisticsHourText, +} from "../_utils/formatStatisticsTime"; + +import type { + StatisticsDayDetail, + StatisticsMonthSummary, +} from "../_types/statistics"; + +type StatisticsSidePanelProps = + | { + variant: "month"; + summary: StatisticsMonthSummary; + } + | { + variant: "day"; + detail: StatisticsDayDetail; + }; + +export const StatisticsSidePanel = (props: StatisticsSidePanelProps) => { + if (props.variant === "month") { + const { summary } = props; + + return ( + + ); + } + const { detail } = props; -export const StatisticsSidePanel = ({ - summary, -}: StatisticsMonthSummaryPanelProps) => { return ( -