Skip to content

[FEAT] 통계 페이지 사이드 패널 구현#128

Merged
yumin-kim2 merged 12 commits into
developfrom
feat/web/123-statistics-side-panel
Jul 10, 2026
Merged

[FEAT] 통계 페이지 사이드 패널 구현#128
yumin-kim2 merged 12 commits into
developfrom
feat/web/123-statistics-side-panel

Conversation

@yumin-kim2

@yumin-kim2 yumin-kim2 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

ISSUE 🔗

close #123



What is this PR? 🔍

통계 화면에서 사용할 우측 사이드 패널 컴포넌트를 구현했습니다.

현재 컴포넌트는 아래 두 상태를 variant로 나눠 렌더링합니다.

  • variant: "month"
  • variant: "day"

월별 요약은 summary를 받고, 일별 상세는 detail을 받습니다.
API 응답이 붙더라도 컨테이너나 쿼리 레이어에서 데이터를 넘겨주면 사이드 패널은 표시만 담당하도록 의도했습니다.

aside 공통 구조를 분리한 이유

월별 요약 패널과 일별 상세 패널은 보여주는 내용은 다르지만, “오른쪽 사이드 패널”이라는 껍데기는 같습니다.
그래서 패널 공통 레이아웃은 SIDE_PANEL_CLASS_NAME으로 분리했습니다.

const SIDE_PANEL_CLASS_NAME =
  "border-timo-gray-500 min-h-full w-76 border-l text-timo-black";

이렇게 하면서 중복되던 width, height, border, 기본 텍스트 색상 스타일을 한 곳에서 관리하도록 했습니다.
각 variant에서는 padding이나 내부 배치처럼 달라지는 부분만 추가로 넘기도록 구성했습니다.

공통 시간 표시 블록

월별 요약과 일별 상세에는 공통적으로 “라벨 + 큰 시간” UI가 들어갑니다.

이번 달의 총 기록 시간
22h 10m
오늘의 총 기록 시간
4h 20m

이 구조가 반복되어 SummaryTimeBlock으로 분리했습니다.

시간 포맷 유틸

API에서는 시간을 분 단위 숫자로 받는다고 보고 구현했습니다.

totalRecordMinutes: 260
actualTimeMinutes: 90
estimatedTimeMinutes: 60

화면에서는 사용 위치에 따라 다른 형태로 보여줘야 해서 유틸을 두 개로 나눴습니다.

formatStatisticsHourText(260) // "4h 20m"
formatStatisticsClockText(90) // "1:30"

formatStatisticsHourText는 월/일 총 기록 시간처럼 큰 요약 시간에 사용합니다.
formatStatisticsClockText는 투두별 실제 시간, 계획 시간처럼 목록 안에서 짧게 보여주는 시간에 사용합니다.

초과/단축 표시 처리

투두의 초과/단축 상태는 아래 기준으로 계산했습니다.

actualTimeMinutes > estimatedTimeMinutes → +초과
actualTimeMinutes < estimatedTimeMinutes → -단축
actualTimeMinutes === estimatedTimeMinutes → 표시 없음

다만 표시가 없는 경우에도 피그마 기준으로 각 투두 아이템 높이가 유지되어야 했기 때문에, 조건부로 아예 렌더링하지 않고 invisible 클래스를 사용해 공간을 유지했습니다.



To Reviewers

이번 작업에서는 StatisticsSidePanel을 전체 통계 화면의 레이아웃 컴포넌트가 아니라, “오른쪽 패널 내부 UI”를 담당하는 컴포넌트로 두었습니다.
따라서 헤더, 캘린더, 우측 패널을 나란히 배치하는 전체 뷰 구조는 후속 작업에서 처리할 예정입니다.



Screenshot 📷

image image



Test Checklist ✔

  • 월별 요약 패널에서 총 기록 시간, 활동일, 일평균, 누적 태스크가 정상 표시되는지 확인
  • 일별 상세 패널에서 날짜, 총 기록 시간, 투두 목록이 정상 표시되는지 확인
  • 실제 시간이 계획 시간보다 길 때 +초과가 표시되는지 확인
  • 실제 시간이 계획 시간보다 짧을 때 -단축이 표시되는지 확인
  • lint, check-types 통과 확인

@yumin-kim2 yumin-kim2 linked an issue Jul 9, 2026 that may be closed by this pull request
@vercel

vercel Bot commented Jul 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
timo Ready Ready Preview, Comment Jul 10, 2026 5:37pm

@github-actions github-actions Bot requested review from jjangminii and kimminna July 9, 2026 14:15
@github-actions github-actions Bot added ⏰ Timo-web Timo 웹 서비스 ✨ Feature 새로운 기능(기능성) 구현 ♣️ 유민 유민양 labels Jul 9, 2026
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yumin-kim2, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 40 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 088d5545-00f0-4ea6-bba9-7b688f3fdab0

📥 Commits

Reviewing files that changed from the base of the PR and between 57e2d66 and 2fa956f.

📒 Files selected for processing (4)
  • apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx
  • apps/timo-web/app/[locale]/(main)/statistics/_components/SummaryTimeBlock.tsx
  • apps/timo-web/app/[locale]/(main)/statistics/_types/statistics.ts
  • apps/timo-web/app/[locale]/(main)/statistics/_utils/formatStatisticsTime.ts

Walkthrough

통계 화면용 StatisticsSidePanel 컴포넌트와 월간·일별 통계 타입, 시간 포맷 유틸이 추가되었습니다. 패널은 variant에 따라 월간 요약 또는 선택 날짜의 투두별 상세 기록을 렌더링합니다.

Changes

통계 사이드 패널

Layer / File(s) Summary
통계 타입 및 시간 포맷 유틸
apps/timo-web/app/[locale]/(main)/statistics/_types/statistics.ts, apps/timo-web/app/[locale]/(main)/statistics/_utils/formatStatisticsTime.ts
월간·일별 통계 데이터 타입과 분 단위를 요약 시간 및 H:MM 문자열로 변환하는 유틸 함수가 추가됩니다.
StatisticsSidePanel 컴포넌트 구현
apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx
monthday 변형에 따라 월간 집계 또는 선택 날짜의 기록 목록을 렌더링하며, 실제·예정 시간 차이에 따른 라벨과 스타일을 표시합니다.

Estimated code review effort: 2 (Simple) | ~15 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Parent
  participant StatisticsSidePanel
  participant SummaryTimeBlock
  participant formatStatisticsTime

  Parent->>StatisticsSidePanel: variant와 summary/detail 전달
  alt variant === "month"
    StatisticsSidePanel->>SummaryTimeBlock: 월간 기록 시간 전달
    SummaryTimeBlock->>formatStatisticsTime: formatStatisticsHourText(minutes) 호출
    formatStatisticsTime-->>SummaryTimeBlock: 요약 시간 문자열 반환
  else variant === "day"
    StatisticsSidePanel->>SummaryTimeBlock: 일별 기록 시간 전달
    SummaryTimeBlock->>formatStatisticsTime: formatStatisticsHourText(minutes) 호출
    formatStatisticsTime-->>SummaryTimeBlock: 요약 시간 문자열 반환
    StatisticsSidePanel->>formatStatisticsTime: 실제/예정 시간 전달
    formatStatisticsTime-->>StatisticsSidePanel: H:MM 문자열 반환
    StatisticsSidePanel->>StatisticsSidePanel: diff 라벨 및 클래스 계산
  end
  StatisticsSidePanel-->>Parent: 월간 또는 일별 패널 렌더링
Loading

Suggested labels: ♠️ 정민

Suggested reviewers: ehye1, jjangminii

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed 통계 페이지의 우측 사이드 패널 구현이라는 핵심 변경을 간결하게 잘 요약했습니다.
Description check ✅ Passed 월간 요약, 일별 상세, props 기반 구조와 시간 포맷 유틸까지 변경 내용과 잘 맞습니다.
Linked Issues check ✅ Passed [#123] 월간 요약, 선택 날짜 상세, 기록 아이템, props 기반 구조 요구를 모두 충족한 것으로 보입니다.
Out of Scope Changes check ✅ Passed 변경 파일이 모두 통계 사이드 패널과 관련된 타입, 유틸, UI 컴포넌트로 범위 밖 변경은 보이지 않습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/web/123-statistics-side-panel

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

Timo Performance Report

Bundle Size — timo-web
라우트 크기 First Load JS
/[locale]/home 71.44 kB 🟡 277.25 kB
/[locale]/today 52.50 kB 🟡 258.31 kB
/[locale]/focus 51.65 kB 🟡 257.46 kB
/[locale]/settings/account 0 B 🟡 205.81 kB
/[locale]/settings 0 B 🟡 205.81 kB
/[locale]/settings/policy 0 B 🟡 205.81 kB
/[locale]/statistics 49.60 kB 🟡 255.41 kB
/[locale]/[...rest] 0 B 🟡 205.81 kB
/[locale]/onboarding 107.39 kB 🟡 313.20 kB
/[locale] 0 B 🟡 205.81 kB

공유 번들: 205.81 kB
🟢 < 200kB  |  🟡 < 350kB  |  🔴 ≥ 350kB (First Load JS · gzip)

Lighthouse — timo-web
URL Perf A11y LCP CLS TBT
/en/home 🔴 67 🟢 96 🔴 14.0s 🟢 0.000 🟡 349ms
/en/today 🟡 71 🟢 96 🔴 13.7s 🟢 0.000 🟡 228ms
/en/focus 🔴 69 🟡 91 🔴 13.6s 🟢 0.000 🟡 279ms
/en/statistics 🔴 60 🟢 95 🔴 13.6s 🟢 0.000 🔴 604ms

Perf ≥ 70 / A11y ≥ 85 목표
LCP 🟢 < 2.5s 🟡 < 4s 🔴 ≥ 4s  |  CLS 🟢 < 0.1 🟡 < 0.25 🔴 ≥ 0.25  |  TBT 🟢 < 200ms 🟡 < 600ms 🔴 ≥ 600ms

Image Optimization — timo-web

public/ 디렉토리에 이미지가 없습니다.

측정 커밋: 003be76

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@apps/timo-web/app/`[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx:
- Around line 16-24: `StatisticsSidePanelProps` is a discriminated union
declared as a type alias, so it should follow the naming convention by using the
`Types` suffix instead of `Props`. Rename the alias in `StatisticsSidePanel` to
match the convention, and update every usage of `StatisticsSidePanelProps` in
this component and any imports/references so the union type remains consistent
with the `SummaryTimeBlockProps` `interface` naming pattern.
- Around line 6-14: StatisticsSidePanel currently imports from relative paths,
which should be converted to the project’s absolute import convention. Update
the imports for formatStatisticsClockText, formatStatisticsHourText,
StatisticsDayDetail, and StatisticsMonthSummary to use the corresponding
absolute paths instead of ../_utils/formatStatisticsTime and
../_types/statistics, keeping the same symbols but changing only the import
paths.
- Line 1: Remove the unnecessary client directive from StatisticsSidePanel so it
can remain a server component; this file only renders static UI and does not use
useState, useEffect, or event handlers. Update the StatisticsSidePanel component
to omit "use client", and keep any imported icons/components that are
server-compatible as-is so the _components UI stays props-only and SSR-friendly.
- Around line 29-38: `getDiffLabel` currently returns `"+초과"` for `diffMinutes
=== 0`, which is semantically incorrect; update the helper so the zero case is
handled explicitly and only positive values map to `"+초과"` while negative values
still map to `"-단축"`. Keep `getDiffClassName` aligned with the same
zero/positive/negative branching in `StatisticsSidePanel` so the label and class
logic remain consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 350dfbba-73f0-4e38-8ec8-eb504bf7eba1

📥 Commits

Reviewing files that changed from the base of the PR and between 6e082b2 and 4654f0e.

📒 Files selected for processing (4)
  • apps/timo-web/app/[locale]/(main)/statistics/_components/.gitkeep
  • apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx
  • apps/timo-web/app/[locale]/(main)/statistics/_types/statistics.ts
  • apps/timo-web/app/[locale]/(main)/statistics/_utils/formatStatisticsTime.ts

Comment thread apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx Outdated
Comment thread apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx Outdated
Comment thread apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx Outdated

@jjangminii jjangminii left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

variant로 월별/일별를 분리한 구조도 적절하고, 공통 클래스와 SummaryTimeBlock을 잘 추출해주셔서 보기 편했어요 👍 절대경로 변경과 사소한 코멘트 몇 가지 남겨두으니 확인 부탁드려요!

Comment thread apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx Outdated
Comment thread apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx Outdated
Comment thread apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx Outdated
Comment thread apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx Outdated
Comment thread apps/timo-web/app/[locale]/(main)/statistics/_types/statistics.ts Outdated
Comment thread apps/timo-web/app/[locale]/(main)/statistics/_types/statistics.ts Outdated
Comment thread apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx Outdated

@kimminna kimminna left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생했어용! 🫡

Comment on lines +1 to +4
/**
* 분 단위 기록 시간을 통계 요약 영역의 시간 텍스트로 변환합니다.
* 예: 260 -> "4h 20m", 120 -> "2h", 30 -> "30m"
*/

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jsdoc 에 관한 문서 첨부해드릴게요!
https://www.typescriptlang.org/ko/docs/handbook/jsdoc-supported-types.html
이거 보고 유틸 파일 추후에 수정해 주면 좋을 것 같아요 😍

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

태그도 같이 붙이는게 확실히 문서 구조가 명확해져서 좋은 것 같네요. 이해하기도 편하구요! 반영완료했습니다😍🤟

@yumin-kim2 yumin-kim2 merged commit f18156f into develop Jul 10, 2026
11 checks passed
@yumin-kim2 yumin-kim2 deleted the feat/web/123-statistics-side-panel branch July 10, 2026 19:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ Feature 새로운 기능(기능성) 구현 ⏰ Timo-web Timo 웹 서비스 ♣️ 유민 유민양

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] 통계 요약 및 일별 상세 패널 구현

3 participants