Skip to content

[Refactor/#86] 통합 대시보드 피드백 반영 - #87

Merged
Seojegyeong merged 16 commits into
developfrom
refactor/#86
Mar 10, 2026
Merged

[Refactor/#86] 통합 대시보드 피드백 반영#87
Seojegyeong merged 16 commits into
developfrom
refactor/#86

Conversation

@Seojegyeong

@Seojegyeong Seojegyeong commented Mar 8, 2026

Copy link
Copy Markdown
Collaborator

🚨 관련 이슈

Closes #86

✨ 변경사항

  • 🐞 BugFix Something isn't working
  • 💻 CrossBrowsing Browser compatibility
  • 🌏 Deploy Deploy
  • 🎨 Design Markup & styling
  • 📃 Docs Documentation writing and editing (README.md, etc.)
  • ✨ Feature Feature
  • 🔨 Refactor Code refactoring
  • ⚙️ Setting Development environment setup
  • ✅ Test Test related (storybook, jest, etc.)

✏️ 작업 내용

통합 대시보드 UI 구현

1. TrafficChart — 실시간 트래픽 차트

  • [ApexCharts] area 차트
  • X축: 00:00~24:00, 6시간 간격 레이블만 표시
  • Y축: K 단위 변환, 0 숨김
  1. BudgetGaugeChart — 예산 소진 게이지
  • 안정(초록) / 주의(노랑) / 위험(빨강) 3단계 상태
  • 진행 바 + 잔액 카드로 구성
  1. PlatformComparison — 플랫폼별 비교
    (1) 왼쪽: PlatformComparisonChart — Google/NAVER/kakao 바 차트
    (2) 오른쪽: PlatformRoasTable — ROAS 순위 테이블
  • 각각의 행 클릭 시 모두 플랫폼 별 대시보드로 이동

통합 대시보드 피드백 수정

  1. Toast 컴포넌트 제거: sonner 라이브러리의 toast.success / toast.error 로 교체
  2. BudgetGaugeChart에서 totalBudget === 0 일 때 나눗셈 오류나는 문제 방어 로직 추가
  3. PlatformRoasTable: 접근성 향상 위해서 button으로 교체
  4. 기타 UI 개선

스크린샷

2026-03-09.3.53.29.mov

CaptureX_2026-03-09_155452_localhost
CaptureX_2026-03-09_155509_localhost

📂 폴더 구조

src/
├── pages/
│   └── dashboard/
│       ├── overview/
│       │   ├── OverviewDashboard.tsx        # 메인 통합 대시보드 페이지
│       │   ├── OverviewAiReportPanel.tsx    # AI 리포트 드로어 콘텐츠
│       │   ├── overview.mock.ts             # KPI 목업 데이터
│       │   └── aiReport.mock.ts             # AI 리포트 목업 데이터
│       ├── platform/
│       │   └── PlatformDashboard.tsx        # 플랫폼 대시보드 페이지 (미구현)
│       └── timeline/
│           └── Timeline.tsx
│
├── components/
│   ├── dashboard/
│   │   ├── charts/
│   │   │   ├── TrafficChart.tsx             # 실시간 트래픽 변화 차트
│   │   │   ├── trafficChart.mock.ts
│   │   │   ├── BudgetGaugeChart.tsx         # 예산 소진 현황 게이지
│   │   │   └── budgetGaugeChart.mock.ts
│   │   └── platform/
│   │       ├── PlatformComparison.tsx       # 플랫폼별 비교 섹션 
│   │       ├── PlatformComparisonChart.tsx  # 플랫폼 순위 바 차트
│   │       ├── PlatformRoasTable.tsx        # ROAS 성과 순위 테이블
│   │       └── platformComparison.mock.ts
│   │
│   └── common/
│       ├── card/
│       │   ├── Card.tsx                     # 공용 카드 컴포넌트
│       │   └── StatCard.tsx                 # KPI 통계 카드
│       ├── chart/
│       │   └── ChartLegend.tsx              # 차트 범례 컴포넌트
│       └── drawer/
│           └── Drawer.tsx                   # AI 패널 드로어
│
├── types/
│   └── dashboard/
│       └── overview.ts                      # IKpiMetric, IOverviewData 타입
│
└── assets/

😅 미완성 작업

  • 통합 대시보드 API 연동 예정
  • 이상 클릭 탐지 기능 구현 예정

📢 논의 사항 및 참고 사항

(자료 제출 마감이 임박해 PR 범위가 넓어졌습니다..죄송합니다ㅠㅠ)

  1. 디자인 수정 피드백 요청
    UI 구현 과정에서 예산 소진 현황 카드 및 플랫폼 비교 카드 디자인 일부 수정했습니다. 함께 피드백 남겨주시면 감사하겠습니다!!!

  2. 통합 필요한 부분
    아이콘 의미에 맞지 않는 네이밍 및 중복 사용되는 구간이 있는 것 같아 전체적으로 정리 필요할 것 같습니다.
    KPI 카드의 trend up, down 에 따라 다른 의미를 가질 수 있으니 색상에 대해서 의미 정리 필요할 것 같습니다.

  3. 차트 라이브러리 관련 논의 내용
    지금 사용하고 있는 apexcharts 라이브러리가 SVG 기반이라 스크롤 시 DOM 재계산 비용이 크고, 번들도 ~450KB로 무거워 초기 로딩 및 스크롤 속도가 느린 것 같습니다.
    지금 즉시 적용 가능한 부분은 React.lazy + Suspense으로 초기 번들에서 분리하거나
    그래프가 더 많아질 경우에는 아예 Canvas 기반인 Chart.js 라이브러리로 교체하는 방법이 있을 것 같습니다.
    어떤 방식이 좋을지 의견 부탁드립니다!

💬 리뷰어 가이드 (P-Rules)
P1: 필수 반영 (Critical) - 버그 가능성, 컨벤션 위반. 해결 전 머지 불가.
P2: 적극 권장 (Recommended) - 더 나은 대안 제시. 가급적 반영 권장.
P3: 제안 (Suggestion) - 아이디어 공유. 반영 여부는 드라이버 자율.
P4: 단순 확인/칭찬 (Nit) - 사소한 오타, 칭찬 등 피드백.

Summary by CodeRabbit

릴리스 노트

  • 접근성 개선
    • 차트에 ARIA 역할/레이블 추가 및 게이지에 접근성 속성 추가
  • UI/UX 개선
    • 예산 게이지에 애니메이션, 상태별 색상, 초과 지출 표시 적용
    • 범례 렌더링 안정성 개선(항목 키를 레이블로 변경)
    • AI 리포트 패널의 타이포그래피·간격 정리
    • 플랫폼 표 행의 클릭 네비게이션 제거
  • 성능/최적화
    • 일부 차트 컨테이너에 브라우저 최적화 힌트 추가
  • 애니메이션/스타일
    • 그래프 및 섀머 애니메이션을 높이 기반에서 transform/scale로 전환
  • 알림 시스템 업그레이드
    • 로컬 토스트 컴포넌트 제거 및 통합 토스트 라이브러리로 전환

@Seojegyeong
Seojegyeong requested review from YermIm and jjjsun March 8, 2026 13:28
@Seojegyeong Seojegyeong self-assigned this Mar 8, 2026
@Seojegyeong Seojegyeong linked an issue Mar 8, 2026 that may be closed by this pull request
2 tasks
@coderabbitai

coderabbitai Bot commented Mar 8, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

로컬 Toast 컴포넌트 제거 및 sonner 통합, 렌더 키 변경(인덱스→라벨/타이틀), 차트 접근성·애니메이션 개선 및 렌더 성능 힌트 추가, 플랫폼 테이블의 클릭 네비게이션 제거, 타이포그래피·애니메이션 CSS 조정이 적용되었습니다.

Changes

Cohort / File(s) Summary
Legend 렌더링 안정화
src/components/common/chart/ChartLegend.tsx
리스트 렌더링 시 key를 인덱스에서 item.label로 변경하여 항목 재정렬/재마운트 안정성 개선.
로컬 Toast 제거 → sonner 통합
src/components/common/toast/Toast.tsx, src/pages/dashboard/overview/OverviewDashboard.tsx
로컬 Toast 컴포넌트 파일과 해당 타입/인터페이스/기본 export 삭제. OverviewDashboard에서 로컬 토스트 사용을 제거하고 sonnertoast 호출로 대체하며 로컬 날짜 렌더링을 useMemo로 캐시화.
예산 게이지 차트 접근성·애니메이션
src/components/dashboard/charts/BudgetGaugeChart.tsx
총예산 0 보호 로직과 isOverBudget 처리 추가, requestAnimationFrame 기반 마운트 애니메이션 도입, progressbar에 ARIA 속성(aria-valuenow/min/max/label/text) 및 시각·색상·텍스트 변경 반영.
차트 래핑 접근성
src/components/dashboard/charts/TrafficChart.tsx
차트 출력물을 role="img" 및 aria-label로 래핑해 대체 텍스트 제공(데이터/렌더링 로직 불변).
플랫폼 테이블 상호작용 단순화
src/components/dashboard/platform/PlatformRoasTable.tsx
useNavigate 및 행 클릭 네비게이션 제거. 클릭 관련 클래스(cursor-pointer, active transform 등) 제거하고 hover 시 시각 피드백만 유지.
AI 리포트 타이포·키 안정화
src/pages/dashboard/overview/OverviewAiReportPanel.tsx
폰트/타이포그래피 클래스 정리(명시적 px 제거). data.sections 매핑 시 key를 index에서 section.title로 변경.
렌더 성능 힌트 추가
src/components/dashboard/platform/PlatformComparisonChart.tsx
차트 컨테이너에 will-change: transform 스타일 추가(렌더 최적화 힌트, 로직 변경 없음).
애니메이션·셔머 CSS 리워크
src/index.css, src/components/auth/intro/IntroAIAnalytics.tsx
그래프 업 애니메이션을 height 기반에서 transform(scaleY) 기반으로 전환, shimmer 애니메이션을 transform 기반 오버레이(::after)로 재구성, IntroAIAnalytics의 비활성 바 숨김을 height→scaleY transform으로 변경.

Sequence Diagram(s)

(생성 조건에 부합하지 않아 생략합니다.)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

🎨 Html&css, ✨ Feature

Suggested reviewers

  • jjjsun
  • YermIm
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 주요 변경사항을 명확하게 반영하고 있습니다. 통합 대시보드 피드백 반영이 이 PR의 핵심 목표이며, 실제 변경사항들(Toast 제거, 접근성 개선, UI 최적화 등)과 일치합니다.
Linked Issues check ✅ Passed PR의 코드 변경사항들이 이슈 #86의 목표와 일치합니다. Toast 컴포넌트 제거 및 sonner 라이브러리 적용, 예산 차트 방어 로직 추가, PlatformRoasTable 접근성 개선, CSS 애니메이션 GPU 가속 처리 등 팀 리뷰 및 CodeRabbit 피드백 반영이 구현되었습니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 이슈 #86의 범위 내에 있습니다. 통합 대시보드 UI 개선, 접근성 강화, 성능 최적화(GPU 가속), 상태 관리 개선 등 모두 명시된 목표와 관련이 있습니다.
Description check ✅ Passed PR 설명이 템플릿의 주요 섹션(관련 이슈, 변경사항, 작업 내용, 미완성 작업, 논의 사항)을 모두 포함하고 있으며, 구체적인 작업 내용과 스크린샷을 제공하고 있습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/#86

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 and usage tips.

@github-actions

github-actions Bot commented Mar 8, 2026

Copy link
Copy Markdown

📚 Storybook 배포 완료

항목 링크
📖 Storybook https://69a147b60a56365d9e2185ef-dussjwatcj.chromatic.com/
🔍 Chromatic https://www.chromatic.com/build?appId=69a147b60a56365d9e2185ef&number=42

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/dashboard/charts/BudgetGaugeChart.tsx (1)

29-37: ⚠️ Potential issue | 🟠 Major

totalBudget === 0일 때 상태가 반대로 표시됩니다.

분모 예외를 막는 건 좋지만, spent > 0인 경우에도 percentage를 0으로 고정해서 상단이 0% / 안정으로 보입니다. 예산이 0인데 지출이 발생한 상태는 사실상 즉시 위험으로 처리돼야 해서, 이 케이스를 별도 분기하지 않으면 사용자가 현재 상태를 반대로 이해하게 됩니다.

수정 예시
-  const percentage =
-    totalBudget > 0 ? Math.round((spent / totalBudget) * 100) : 0;
-  const remaining = Math.max(0, totalBudget - spent);
-  const isOverBudget = spent > totalBudget;
+  const balance = totalBudget - spent;
+  const hasBudget = totalBudget > 0;
+  const isOverBudget = balance < 0;
+  const percentage = hasBudget
+    ? Math.round((spent / totalBudget) * 100)
+    : isOverBudget
+      ? 100
+      : 0;
+  const remaining = Math.max(0, balance);
 
   const getStatus = () => {
+    if (!hasBudget && spent > 0) return "위험";
     if (percentage >= dangerThreshold) return "위험";
     if (percentage >= warningThreshold) return "주의";
     return "안정";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/dashboard/charts/BudgetGaugeChart.tsx` around lines 29 - 37,
The status logic misreports when totalBudget === 0 and spent > 0; update the
percentage calculation and getStatus to treat a zero budget with positive
spending as over-budget: change percentage to totalBudget > 0 ?
Math.round((spent / totalBudget) * 100) : (spent > 0 ? 100 : 0), and in
getStatus add an explicit branch that returns "위험" when totalBudget === 0 &&
spent > 0 (or simply use isOverBudget || (totalBudget === 0 && spent > 0))
before checking dangerThreshold and warningThreshold so getStatus, percentage,
and isOverBudget/remaining reflect the zero-budget-over-spent case correctly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/dashboard/charts/BudgetGaugeChart.tsx`:
- Around line 31-32: The chart currently clamps remaining to zero (const
remaining = Math.max(0, totalBudget - spent)) and always shows ₩0 when over
budget; change logic in BudgetGaugeChart so when isOverBudget (const
isOverBudget = spent > totalBudget) you compute and display an overage amount
(e.g., overage = spent - totalBudget) and use that value for the "초과 지출"
card/label instead of remaining; update any rendering branches that show
remaining (including the block around the existing label logic and the similar
code at lines referenced 118-127) to choose remaining when not over budget and
overage when isOverBudget. Ensure formatting/currency is applied consistently.

In `@src/components/dashboard/charts/TrafficChart.tsx`:
- Around line 86-93: The chart currently only exposes an aria-label on the
container, so screen readers get the title but not the underlying data; update
the TrafficChart component to provide a true accessible alternative by adding a
visually-hidden summary and/or a hidden data table generated from the series and
options values (use the existing series and options props to build the text),
connect it to the chart via aria-describedby, and keep the visual chart
(ReactApexChart) aria-hidden if needed; ensure the summary uses your app's
"sr-only" CSS class and the table includes timestamps and click counts so
assistive tech can read the actual trend and numbers.

In `@src/components/dashboard/platform/PlatformRoasTable.tsx`:
- Around line 39-42: The row button currently calls navigate("/platform") and
drops the clicked platform context; update the onClick in PlatformRoasTable so
it passes platform.name to the destination (e.g., as a path parameter, a query
parameter, or via navigation state) instead of a static "/platform" URL; locate
the button with key platform.name and replace the navigate call so the
destination can reconstruct the selected platform (use encodeURIComponent for
safety if embedding in a URL) and ensure the target route/component reads that
param/query/state to restore the selected platform.

---

Outside diff comments:
In `@src/components/dashboard/charts/BudgetGaugeChart.tsx`:
- Around line 29-37: The status logic misreports when totalBudget === 0 and
spent > 0; update the percentage calculation and getStatus to treat a zero
budget with positive spending as over-budget: change percentage to totalBudget >
0 ? Math.round((spent / totalBudget) * 100) : (spent > 0 ? 100 : 0), and in
getStatus add an explicit branch that returns "위험" when totalBudget === 0 &&
spent > 0 (or simply use isOverBudget || (totalBudget === 0 && spent > 0))
before checking dangerThreshold and warningThreshold so getStatus, percentage,
and isOverBudget/remaining reflect the zero-budget-over-spent case correctly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0c12e541-2030-43ab-977c-77872f91f8fd

📥 Commits

Reviewing files that changed from the base of the PR and between b1ee3e7 and 1fa4bac.

📒 Files selected for processing (7)
  • src/components/common/chart/ChartLegend.tsx
  • src/components/common/toast/Toast.tsx
  • src/components/dashboard/charts/BudgetGaugeChart.tsx
  • src/components/dashboard/charts/TrafficChart.tsx
  • src/components/dashboard/platform/PlatformRoasTable.tsx
  • src/pages/dashboard/overview/OverviewAiReportPanel.tsx
  • src/pages/dashboard/overview/OverviewDashboard.tsx
💤 Files with no reviewable changes (1)
  • src/components/common/toast/Toast.tsx

Comment thread src/components/dashboard/charts/BudgetGaugeChart.tsx Outdated
Comment thread src/components/dashboard/charts/TrafficChart.tsx Outdated
Comment thread src/components/dashboard/platform/PlatformRoasTable.tsx Outdated

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/dashboard/charts/BudgetGaugeChart.tsx`:
- Around line 29-32: The status/percentage logic in BudgetGaugeChart is
inconsistent when totalBudget === 0: percentage is forced to 0 while
isOverBudget can be true, causing contradictory UI. Update the computations in
BudgetGaugeChart so the three values are computed together: determine
isOverBudget = spent > totalBudget || (totalBudget === 0 && spent > 0); compute
percentage = totalBudget > 0 ? Math.round((spent / totalBudget) * 100) :
(isOverBudget ? 100 : 0); and compute remaining = isOverBudget ? Math.abs(spent
- totalBudget) : Math.max(totalBudget - spent, 0); ensure any downstream
status/label logic uses these unified values so the badge, percent display, and
helper text remain consistent.
- Around line 73-78: The gauge currently clamps displayed percentage for
assistive tech by using Math.min(percentage, 100) for aria-valuenow and
aria-label; update BudgetGaugeChart to keep aria-valuenow as
Math.min(percentage, 100) but add an aria-valuetext that exposes the actual
percentage and when it exceeds 100 (e.g., "120% (over budget)") so screen
readers get the true value and overage status while preserving expected 0–100
range in aria-valuenow; reference the percentage variable and the element
rendering the progressbar to add aria-valuetext accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9caaa967-e750-43cb-b0f4-6061e3dce670

📥 Commits

Reviewing files that changed from the base of the PR and between 1fa4bac and 6f68ae6.

📒 Files selected for processing (2)
  • src/components/dashboard/charts/BudgetGaugeChart.tsx
  • src/components/dashboard/platform/PlatformRoasTable.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/dashboard/platform/PlatformRoasTable.tsx

Comment thread src/components/dashboard/charts/BudgetGaugeChart.tsx
Comment thread src/components/dashboard/charts/BudgetGaugeChart.tsx

@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 (1)
src/components/dashboard/charts/BudgetGaugeChart.tsx (1)

29-40: ⚠️ Potential issue | 🟡 Minor

totalBudget === 0일 때 상태 표시 불일치 문제가 남아있습니다.

현재 로직에서 totalBudget === 0이고 spent > 0인 경우:

  • percentage = 0 (분모 0 방어)
  • isOverBudget = true (spent > 0 > totalBudget)
  • status = "안정" (percentage가 0이므로)

결과적으로 상단 뱃지는 "안정"으로 표시되지만, 하단 카드는 "초과 지출"로 표시되어 사용자에게 모순된 정보를 전달합니다. API 연동 시 예산 데이터가 0으로 들어올 수 있으므로, 이 케이스를 명시적으로 처리하는 것이 좋습니다.

수정 제안
  const percentage =
    totalBudget > 0 ? Math.round((spent / totalBudget) * 100) : 0;
- const isOverBudget = spent > totalBudget;
+ const isOverBudget = spent > totalBudget || (totalBudget === 0 && spent > 0);
  const remaining = isOverBudget ? spent - totalBudget : totalBudget - spent;

  const getStatus = () => {
+   // totalBudget이 0인데 지출이 있으면 위험 상태로 처리
+   if (totalBudget === 0 && spent > 0) return "위험";
    if (percentage >= dangerThreshold) return "위험";
    if (percentage >= warningThreshold) return "주의";
    return "안정";
  };

코딩 가이드라인에 따라 "에러 처리: API 실패 대응 및 사용자 피드백 적절성 검토"를 준수해야 합니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/dashboard/charts/BudgetGaugeChart.tsx` around lines 29 - 40,
The status logic is inconsistent when totalBudget === 0 and spent > 0
(percentage is 0 but isOverBudget is true), so update getStatus to explicitly
treat over-budget-zero-budget cases: reference totalBudget, spent, isOverBudget,
percentage, getStatus and status and make getStatus return the
over-budget/danger state when isOverBudget or (totalBudget === 0 && spent > 0),
otherwise use the existing percentage threshold checks; ensure the computed
status aligns with the remaining/isOverBudget display elsewhere.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/components/dashboard/charts/BudgetGaugeChart.tsx`:
- Around line 29-40: The status logic is inconsistent when totalBudget === 0 and
spent > 0 (percentage is 0 but isOverBudget is true), so update getStatus to
explicitly treat over-budget-zero-budget cases: reference totalBudget, spent,
isOverBudget, percentage, getStatus and status and make getStatus return the
over-budget/danger state when isOverBudget or (totalBudget === 0 && spent > 0),
otherwise use the existing percentage threshold checks; ensure the computed
status aligns with the remaining/isOverBudget display elsewhere.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: cc7e3c7f-7c47-44ea-aa12-e3f06f874142

📥 Commits

Reviewing files that changed from the base of the PR and between 6f68ae6 and 273ea69.

📒 Files selected for processing (1)
  • src/components/dashboard/charts/BudgetGaugeChart.tsx

@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 (1)
src/components/dashboard/charts/TrafficChart.tsx (1)

86-96: ⚠️ Potential issue | 🟠 Major

차트 이름만 노출되고 실제 데이터는 여전히 읽히지 않아요.

Line 87-88의 role="img" + aria-label만으로는 스크린리더가 차트 제목만 읽고, 시간대별 클릭수/추세 자체는 전달하지 못합니다. 숨김 요약이나 숨김 테이블을 추가해서 aria-describedby로 연결하고, 시각 차트는 별도 래퍼에서 aria-hidden 처리하는 쪽으로 마무리해 주세요.

접근성 대체 표현 예시
 export default function TrafficChart() {
+  const descriptionId = "traffic-chart-description";
+
   return (
     <div
       role="img"
       aria-label="실시간 트래픽 변화 차트: 시간대별 클릭수 추이"
+      aria-describedby={descriptionId}
       style={{ willChange: "transform" }}
     >
-      <ReactApexChart
-        type="area"
-        options={options}
-        series={series}
-        height={360}
-      />
+      <div id={descriptionId} className="sr-only">
+        {labels
+          .map((label, i) => `${label} 클릭수 ${clicks[i].toLocaleString()}회`)
+          .join(", ")}
+      </div>
+      <div aria-hidden="true">
+        <ReactApexChart
+          type="area"
+          options={options}
+          series={series}
+          height={360}
+        />
+      </div>
     </div>
   );
 }

As per coding guidelines, "접근성: 시맨틱 HTML, ARIA 속성 사용 확인."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/dashboard/charts/TrafficChart.tsx` around lines 86 - 96, The
visual chart currently only exposes a title via role="img" and aria-label;
update the TrafficChart component to provide a hidden textual summary and/or
hidden data table (describing time buckets and click counts and trend) and
connect it with aria-describedby on the chart wrapper, and mark the visual chart
element (the ReactApexChart wrapper) aria-hidden="true" so screen readers ignore
the SVG; ensure the hidden summary/table is kept in the same component (near
ReactApexChart) and references the chart's series/options data to produce the
descriptive text, and use stable IDs (e.g., chartSummaryId, chartDataTableId) to
link aria-describedby to the hidden element(s).
🧹 Nitpick comments (1)
src/components/dashboard/platform/PlatformComparisonChart.tsx (1)

115-122: willChange: "transform" 적용에 대한 참고 사항

스크롤 성능 개선을 위한 willChange 적용 의도는 이해되지만, 몇 가지 고려할 점이 있습니다:

  1. will-change는 브라우저에게 레이어 승격(compositing layer)을 요청하여 GPU 메모리를 지속적으로 점유합니다.
  2. 정적 차트처럼 실제 transform 애니메이션이 빈번하지 않은 경우, 상시 적용보다는 스크롤/애니메이션 직전에 동적으로 적용하고 완료 후 제거하는 것이 권장됩니다.
  3. 현재 대시보드에 여러 차트가 있다면, 모든 차트에 will-change를 적용 시 메모리 오버헤드가 누적될 수 있습니다.

현재 적용이 체감 성능 향상에 기여한다면 유지해도 괜찮지만, 실제 효과가 미미하다면 제거를 고려해 주세요.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/dashboard/platform/PlatformComparisonChart.tsx` around lines
115 - 122, The inline style willChange: "transform" on the wrapper div in
PlatformComparisonChart can cause persistent GPU layer allocation; either remove
the static will-change or apply it dynamically only during interactions: update
the PlatformComparisonChart component to stop setting style={{ willChange:
"transform" }} by default, and instead add a short-lived application via a hook
or event handlers (e.g., set will-change on the chart wrapper just before
scroll/hover/animation and remove it after a short timeout or on
mouseLeave/scroll end) using useEffect or local state tied to events around
ReactApexChart to ensure the property is applied only when needed to avoid
memory overhead when many charts are rendered.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/components/dashboard/charts/TrafficChart.tsx`:
- Around line 86-96: The visual chart currently only exposes a title via
role="img" and aria-label; update the TrafficChart component to provide a hidden
textual summary and/or hidden data table (describing time buckets and click
counts and trend) and connect it with aria-describedby on the chart wrapper, and
mark the visual chart element (the ReactApexChart wrapper) aria-hidden="true" so
screen readers ignore the SVG; ensure the hidden summary/table is kept in the
same component (near ReactApexChart) and references the chart's series/options
data to produce the descriptive text, and use stable IDs (e.g., chartSummaryId,
chartDataTableId) to link aria-describedby to the hidden element(s).

---

Nitpick comments:
In `@src/components/dashboard/platform/PlatformComparisonChart.tsx`:
- Around line 115-122: The inline style willChange: "transform" on the wrapper
div in PlatformComparisonChart can cause persistent GPU layer allocation; either
remove the static will-change or apply it dynamically only during interactions:
update the PlatformComparisonChart component to stop setting style={{
willChange: "transform" }} by default, and instead add a short-lived application
via a hook or event handlers (e.g., set will-change on the chart wrapper just
before scroll/hover/animation and remove it after a short timeout or on
mouseLeave/scroll end) using useEffect or local state tied to events around
ReactApexChart to ensure the property is applied only when needed to avoid
memory overhead when many charts are rendered.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7a38766a-ce99-4187-ab3b-6466c8292bdd

📥 Commits

Reviewing files that changed from the base of the PR and between 273ea69 and 177ca48.

📒 Files selected for processing (2)
  • src/components/dashboard/charts/TrafficChart.tsx
  • src/components/dashboard/platform/PlatformComparisonChart.tsx

@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 (1)
src/components/dashboard/charts/BudgetGaugeChart.tsx (1)

29-32: ⚠️ Potential issue | 🟠 Major

totalBudget === 0 분기가 아직도 상태 계산과 어긋납니다.

Line 29-32에서는 분모 0만 피하고 있어서, totalBudget가 0이고 spent > 0이면 하단 카드만 초과 지출로 바뀌고 상단은 0% / 안정으로 남습니다. isOverBudget, percentage, remaining은 같은 분기에서 같이 계산하고, 상태 계산도 그 값을 기준으로 맞춰야 화면이 일관됩니다.

수정 예시
-  const percentage =
-    totalBudget > 0 ? Math.round((spent / totalBudget) * 100) : 0;
-  const isOverBudget = spent > totalBudget;
-  const remaining = isOverBudget ? spent - totalBudget : totalBudget - spent;
+  const isOverBudget = totalBudget > 0 ? spent > totalBudget : spent > 0;
+  const percentage =
+    totalBudget > 0
+      ? Math.round((spent / totalBudget) * 100)
+      : isOverBudget
+        ? 100
+        : 0;
+  const remaining = isOverBudget
+    ? Math.max(spent - totalBudget, 0)
+    : Math.max(totalBudget - spent, 0);

   const getStatus = () => {
+    if (isOverBudget) return "위험";
     if (percentage >= dangerThreshold) return "위험";
     if (percentage >= warningThreshold) return "주의";
     return "안정";
   };

As per coding guidelines, "6. 에러 처리: API 실패 대응 및 사용자 피드백 적절성 검토."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/dashboard/charts/BudgetGaugeChart.tsx` around lines 29 - 32,
The three derived values percentage, isOverBudget, and remaining are computed
with inconsistent branching when totalBudget is 0; update BudgetGaugeChart to
compute them together in a single branch: determine isOverBudget as (spent >
totalBudget), and then if totalBudget <= 0 set percentage = isOverBudget ? 100 :
0 and remaining = Math.abs(spent - totalBudget) (or spent when overbudget,
totalBudget - spent when not), so the top gauge and bottom card use the same
state; replace the existing separate calculations of percentage, isOverBudget,
and remaining with this unified logic and ensure any UI state checks reference
these updated variables.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/components/dashboard/charts/BudgetGaugeChart.tsx`:
- Around line 29-32: The three derived values percentage, isOverBudget, and
remaining are computed with inconsistent branching when totalBudget is 0; update
BudgetGaugeChart to compute them together in a single branch: determine
isOverBudget as (spent > totalBudget), and then if totalBudget <= 0 set
percentage = isOverBudget ? 100 : 0 and remaining = Math.abs(spent -
totalBudget) (or spent when overbudget, totalBudget - spent when not), so the
top gauge and bottom card use the same state; replace the existing separate
calculations of percentage, isOverBudget, and remaining with this unified logic
and ensure any UI state checks reference these updated variables.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: afa2b96f-c39b-4ad9-a08e-77b51f54ffe3

📥 Commits

Reviewing files that changed from the base of the PR and between 177ca48 and 850929f.

📒 Files selected for processing (3)
  • src/components/auth/intro/IntroAIAnalytics.tsx
  • src/components/dashboard/charts/BudgetGaugeChart.tsx
  • src/index.css

@WhereYouAd WhereYouAd deleted a comment from github-actions Bot Mar 9, 2026
@WhereYouAd WhereYouAd deleted a comment from github-actions Bot Mar 9, 2026
@WhereYouAd WhereYouAd deleted a comment from github-actions Bot Mar 9, 2026
@WhereYouAd WhereYouAd deleted a comment from github-actions Bot Mar 9, 2026
@WhereYouAd WhereYouAd deleted a comment from github-actions Bot Mar 9, 2026
@WhereYouAd WhereYouAd deleted a comment from github-actions Bot Mar 9, 2026
@WhereYouAd WhereYouAd deleted a comment from github-actions Bot Mar 9, 2026
@YermIm

YermIm commented Mar 9, 2026

Copy link
Copy Markdown
Collaborator

P3: Card 컴포넌트의 제목 부분 폰트를 heading4 정도로 키워도 좋을 것 같습니다! 이번 달 잔액폰트도 키워도 좋을 것 같아요!

@YermIm

YermIm commented Mar 9, 2026

Copy link
Copy Markdown
Collaborator

P2: 플랫폼별 비교에서 호버시 나오는 툴팁이 막대를 가려서 막대가 잘 보이지 않습니다. 막대들의 옆쪽에 나오면 좋을 것 같습니다!

@jjjsun jjjsun left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

P4: 지금 실시간 차트랑 플랫폼별 비교 차트에 hover시에 Chart라고 text가 뜨는데 조금 어색해 보여서 삭제하는걸 추천드립니다!

Comment thread src/components/dashboard/charts/TrafficChart.tsx
Comment thread src/components/dashboard/charts/TrafficChart.tsx
Comment thread src/components/dashboard/charts/TrafficChart.tsx
Comment thread src/components/dashboard/charts/TrafficChart.tsx Outdated
Comment thread src/pages/dashboard/overview/OverviewDashboard.tsx Outdated
Comment thread src/pages/dashboard/overview/OverviewAiReportPanel.tsx Outdated
Comment thread src/components/dashboard/charts/BudgetGaugeChart.tsx
Comment thread src/components/dashboard/platform/PlatformRoasTable.tsx
@jjjsun

jjjsun commented Mar 9, 2026

Copy link
Copy Markdown
Collaborator

차트 라이브러리 관련
저도 확인해보니 ApexCharts가 간편하지만 성능 부분에서 무거워지는 단점이 있더라고요!
현재로서는 바로 chart.js로 전환하기 보다는 react.lazy + suspense로차트 분리최적화를 먼저 진행해보는 것이 좋을것같아요
그다음에 플랫폼별 대시보드를 진행할때 성능이슈가 발생한다면 chart.js로 변경하는걸 한번 더 논의해보는 방향은 어떠세요?
현재로써는 기능적인 이슈가 나타나지않아서 현재 라이브러리 유지하고 분리최적화만 진행하는게 일정 관계상 좋을것같습니다!

@Seojegyeong

Copy link
Copy Markdown
Collaborator Author

P2: 플랫폼별 비교에서 호버시 나오는 툴팁이 막대를 가려서 막대가 잘 보이지 않습니다. 막대들의 옆쪽에 나오면 좋을 것 같습니다!

사실 그래프 안에서만 tooltip이 표시되기 때문에 막대 그래프가 가려질 수 밖에 없습니다ㅠㅠ
호버되는 그래프마다 툴팁의 위치를 다르게 하는건 ApexCharts 기본 옵션으로는 불가능하고 ApexCharts.exec으로 동적으로 position을 바꾸는 방식으로 해야할 것 같은데... 이렇게 해도 막대 그래프가 아예 가려지지 않게 구현은 어려울 것 같습니다.

@Seojegyeong

Seojegyeong commented Mar 9, 2026

Copy link
Copy Markdown
Collaborator Author

차트 라이브러리 관련 저도 확인해보니 ApexCharts가 간편하지만 성능 부분에서 무거워지는 단점이 있더라고요! 현재로서는 바로 chart.js로 전환하기 보다는 react.lazy + suspense로차트 분리최적화를 먼저 진행해보는 것이 좋을것같아요 그다음에 플랫폼별 대시보드를 진행할때 성능이슈가 발생한다면 chart.js로 변경하는걸 한번 더 논의해보는 방향은 어떠세요? 현재로써는 기능적인 이슈가 나타나지않아서 현재 라이브러리 유지하고 분리최적화만 진행하는게 일정 관계상 좋을것같습니다!

지금 react.lazy + suspense로 먼저 최적화를 하고 나중에 라이브러리를 교체하면, 최적화 작업이 두 번 이루어지는 셈이라 전체 비용이 더 커질 것 같습니다.
차트 컴포넌트를 lazy로 분리해놓은 상태에서 라이브러리까지 교체하면 각 컴포넌트마다 API 방식이 달라서 수정 범위가 넓어지고요....

그래서
지금 당장 chart.js로 교체하고 규모가 커지기 전에 한 번에 정리하거나
ApexCharts 유지 + 최적화 없이 진행한 후에 플랫폼별 대시보드 개발 후 성능 이슈 확인 후 최적화 할지 판단
이 두가지 방법이 나을 것 같은데 어떻게 생각하시나요?

@jjjsun

jjjsun commented Mar 9, 2026

Copy link
Copy Markdown
Collaborator

차트 라이브러리 관련 저도 확인해보니 ApexCharts가 간편하지만 성능 부분에서 무거워지는 단점이 있더라고요! 현재로서는 바로 chart.js로 전환하기 보다는 react.lazy + suspense로차트 분리최적화를 먼저 진행해보는 것이 좋을것같아요 그다음에 플랫폼별 대시보드를 진행할때 성능이슈가 발생한다면 chart.js로 변경하는걸 한번 더 논의해보는 방향은 어떠세요? 현재로써는 기능적인 이슈가 나타나지않아서 현재 라이브러리 유지하고 분리최적화만 진행하는게 일정 관계상 좋을것같습니다!

지금 react.lazy + suspense로 먼저 최적화를 하고 나중에 라이브러리를 교체하면, 최적화 작업이 두 번 이루어지는 셈이라 전체 비용이 더 커질 것 같습니다. 차트 컴포넌트를 lazy로 분리해놓은 상태에서 라이브러리까지 교체하면 각 컴포넌트마다 API 방식이 달라서 수정 범위가 넓어지고요....

그래서 지금 당장 chart.js로 교체하고 규모가 커지기 전에 한 번에 정리하거나 ApexCharts 유지 + 최적화 없이 진행한 후에 플랫폼별 대시보드 개발 후 성능 이슈 확인 후 판단 이 두가지 방법이 나을 것 같은데 어떻게 생각하시나요?

그러면 저는 ApexChart 유지하고, 이슈 확인후 판단으로 진행하는것이 좋을것같습니다!

@github-actions

github-actions Bot commented Mar 9, 2026

Copy link
Copy Markdown

📚 Storybook 배포 완료

항목 링크
📖 Storybook https://69a147b60a56365d9e2185ef-npaagtwwzg.chromatic.com/
🔍 Chromatic https://www.chromatic.com/build?appId=69a147b60a56365d9e2185ef&number=50

@jjjsun jjjsun left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

P4:수정사항 확인했습니다! 고생하셨어요!

@YermIm

YermIm commented Mar 9, 2026

Copy link
Copy Markdown
Collaborator

차트 라이브러리 관련 저도 확인해보니 ApexCharts가 간편하지만 성능 부분에서 무거워지는 단점이 있더라고요! 현재로서는 바로 chart.js로 전환하기 보다는 react.lazy + suspense로차트 분리최적화를 먼저 진행해보는 것이 좋을것같아요 그다음에 플랫폼별 대시보드를 진행할때 성능이슈가 발생한다면 chart.js로 변경하는걸 한번 더 논의해보는 방향은 어떠세요? 현재로써는 기능적인 이슈가 나타나지않아서 현재 라이브러리 유지하고 분리최적화만 진행하는게 일정 관계상 좋을것같습니다!

지금 react.lazy + suspense로 먼저 최적화를 하고 나중에 라이브러리를 교체하면, 최적화 작업이 두 번 이루어지는 셈이라 전체 비용이 더 커질 것 같습니다. 차트 컴포넌트를 lazy로 분리해놓은 상태에서 라이브러리까지 교체하면 각 컴포넌트마다 API 방식이 달라서 수정 범위가 넓어지고요....

그래서 지금 당장 chart.js로 교체하고 규모가 커지기 전에 한 번에 정리하거나 ApexCharts 유지 + 최적화 없이 진행한 후에 플랫폼별 대시보드 개발 후 성능 이슈 확인 후 최적화 할지 판단 이 두가지 방법이 나을 것 같은데 어떻게 생각하시나요?

저도 일단 유지하고 개발 후에 판단하는 것이 좋을 것 같습니다!

@YermIm

YermIm commented Mar 9, 2026

Copy link
Copy Markdown
Collaborator

P4: 확인했습니다 고생하셨어요!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🎨 Html&css 마크업 & 스타일링 🔨 Refactor 코드 리팩토링

Projects

None yet

Development

Successfully merging this pull request may close these issues.

♻️ [Refactor] 통합 대시보드 UI 구현 피드백 반영

3 participants