Skip to content

[FEAT] 통계 페이지 뷰 구현#143

Merged
yumin-kim2 merged 14 commits into
developfrom
feat/web/142-statistics-calendar-view
Jul 12, 2026
Merged

[FEAT] 통계 페이지 뷰 구현#143
yumin-kim2 merged 14 commits into
developfrom
feat/web/142-statistics-calendar-view

Conversation

@yumin-kim2

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

Copy link
Copy Markdown
Contributor

ISSUE 🔗

close #142



What is this PR? 🔍

1. 통계 뷰 컨테이너 연결

StatisticsContainer에서 통계 화면의 주요 상태를 관리하도록 했습니다.

const [currentMonth, setCurrentMonth] = useState(() => new Date());
const [selectedDate, setSelectedDate] = useState(
  () => new Date(MOCK_STATISTICS_CALENDAR.today),
);
const [panelMode, setPanelMode] = useState<StatisticsPanelMode>("month");

월 이동과 날짜 클릭은 각각 다른 패널 모드로 이어지도록 분리했습니다.

const handleChangeMonth: typeof setCurrentMonth = (value) => {
  setCurrentMonth(value);
  setPanelMode("month");
};

const handleSelectDate = (date: Date) => {
  setSelectedDate(date);
  setPanelMode("day");
};

이 구조를 선택한 이유는 API 연결 시에도 동일하게 유지될 수 있기 때문입니다.
나중에는 현재 mock 데이터를 아래처럼 query 결과로 바꾸면 됩니다.

const calendarData = useStatisticsCalendarQuery(currentMonth);
const monthSummary = useStatisticsMonthSummaryQuery(currentMonth);
const dayDetail = useStatisticsDayDetailQuery(selectedDate);

2. 캘린더 날짜 선택 및 아이콘 상태 처리

캘린더 날짜 클릭 시 부모 컨테이너의 selectedDate가 갱신되도록 연결했습니다.
onClick={() => onSelectDate(calendarDate.date)}
아이콘 상태는 완료율과 미래 날짜 여부를 기준으로 계산합니다.

미래 날짜는 아직 기록이 존재할 수 없는 날짜이므로 disabled 아이콘으로 보여주고 클릭도 막았습니다.
disabled={isFutureDate}
반대로 과거 날짜의 completionRate: null은 미래 날짜가 아니므로 disabled가 아니라 0% 상태로 처리했습니다.

3. 오른쪽 패널 월별/일별 전환

StatisticsSidePanel은 variant에 따라 월별 패널과 일별 패널을 렌더링합니다.

type StatisticsSidePanelProps =
  | StatisticsMonthSidePanelProps
  | StatisticsDaySidePanelProps;

4. 오른쪽 패널 고정 너비 처리

처음에는 w-76만 적용했는데, flex row 안에서 사이드 패널이 줄어들어 피그마 기준 304px이 유지되지 않는 문제가 있었습니다.
그래서 사이드 패널은 고정 너비와 shrink 방지를 함께 적용했습니다.
w-[304px] shrink-0
캘린더 영역은 남은 공간을 차지하도록 변경했습니다.
min-w-0 flex-1
이렇게 해서 레이아웃 역할이 명확해졌습니다.

  • 캘린더: 남은 공간 사용
  • 오른쪽 패널: 304px 고정

5. 다국어 지원

오른쪽 패널의 고정 문구를 Statistics.sidePanel 네임스페이스로 분리했습니다.
const t = useTranslations("Statistics.sidePanel");
예시:

t("monthTotalRecordTime")
t("activeDays")
t("plan")

ko.json, en.json에 각각 통계 패널 문구를 추가했습니다.
날짜와 월 표시는 useLocale()과 Intl.DateTimeFormat을 사용했습니다.
const locale = useLocale();
이 화면에서는 한국어 화면이면 7월, 영어 화면이면 July처럼 현재 locale을 따라가야 하므로 useLocale() 기반 포맷을 유지했습니다.



To Reviewers

  • 현재 통계 데이터는 API 연결 전 mock 데이터입니다.
  • API 연결 시 _queries에 월별/일별 query hook을 추가하고, StatisticsContainer에서 mock 데이터를 query 결과로 교체하는 흐름을 예상하고 있습니다!



Screenshot 📷

2026-07-11.9.59.27.mov



Test Checklist ✔

  • pnpm --filter timo-web exec tsc --noEmit 통과
  • pnpm --filter timo-web lint 통과
  • 브라우저에서 월 이동 시 월별 패널로 전환되는지 확인
  • 브라우저에서 날짜 클릭 시 일별 패널로 전환되는지 확인
  • 브라우저에서 미래 날짜가 disabled 처리되고 클릭되지 않는지 확인
  • 브라우저에서 ko/en locale 전환 후 통계 패널 문구와 날짜 포맷 확인
  • pnpm build 실행

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

vercel Bot commented Jul 10, 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 12, 2026 10:09am

Request Review

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

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

통계 페이지가 날짜 선택과 월·일 사이드 패널 전환을 지원하도록 확장되었습니다. 캘린더와 헤더는 현재 로케일을 사용하고, 사이드 패널 라벨은 번역 메시지로 표시됩니다.

Changes

통계 페이지 상호작용

Layer / File(s) Summary
통계 목 데이터와 포맷 계약
apps/timo-web/app/[locale]/(main)/statistics/_mocks/statistics-calendar.ts, apps/timo-web/app/[locale]/(main)/statistics/_utils/..., apps/timo-web/app/[locale]/(main)/statistics/_components/SummaryTimeBlock.tsx
캘린더 목 데이터가 월별 요약과 일별 상세로 확장되고, 날짜·시간 포맷 함수가 추가되었습니다.
월·일 상태와 패널 연결
apps/timo-web/app/[locale]/(main)/statistics/_containers/...
컨테이너가 현재 월, 선택 날짜, 패널 모드를 관리하며 월 요약 또는 선택 날짜 상세 정보를 사이드 패널에 전달합니다.
캘린더와 헤더 로케일 표시
apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsCalendar.tsx, apps/timo-web/app/[locale]/(main)/statistics/_containers/StatisticsHeaderContainer.tsx
날짜 항목이 선택 가능한 버튼으로 변경되고 미래 날짜가 비활성화되며, 월·오늘 라벨이 현재 로케일로 포맷됩니다.
사이드 패널 번역
apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx, apps/timo-web/messages/en.json, apps/timo-web/messages/ko.json
월·일 통계 라벨과 계획, 초과·단축 문구가 번역 키를 통해 표시됩니다.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant 사용자
  participant StatisticsCalendar
  participant StatisticsContainer
  participant StatisticsSidePanel
  사용자->>StatisticsCalendar: 날짜 버튼 클릭
  StatisticsCalendar->>StatisticsContainer: 선택 날짜 전달
  StatisticsContainer->>StatisticsContainer: 날짜 키로 상세 데이터 조회
  StatisticsContainer->>StatisticsSidePanel: 일별 패널 데이터 전달
  StatisticsSidePanel-->>사용자: 선택 날짜 통계 표시
Loading

Possibly related PRs

  • Team-Timo/Timo-client#105 — 통계 화면이 사용하는 next-intl 라우팅 및 메시지 로딩 인프라와 연결됩니다.
  • Team-Timo/Timo-client#128StatisticsSidePanel의 월·일 variant와 diff 표시 로직이 직접 연결됩니다.
  • Team-Timo/Timo-client#133StatisticsCalendar의 미래 날짜 상태와 선택 동작 변경에 직접 연결됩니다.

Suggested labels: ♦️ 민아

Suggested reviewers: kimminna, ehye1, jjangminii

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed 제목이 통계 페이지 뷰 구현이라는 핵심 변경을 명확히 요약합니다.
Description check ✅ Passed 설명이 실제 변경 내용과 일치하며 통계 화면 연결과 다국어 지원을 잘 담고 있습니다.
Linked Issues check ✅ Passed 중앙 캘린더와 오른쪽 패널 배치, 선택 상태 연동, 여백·반응형 보강이 요구사항대로 반영되었습니다.
Out of Scope Changes check ✅ Passed 통계 화면 구현을 위한 보조 유틸과 메시지 추가 외에 눈에 띄는 범위 이탈 변경은 보이지 않습니다.
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/142-statistics-calendar-view

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 10, 2026

Copy link
Copy Markdown

Timo Performance Report

Bundle Size — timo-web
라우트 크기 First Load JS
/[locale]/home 167.33 kB 🔴 373.15 kB
/[locale]/today 64.79 kB 🟡 270.61 kB
/[locale]/focus 61.48 kB 🟡 267.29 kB
/[locale]/settings/account 0 B 🟡 205.82 kB
/[locale]/settings 71.49 kB 🟡 277.30 kB
/[locale]/statistics 60.01 kB 🟡 265.83 kB
/[locale]/[...rest] 0 B 🟡 205.82 kB
/[locale]/login 116.05 kB 🟡 321.86 kB
/[locale]/onboarding 134.84 kB 🟡 340.66 kB
/[locale] 0 B 🟡 205.82 kB

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

Lighthouse — timo-web
URL Perf A11y LCP CLS TBT
/en/home 🔴 62 🟢 96 🔴 14.5s 🟢 0.000 🟡 527ms
/en/today 🟡 71 🟡 93 🔴 13.8s 🟢 0.000 🟡 243ms
/en/focus 🟡 71 🟡 91 🔴 13.8s 🟢 0.000 🟡 238ms
/en/statistics 🟡 72 🟢 96 🔴 13.7s 🟢 0.000 🟡 201ms

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

Image Optimization — timo-web
파일 크기 포맷 상태
images/google-calendar.png 36.20 kB PNG ⚠️ 🟢
images/google-logo.png 26.79 kB PNG ⚠️ 🟢

총 2개 · 63.00 kB  |  🟢 < 200KB  |  🟡 < 500KB  |  🔴 ≥ 500KB
⚠️ 2개 파일 WebP/AVIF 변환 권장

측정 커밋: 3f3c06b

@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: 9

🤖 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/StatisticsCalendar.tsx:
- Line 1: StatisticsCalendar의 onClick 등 인터랙티브 로직을 _containers/로 이동해
_components/가 순수 props 기반 UI로 동작하도록 분리하거나, 구조상 해당 컴포넌트를 _containers/로 옮기고 'use
client'를 유지하세요.
- Around line 117-140: 날짜 선택 버튼에 전체 날짜 맥락이 포함된 접근성 라벨이 없습니다. StatisticsCalendar의
날짜 버튼에 formatStatisticsCalendarDate(calendarDate.date)를 사용한 aria-label을 추가해 스크린
리더가 연도·월·일을 함께 읽도록 수정하세요.
- Around line 109-142: Move the invariant formatDateKey(selectedDate)
calculation outside the calendarDates.map callback, store it in a clearly named
variable near the component’s other derived values, and compare each dateKey
against that variable when computing isSelected.

In
`@apps/timo-web/app/`[locale]/(main)/statistics/_containers/StatisticsContainer.tsx:
- Line 17: Rename the union type alias StatisticsPanelMode to
StatisticsPanelModeTypes and update all references within
StatisticsContainer.tsx accordingly.
- Around line 22-24: MOCK_STATISTICS_CALENDAR.today is parsed as UTC and can
produce the previous local date. Update the mock date initialization used by
StatisticsContainer and the definition of MOCK_STATISTICS_CALENDAR to construct
July 10, 2026 in local time (for example, using numeric Date arguments) or
include an explicit local-time offset, while preserving formatDateKey
compatibility.

In
`@apps/timo-web/app/`[locale]/(main)/statistics/_containers/StatisticsHeaderContainer.tsx:
- Around line 23-26: StatisticsHeaderContainer의 인라인 월 포맷팅을 제거하고,
_utils/format-statistics-date.ts의 formatStatisticsMonth를 import하여
formatStatisticsMonth(currentMonth, locale)로 monthLabel을 생성하도록 변경하세요.

In `@apps/timo-web/app/`[locale]/(main)/statistics/_mocks/statistics-calendar.ts:
- Around line 55-61: MOCK_STATISTICS_MONTH_SUMMARY의 월간 요약 값이 일별 목 데이터와 일관되지
않습니다. MOCK_COMPLETION_RATES의 유효 일수와 일별 상세 데이터의 todo 개수를 기준으로 activeDayCount를 26,
totalTodoCount를 52로 맞추고, 일별 totalRecordMinutes 합계인 5340과 activeDayCount를 기준으로
totalRecordMinutes 및 averageRecordedMinutes를 조정하세요.

In `@apps/timo-web/messages/en.json`:
- Line 43: Update the activeDayCount message to use ICU pluralization, selecting
the singular “day” when count equals 1 and the plural “days” otherwise, while
preserving the count value in both variants.
- Line 48: Update the "overtime" translation value in the messages/en.json
localization resource from "+Overdue" to "+Overtime" (or "+Over") to accurately
represent exceeding the planned time.
🪄 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: 32ef4fa5-3816-4250-9998-0c81b8491eb0

📥 Commits

Reviewing files that changed from the base of the PR and between 9552e20 and dea7333.

📒 Files selected for processing (9)
  • apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsCalendar.tsx
  • apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx
  • apps/timo-web/app/[locale]/(main)/statistics/_containers/StatisticsContainer.tsx
  • apps/timo-web/app/[locale]/(main)/statistics/_containers/StatisticsHeaderContainer.tsx
  • apps/timo-web/app/[locale]/(main)/statistics/_containers/StatisticsPageContainer.tsx
  • apps/timo-web/app/[locale]/(main)/statistics/_mocks/statistics-calendar.ts
  • apps/timo-web/app/[locale]/(main)/statistics/_utils/format-statistics-date.ts
  • apps/timo-web/messages/en.json
  • apps/timo-web/messages/ko.json
💤 Files with no reviewable changes (1)
  • apps/timo-web/app/[locale]/(main)/statistics/_containers/StatisticsPageContainer.tsx

@@ -1,10 +1,13 @@
"use client";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

_components/ 디렉터리의 'use client' 사용을 검토해주세요.

경로 규칙에 따르면 _components/'use client' 없이 동작 가능한 순수 UI여야 합니다. 이 컴포넌트는 onClick 핸들러가 추가되어 클라이언트 렌더링이 필수가 되었습니다. 인터랙티브 로직을 _containers/로 분리하거나, 이 컴포넌트가 여전히 props 기반 UI로서 _components/에 머무는 것이 타당한지 팀과 논의해보시길 권장합니다.

As per path instructions, _components/는 props만 받는 순수 UI — 'use client' 없이 동작 가능해야 합니다.

🤖 Prompt for 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.

In
`@apps/timo-web/app/`[locale]/(main)/statistics/_components/StatisticsCalendar.tsx
at line 1, StatisticsCalendar의 onClick 등 인터랙티브 로직을 _containers/로 이동해
_components/가 순수 props 기반 UI로 동작하도록 분리하거나, 구조상 해당 컴포넌트를 _containers/로 옮기고 'use
client'를 유지하세요.

Source: Path instructions

Comment on lines 109 to 142
{calendarDates.map((calendarDate) => {
const dateKey = formatDateKey(calendarDate.date);
const isSelected = dateKey === formatDateKey(selectedDate);
const completionRate = completionRateByDate.get(dateKey) ?? null;
const status = getIconStatus(completionRate);
const Icon = STATUS_ICON[status];

return (
<div key={dateKey} className="flex flex-col items-center gap-2.5">
<Icon />
<span className="typo-body-sb-11 text-timo-gray-700">
<button
key={dateKey}
type="button"
className="flex flex-col items-center gap-2.5"
onClick={() => onSelectDate(calendarDate.date)}
>
<span
className={cn(
"rounded-full",
isSelected &&
"drop-shadow-[0_0_10px_var(--color-timo-blue-75)]",
)}
>
<Icon />
</span>
<span
className={cn(
"typo-body-sb-11 text-timo-gray-700",
isSelected && "text-timo-blue-300",
)}
>
{calendarDate.day}
</span>
</div>
</button>
);
})}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

formatDateKey(selectedDate)를 루프 밖으로 이동해주세요.

formatDateKey(selectedDate)calendarDates.map 콜백 내부(Line 111)에서 매 반복마다 호출됩니다. selectedDate는 루프 내에서 변하지 않으므로 컴포넌트 본문 상단에서 한 번만 계산하는 것이 효율적입니다.

♻️ 제안하는 리팩터링
  const todayLabel = formatStatisticsCalendarDate(today, locale);
+ const selectedDateKey = formatDateKey(selectedDate);

  return (
    <section className="w-full px-14.75 pt-10 pb-13">
      ...
          {calendarDates.map((calendarDate) => {
            const dateKey = formatDateKey(calendarDate.date);
-           const isSelected = dateKey === formatDateKey(selectedDate);
+           const isSelected = dateKey === selectedDateKey;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{calendarDates.map((calendarDate) => {
const dateKey = formatDateKey(calendarDate.date);
const isSelected = dateKey === formatDateKey(selectedDate);
const completionRate = completionRateByDate.get(dateKey) ?? null;
const status = getIconStatus(completionRate);
const Icon = STATUS_ICON[status];
return (
<div key={dateKey} className="flex flex-col items-center gap-2.5">
<Icon />
<span className="typo-body-sb-11 text-timo-gray-700">
<button
key={dateKey}
type="button"
className="flex flex-col items-center gap-2.5"
onClick={() => onSelectDate(calendarDate.date)}
>
<span
className={cn(
"rounded-full",
isSelected &&
"drop-shadow-[0_0_10px_var(--color-timo-blue-75)]",
)}
>
<Icon />
</span>
<span
className={cn(
"typo-body-sb-11 text-timo-gray-700",
isSelected && "text-timo-blue-300",
)}
>
{calendarDate.day}
</span>
</div>
</button>
);
})}
{calendarDates.map((calendarDate) => {
const dateKey = formatDateKey(calendarDate.date);
const isSelected = dateKey === selectedDateKey;
const completionRate = completionRateByDate.get(dateKey) ?? null;
const status = getIconStatus(completionRate);
const Icon = STATUS_ICON[status];
return (
<button
key={dateKey}
type="button"
className="flex flex-col items-center gap-2.5"
onClick={() => onSelectDate(calendarDate.date)}
>
<span
className={cn(
"rounded-full",
isSelected &&
"drop-shadow-[0_0_10px_var(--color-timo-blue-75)]",
)}
>
<Icon />
</span>
<span
className={cn(
"typo-body-sb-11 text-timo-gray-700",
isSelected && "text-timo-blue-300",
)}
>
{calendarDate.day}
</span>
</button>
);
})}
🤖 Prompt for 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.

In
`@apps/timo-web/app/`[locale]/(main)/statistics/_components/StatisticsCalendar.tsx
around lines 109 - 142, Move the invariant formatDateKey(selectedDate)
calculation outside the calendarDates.map callback, store it in a clearly named
variable near the component’s other derived values, and compare each dateKey
against that variable when computing isSelected.

Comment on lines +117 to +140
<button
key={dateKey}
type="button"
className="flex flex-col items-center gap-2.5"
onClick={() => onSelectDate(calendarDate.date)}
>
<span
className={cn(
"rounded-full",
isSelected &&
"drop-shadow-[0_0_10px_var(--color-timo-blue-75)]",
)}
>
<Icon />
</span>
<span
className={cn(
"typo-body-sb-11 text-timo-gray-700",
isSelected && "text-timo-blue-300",
)}
>
{calendarDate.day}
</span>
</div>
</button>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

날짜 버튼에 aria-label 추가를 권장합니다.

버튼 내부에 날짜 숫자 텍스트가 있지만, 스크린 리더 사용자에게 "15"만 들리는 것보다 "2024년 1월 15일"과 같은 맥락 정보가 포함된 aria-label이 접근성에 도움이 됩니다. formatStatisticsCalendarDate 유틸을 활용하면 쉽게 구현할 수 있습니다.

🛡️ 제안하는 접근성 개선
              <button
                key={dateKey}
                type="button"
+               aria-label={formatStatisticsCalendarDate(calendarDate.date, locale)}
                className="flex flex-col items-center gap-2.5"
                onClick={() => onSelectDate(calendarDate.date)}
              >
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<button
key={dateKey}
type="button"
className="flex flex-col items-center gap-2.5"
onClick={() => onSelectDate(calendarDate.date)}
>
<span
className={cn(
"rounded-full",
isSelected &&
"drop-shadow-[0_0_10px_var(--color-timo-blue-75)]",
)}
>
<Icon />
</span>
<span
className={cn(
"typo-body-sb-11 text-timo-gray-700",
isSelected && "text-timo-blue-300",
)}
>
{calendarDate.day}
</span>
</div>
</button>
<button
key={dateKey}
type="button"
aria-label={formatStatisticsCalendarDate(calendarDate.date, locale)}
className="flex flex-col items-center gap-2.5"
onClick={() => onSelectDate(calendarDate.date)}
>
<span
className={cn(
"rounded-full",
isSelected &&
"drop-shadow-[0_0_10px_var(--color-timo-blue-75)]",
)}
>
<Icon />
</span>
<span
className={cn(
"typo-body-sb-11 text-timo-gray-700",
isSelected && "text-timo-blue-300",
)}
>
{calendarDate.day}
</span>
</button>
🤖 Prompt for 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.

In
`@apps/timo-web/app/`[locale]/(main)/statistics/_components/StatisticsCalendar.tsx
around lines 117 - 140, 날짜 선택 버튼에 전체 날짜 맥락이 포함된 접근성 라벨이 없습니다.
StatisticsCalendar의 날짜 버튼에 formatStatisticsCalendarDate(calendarDate.date)를 사용한
aria-label을 추가해 스크린 리더가 연도·월·일을 함께 읽도록 수정하세요.

import { formatStatisticsSidePanelDate } from "@/app/[locale]/(main)/statistics/_utils/format-statistics-date";
import { formatDateKey } from "@/app/[locale]/(main)/statistics/_utils/statistics-calendar";

type StatisticsPanelMode = "month" | "day";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

타입 alias 명명 컨벤션을 준수해 주세요.

StatisticsPanelMode는 유니언 타입 alias이므로, 컨벤션에 따라 Types 접미사를 붙여 StatisticsPanelModeTypes로 명명해야 합니다. 이 파일 내에서만 사용되므로 변경 범위가 제한적입니다.

As per coding guidelines, **/*.{ts,tsx}: "type alias는 유니언·튜플·리터럴에만 사용, 접미사 Types"

♻️ 제안 수정안
-type StatisticsPanelMode = "month" | "day";
+type StatisticsPanelModeTypes = "month" | "day";

 export const StatisticsContainer = () => {
   const locale = useLocale();
   const [currentMonth, setCurrentMonth] = useState(() => new Date());
   const [selectedDate, setSelectedDate] = useState(
     () => new Date(MOCK_STATISTICS_CALENDAR.today),
   );
-  const [panelMode, setPanelMode] = useState<StatisticsPanelMode>("month");
+  const [panelMode, setPanelMode] = useState<StatisticsPanelModeTypes>("month");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
type StatisticsPanelMode = "month" | "day";
type StatisticsPanelModeTypes = "month" | "day";
export const StatisticsContainer = () => {
const locale = useLocale();
const [currentMonth, setCurrentMonth] = useState(() => new Date());
const [selectedDate, setSelectedDate] = useState(
() => new Date(MOCK_STATISTICS_CALENDAR.today),
);
const [panelMode, setPanelMode] = useState<StatisticsPanelModeTypes>("month");
🤖 Prompt for 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.

In
`@apps/timo-web/app/`[locale]/(main)/statistics/_containers/StatisticsContainer.tsx
at line 17, Rename the union type alias StatisticsPanelMode to
StatisticsPanelModeTypes and update all references within
StatisticsContainer.tsx accordingly.

Source: Coding guidelines

Comment thread apps/timo-web/app/[locale]/(main)/statistics/_containers/StatisticsContainer.tsx Outdated
Comment on lines +23 to +26
const locale = useLocale();
const monthLabel = new Intl.DateTimeFormat(locale, {
month: "long",
}).format(currentMonth);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

formatStatisticsMonth 유틸을 재사용해주세요.

StatisticsCalendar.tsx에서 이미 formatStatisticsMonth(currentMonth, locale)를 사용하고 있는데, 이 컨테이너에서는 동일한 로직을 new Intl.DateTimeFormat(locale, { month: "long" }).format(currentMonth)로 인라인하고 있습니다. _utils/format-statistics-date.tsformatStatisticsMonth를 import하여 중복을 제거해주세요.

♻️ 제안하는 리팩터링
+ import { formatStatisticsMonth } from "../_utils/format-statistics-date";
  ...
  const locale = useLocale();
- const monthLabel = new Intl.DateTimeFormat(locale, {
-   month: "long",
- }).format(currentMonth);
+ const monthLabel = formatStatisticsMonth(currentMonth, locale);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const locale = useLocale();
const monthLabel = new Intl.DateTimeFormat(locale, {
month: "long",
}).format(currentMonth);
import { formatStatisticsMonth } from "../_utils/format-statistics-date";
const locale = useLocale();
- const monthLabel = new Intl.DateTimeFormat(locale, {
- month: "long",
const monthLabel = formatStatisticsMonth(currentMonth, locale);
🤖 Prompt for 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.

In
`@apps/timo-web/app/`[locale]/(main)/statistics/_containers/StatisticsHeaderContainer.tsx
around lines 23 - 26, StatisticsHeaderContainer의 인라인 월 포맷팅을 제거하고,
_utils/format-statistics-date.ts의 formatStatisticsMonth를 import하여
formatStatisticsMonth(currentMonth, locale)로 monthLabel을 생성하도록 변경하세요.

Comment on lines +55 to +61
export const MOCK_STATISTICS_MONTH_SUMMARY: StatisticsMonthSummary = {
totalRecordMinutes: 1330,
activeDayCount: 28,
averageRecordedMinutes: 214,
completedTodoCount: 80,
totalTodoCount: 100,
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

목 요약 목 데이터의 수치 일관성을 점검해 주세요.

MOCK_STATISTICS_MONTH_SUMMARY 내부 값들이 서로 맞지 않습니다:

  • averageRecordedMinutes(214) ≠ totalRecordMinutes / activeDayCount = 1330 / 28 ≈ 47.5
  • activeDayCount(28) ≠ MOCK_COMPLETION_RATES에서 null이 아닌 날 수(26개)
  • totalTodoCount(100) ≠ 일별 상세의 실제 todo 수(26일 × 2개 = 52)

StatisticsSidePanel 월 패널에서 totalRecordMinutesaverageRecordedMinutes가 함께 표시되므로, 개발 중 수치 불일치를 눈치챌 수 있습니다. 목 데이터라도 패널에 직접 노출되는 값들은 내부 연관성을 맞추는 것이 좋습니다.

🔧 제안 수정안
 export const MOCK_STATISTICS_MONTH_SUMMARY: StatisticsMonthSummary = {
-  totalRecordMinutes: 1330,
-  activeDayCount: 28,
-  averageRecordedMinutes: 214,
-  completedTodoCount: 80,
-  totalTodoCount: 100,
+  totalRecordMinutes: 5340,
+  activeDayCount: 26,
+  averageRecordedMinutes: 205,
+  completedTodoCount: 52,
+  totalTodoCount: 52,
 };

참고: totalRecordMinutes 5340는 일별 totalRecordMinutes 합계이고, averageRecordedMinutes는 5340 / 26 ≈ 205입니다.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const MOCK_STATISTICS_MONTH_SUMMARY: StatisticsMonthSummary = {
totalRecordMinutes: 1330,
activeDayCount: 28,
averageRecordedMinutes: 214,
completedTodoCount: 80,
totalTodoCount: 100,
};
export const MOCK_STATISTICS_MONTH_SUMMARY: StatisticsMonthSummary = {
totalRecordMinutes: 5340,
activeDayCount: 26,
averageRecordedMinutes: 205,
completedTodoCount: 52,
totalTodoCount: 52,
};
🤖 Prompt for 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.

In `@apps/timo-web/app/`[locale]/(main)/statistics/_mocks/statistics-calendar.ts
around lines 55 - 61, MOCK_STATISTICS_MONTH_SUMMARY의 월간 요약 값이 일별 목 데이터와 일관되지
않습니다. MOCK_COMPLETION_RATES의 유효 일수와 일별 상세 데이터의 todo 개수를 기준으로 activeDayCount를 26,
totalTodoCount를 52로 맞추고, 일별 totalRecordMinutes 합계인 5340과 activeDayCount를 기준으로
totalRecordMinutes 및 averageRecordedMinutes를 조정하세요.

"sidePanel": {
"monthTotalRecordTime": "Total record time this month",
"activeDays": "Active days",
"activeDayCount": "{count} days",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

activeDayCount에 ICU 복수형을 적용해주세요.

현재 "{count} days"는 count가 1일 때 "1 days"가 되어 문법적으로 올바르지 않습니다. next-intl의 ICU MessageFormat 복수형 규칙을 사용해주세요.

💚 제안하는 수정
-      "activeDayCount": "{count} days",
+      "activeDayCount": "{count, plural, one {# day} other {# days}}",

참고: next-intl ICU MessageFormat 문서

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"activeDayCount": "{count} days",
"activeDayCount": "{count, plural, one {# day} other {# days}}",
🤖 Prompt for 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.

In `@apps/timo-web/messages/en.json` at line 43, Update the activeDayCount message
to use ICU pluralization, selecting the singular “day” when count equals 1 and
the plural “days” otherwise, while preserving the count value in both variants.

"accumulatedTasks": "Accumulated tasks",
"dayTotalRecordTime": "Total record time today",
"plan": "Plan",
"overtime": "+Overdue",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

"Overdue"를 "Overtime"으로 수정해주세요.

한국어 "초과"는 계획 시간을 초과했음을 의미하지만, 영어 "Overdue"는 "기한이 지남"을 뜻합니다. 이 맥락에서는 "Overtime" 또는 "Over"가 올바른 번역입니다.

💚 제안하는 수정
-      "overtime": "+Overdue",
+      "overtime": "+Overtime",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"overtime": "+Overdue",
"overtime": "+Overtime",
🤖 Prompt for 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.

In `@apps/timo-web/messages/en.json` at line 48, Update the "overtime" translation
value in the messages/en.json localization resource from "+Overdue" to
"+Overtime" (or "+Over") to accurately represent exceeding the planned time.

@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: 1

🤖 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/_utils/format-statistics-time.ts:
- Around line 12-25: Guard negative inputs in both formatStatisticsHourText and
formatStatisticsClockText by normalizing minutes to a nonnegative value before
performing time calculations. Preserve the existing formatting behavior for zero
and positive inputs, and ensure negative values cannot produce negative hour,
minute, or clock components.
🪄 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: 5d219b60-ae7e-43a5-86a7-dc06d50b348a

📥 Commits

Reviewing files that changed from the base of the PR and between dea7333 and faba532.

📒 Files selected for processing (4)
  • apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsCalendar.tsx
  • 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/_utils/format-statistics-time.ts

@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.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1

🤖 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/_utils/format-statistics-time.ts:
- Around line 12-25: Guard negative inputs in both formatStatisticsHourText and
formatStatisticsClockText by normalizing minutes to a nonnegative value before
performing time calculations. Preserve the existing formatting behavior for zero
and positive inputs, and ensure negative values cannot produce negative hour,
minute, or clock components.
🪄 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: 5d219b60-ae7e-43a5-86a7-dc06d50b348a

📥 Commits

Reviewing files that changed from the base of the PR and between dea7333 and faba532.

📒 Files selected for processing (4)
  • apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsCalendar.tsx
  • 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/_utils/format-statistics-time.ts
🛑 Comments failed to post (1)
apps/timo-web/app/[locale]/(main)/statistics/_utils/format-statistics-time.ts (1)

12-25: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

음수 입력값에 대한 가드가 없습니다.

두 함수 모두 minutes가 음수일 경우 예상치 못한 결과를 반환합니다. 예를 들어 formatStatisticsHourText(-30)"-1h -30m"을, formatStatisticsClockText(-90)"1:-30"을 반환합니다. 현재 목 데이터에서는 음수가 들어올 가능성이 낮지만, 방어적 차원에서 early return이나 Math.max(0, minutes) 처리를 고려해보세요.

참고: MDN — Math.max()

Also applies to: 37-42

🤖 Prompt for 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.

In
`@apps/timo-web/app/`[locale]/(main)/statistics/_utils/format-statistics-time.ts
around lines 12 - 25, Guard negative inputs in both formatStatisticsHourText and
formatStatisticsClockText by normalizing minutes to a nonnegative value before
performing time calculations. Preserve the existing formatting behavior for zero
and positive inputs, and ensure negative values cannot produce negative hour,
minute, or clock components.

@yumin-kim2 yumin-kim2 changed the title [FEAT] 통계 페이지 뷰 구현 (PR수정중) [FEAT] 통계 페이지 뷰 구현 Jul 11, 2026

@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 thread apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx Outdated
Comment thread apps/timo-web/app/[locale]/(main)/statistics/_containers/StatisticsContainer.tsx Outdated
Comment thread apps/timo-web/app/[locale]/(main)/statistics/_containers/StatisticsContainer.tsx Outdated
yumin-kim2 and others added 2 commits July 12, 2026 15:15
Co-authored-by: 김민아 <kmina121777@naver.com>
Co-authored-by: 김민아 <kmina121777@naver.com>
- develop 병합 후 공용 date 유틸로 이동한 formatDateKey import 경로를 반영했습니다

@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.

API 연결까지 고려해서 설계해주신 게 느껴졌어요 이제 진짜 뷰 마감이 보이네요, 고생하셨습니다~

크리티컬 이슈는 아닌데 나중에 한번 고민해보시면 좋을 것 같은 부분들 코멘트 남겨뒀어요, 확인해주세요 😊

Comment thread apps/timo-web/app/[locale]/(main)/statistics/_containers/StatisticsContainer.tsx Outdated
Comment thread apps/timo-web/app/[locale]/(main)/statistics/_containers/StatisticsContainer.tsx Outdated
@yumin-kim2 yumin-kim2 merged commit 2d480a7 into develop Jul 12, 2026
14 checks passed
@yumin-kim2 yumin-kim2 deleted the feat/web/142-statistics-calendar-view branch July 12, 2026 10:12

@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.

♻️ Duplicate comments (3)
apps/timo-web/app/[locale]/(main)/statistics/_containers/StatisticsHeaderContainer.tsx (1)

22-24: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

formatStatisticsMonth 유틸 재사용 건은 여전히 유효합니다.

이전 리뷰에서 제안드린 내용이 현재 코드에 반영되지 않았습니다. StatisticsCalendar.tsx에서 사용하는 formatStatisticsMonth(currentMonth, locale)와 동일한 로직을 인라인으로 중복 작성하고 있습니다.

♻️ 제안 수정안
+ import { formatStatisticsMonth } from "../_utils/format-statistics-date";
  ...
  const locale = useLocale();
- const monthLabel = new Intl.DateTimeFormat(locale, {
-   month: "long",
- }).format(currentMonth);
+ const monthLabel = formatStatisticsMonth(currentMonth, locale);

As per coding guidelines, **/*.{ts,tsx}: "절대 경로 import 사용 (상대 경로 ../../ 지양)" — formatStatisticsMonth를 공용 유틸로 통합하면 중복 로직을 제거할 수 있습니다.

🤖 Prompt for 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.

In
`@apps/timo-web/app/`[locale]/(main)/statistics/_containers/StatisticsHeaderContainer.tsx
around lines 22 - 24, StatisticsHeaderContainer의 인라인 Intl.DateTimeFormat 월 포맷
로직을 제거하고, StatisticsCalendar.tsx에서 사용하는 공용 formatStatisticsMonth(currentMonth,
locale) 유틸을 절대 경로 import로 재사용하세요.
apps/timo-web/messages/en.json (2)

100-100: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

activeDayCount ICU 복수형 적용 건은 여전히 유효합니다.

이전 리뷰에서 제안드린 ICU MessageFormat 복수형 규칙이 아직 반영되지 않았습니다. count가 1일 때 "1 days"가 되어 문법적으로 올바르지 않습니다.

💚 제안하는 수정
-      "activeDayCount": "{count} days",
+      "activeDayCount": "{count, plural, one {# day} other {# days}}",

참고: next-intl ICU MessageFormat 문서

🤖 Prompt for 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.

In `@apps/timo-web/messages/en.json` at line 100, Update the activeDayCount
message to use ICU MessageFormat pluralization so count 1 renders “1 day” and
other counts render “{count} days,” preserving the existing count interpolation.

105-105: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

"Overdue" → "Overtime" 수정 건도 여전히 유효합니다.

한국어 "초과"는 계획 시간 초과를 의미하지만, 영어 "Overdue"는 "기한이 지남"을 뜻합니다. 이 맥락에서는 "Overtime"이 올바른 번역입니다.

💚 제안하는 수정
-      "overtime": "+Overdue",
+      "overtime": "+Overtime",
🤖 Prompt for 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.

In `@apps/timo-web/messages/en.json` at line 105, Update the overtime translation
value in the messages resource from “Overdue” to “Overtime”, preserving the
existing “+” prefix and key.
🤖 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.

Duplicate comments:
In
`@apps/timo-web/app/`[locale]/(main)/statistics/_containers/StatisticsHeaderContainer.tsx:
- Around line 22-24: StatisticsHeaderContainer의 인라인 Intl.DateTimeFormat 월 포맷 로직을
제거하고, StatisticsCalendar.tsx에서 사용하는 공용 formatStatisticsMonth(currentMonth,
locale) 유틸을 절대 경로 import로 재사용하세요.

In `@apps/timo-web/messages/en.json`:
- Line 100: Update the activeDayCount message to use ICU MessageFormat
pluralization so count 1 renders “1 day” and other counts render “{count} days,”
preserving the existing count interpolation.
- Line 105: Update the overtime translation value in the messages resource from
“Overdue” to “Overtime”, preserving the existing “+” prefix and key.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 78793cb3-4d34-4cec-b1d9-cb59dd663fa9

📥 Commits

Reviewing files that changed from the base of the PR and between 4cdc567 and bd554bf.

📒 Files selected for processing (6)
  • apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsCalendar.tsx
  • apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsSidePanel.tsx
  • apps/timo-web/app/[locale]/(main)/statistics/_containers/StatisticsContainer.tsx
  • apps/timo-web/app/[locale]/(main)/statistics/_containers/StatisticsHeaderContainer.tsx
  • apps/timo-web/messages/en.json
  • apps/timo-web/messages/ko.json

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