Skip to content

[feature] 관리자 캘린더 Google·Notion 연동 UI 개편 - #1894

Open
seongwon030 wants to merge 15 commits into
develop-fefrom
calendar-sync-modal-ui
Open

[feature] 관리자 캘린더 Google·Notion 연동 UI 개편#1894
seongwon030 wants to merge 15 commits into
develop-fefrom
calendar-sync-modal-ui

Conversation

@seongwon030

@seongwon030 seongwon030 commented Aug 4, 2026

Copy link
Copy Markdown
Member

#️⃣연관된 이슈

없음

📝작업 내용

관리자 캘린더의 Google·Notion 연동 UI를 Figma 시안대로 다시 만들었습니다. 기존에는 캘린더 우측 하단 아이콘 팝오버 안에 연동/해제/캘린더 선택이 숨어 있었는데, 일정 추가 시트 '일반' 탭 하단의 일정 연동하기 섹션으로 옮겼습니다.

1. 연동 섹션 (CalendarLinkSection)

Figma에서 주신 컴포넌트를 조합했습니다.

컴포넌트 내용
CalendarLinkButton 미연동(일정 가져오기) / 불러오는 중 / 연동됨(일정 연동 해제) 3상태
LoadingDots 진행 중 버튼 안의 점 3개 시차 바운스
EventCheckItem 체크박스 + 날짜·제목 한 줄 말줄임
CalendarLinkCard 제목 + 설명 + 버튼 + 일정 체크 목록(스크롤)
DisconnectConfirmModal 연동 해제 확인
CalendarLinkPanel 위 컴포넌트에 실제 데이터를 물리는 컨테이너

불러오는 중취소는 둘 다 88×37에 dot이 붙어 있어 hover 관계로 해석했습니다. 로딩 중 버튼에 마우스를 올리면 회색 취소로 바뀝니다.

2. 체크 = 캘린더 표시

이벤트 왼쪽 체크박스가 캘린더 표시 여부입니다. 기존 hiddenCalendarEvents(숨김 목록)를 뒤집어 씁니다.

숨김 해제 API가 프론트에만 없었는데, 백엔드에는 이미 DELETE /api/integration/calendar-events/hidden이 있어서(HiddenCalendarEventController.unhideEvent) 그것만 연결했습니다.

기본값은 "전부 체크"입니다. 숨김 목록에 없는 = 한 번도 안 건드린 이벤트는 표시 상태이기 때문입니다. Figma 목업은 전부 미체크였는데, 그대로 따르면 연동 직후 캘린더가 비고 기존 사용자 일정도 전부 사라져서 기존 동작을 유지했습니다.

3. 시트 인터랙션

  • 저장 버튼 고정: 연동 목록이 길어져도 가려지지 않게 시트 하단에 sticky로 고정 (좌우 24px / 위 10px / 아래 20px)
  • 바텀시트 드래그로 닫기: 손잡이를 잡고 100px 이상 내리면 닫힙니다. BottomSheetResponsiveSheet만 쓰므로 모바일·태블릿의 모든 시트에 함께 적용됩니다.
  • 반복 일정 종료 날짜: 미지정 표시를 없음종료 기간 없음으로 변경

4. 개발 편의

VITE_ENABLE_MSW=false.env에 두면 개발 모드에서도 실서버로 붙습니다. 팀 기본값은 그대로 목이라 옵트인 없이는 동작이 바뀌지 않습니다.

검증

  • tsc --noEmit 통과, ESLint 0 issues, prettier 통과
  • 전체 테스트 352개 통과 (신규 스토리북 스토리 6종 추가)
  • Storybook에서 각 컴포넌트 렌더링 확인
  • 시트 드래그는 실제 포인터 이벤트로 시뮬레이션해 확인 — 40px는 제자리 복귀, 150px는 닫힘
  • 저장 버튼 고정은 스크롤 중간·끝 모두 좌우 24px / 아래 20px로 측정 확인

중점적으로 리뷰받고 싶은 부분(선택)

저장 버튼 sticky의 음수 마진입니다. 시트(BottomSheet)·카드(DesktopCard)의 20px 패딩을 상쇄하려고 SaveArea에서 좌우 -20px, bottom·margin-bottomcalc(-20px - safe-area)로 잡았습니다. 부모 패딩값을 자식이 알고 있는 구조라 깨지기 쉬운데, 더 나은 방법이 있을지 봐주시면 좋겠습니다.

FixedBottomButtonArea는 재사용을 검토했지만 풀페이지용이라(버튼 517px 고정, 태블릿 이하에서 position: fixed로 뷰포트에 붙음) 시트 안에서는 맞지 않아 새로 만들었습니다.

논의하고 싶은 부분(선택)

체크박스 기본값은 "전부 표시"로 확정했습니다. (논의 완료)

숨김 목록(hiddenCalendarEvents)에 없는 = 한 번도 안 건드린 이벤트는 표시 상태이므로 기본이 전부 체크입니다. Figma 목업은 전부 미체크였지만, 그대로 따르면 연동 직후 캘린더가 비고 기존 사용자의 일정도 전부 사라져서 기존 동작을 유지했습니다.

🫡 참고사항

  • Notion 연동 해제는 백엔드 #1893과 함께 동작합니다. 프론트가 호출하는 DELETE /api/integration/notion/connection이 #1893의 NotionOAuthController.deleteConnection(@DeleteMapping("/connection"))과 경로가 일치하는 것을 확인했습니다. #1893이 머지되기 전에는 Notion 해제가 모달까지만 뜨고 호출은 실패합니다. (Google 해제는 이 PR만으로 정상 동작)
  • useCalendarSyncCalendarSyncTab과 패널에서 두 번 인스턴스화됩니다. useNotionOAuth가 URL 콜백 파라미터를 처리하는 effect를 갖고 있어 구조상 취약하지만, 시트는 열렸을 때만 마운트되고 OAuth는 페이지를 떠났다 돌아오므로 실제로는 겹치지 않습니다.
  • 기존 ProviderPopover, ProviderIcons는 미사용 상태가 됐지만 삭제하지 않고 남겨뒀습니다.

Summary by CodeRabbit

  • 새 기능

    • Google·Notion 캘린더 연동 상태와 일정을 카드 형태로 확인하고 선택할 수 있습니다.
    • 캘린더 연결 해제 전 확인 창이 표시되며, 숨긴 일정을 다시 표시할 수 있습니다.
    • 일정 추가 화면에서 날짜 선택과 저장 영역이 더욱 편리해졌습니다.
    • 바텀시트를 아래로 끌어 닫고 여러 시트를 겹쳐 사용할 수 있습니다.
  • 개선

    • 연동 중 로딩 및 취소 상태를 명확히 표시합니다.
    • 반복 일정의 종료 기간 없음 표시와 관련 안내 문구를 개선했습니다.
    • 캘린더 탐색과 일정 추가·삭제·숨김 동작이 더 안정적으로 동작합니다.

개발 모드에서 항상 MSW가 켜져 실서버 연동을 확인할 수 없었다.
기본값은 그대로 목이고, .env에 VITE_ENABLE_MSW=false를 두면 실서버로 붙는다.
손잡이 바만으로는 집기 어려워 위아래 패딩을 준 영역을 두고 포인터 이벤트를 붙였다.
100px 이상 내리면 닫히고 그 아래면 제자리로 돌아간다.
빠르게 끌 때 포인터가 손잡이를 벗어나 드래그가 끊기지 않도록 포인터를 캡처한다.
연동 UI가 일정 시트 안으로 옮겨가면서 우측 하단 Google·Notion 팝오버와
상단 데이터 오류 배너가 필요 없어졌다. 함께 고아가 된 스타일도 정리했다.
일정 추가 시트 '일반' 탭 하단에 연동 카드를 붙였다. 카드는 미연동·불러오는
중·연동됨 3상태이고, 연동되면 가져온 일정이 체크 목록으로 펼쳐진다.

체크는 캘린더 표시 여부다. 숨김 목록에 없으면 표시 상태이므로 기본은 전부
체크이고, 해제하면 숨기고 다시 체크하면 되살린다. 숨김 해제는 백엔드에 이미
있던 DELETE /calendar-events/hidden을 이제야 연결했다.

연동 해제는 되돌릴 수 없어 확인 모달을 거치게 했다. Notion 해제 엔드포인트는
백엔드에 아직 없어 Google과 같은 경로 규칙으로 붙여뒀다.

저장 버튼은 연동 목록이 길어져도 가려지지 않게 시트 하단에 고정했다.
'없음'만으로는 무엇이 없는지 읽히지 않아 문구를 명확히 했다.
@seongwon030 seongwon030 self-assigned this Aug 4, 2026
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@vercel

vercel Bot commented Aug 4, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
moadong Ready Ready Preview Aug 5, 2026 4:32pm

@github-actions github-actions Bot added the 💻 FE Frontend label Aug 4, 2026
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

캘린더 연동 UI를 카드와 이벤트 선택 목록 중심으로 재구성했습니다. Notion 연결 해제와 숨김 일정 표시 해제 API를 추가했습니다. Mixpanel 추적과 모바일 BottomSheet의 중첩·드래그 동작을 추가했습니다.

Changes

캘린더 관리 기능

Layer / File(s) Summary
연동 해제 API와 mutation
frontend/src/apis/*, frontend/src/hooks/Queries/*
Notion 연결 해제와 숨김 일정 표시 해제 API 및 mutation을 추가했습니다. 성공 시 관련 쿼리를 무효화합니다.
캘린더 연동 컴포넌트
frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLink*/, .../EventCheckItem/*, .../LoadingDots/*, .../DisconnectConfirmModal/*
Google·Notion 상태, 이벤트 목록, 연결 상태 버튼, 로딩 표시, 연결 해제 모달을 추가했습니다. Storybook 스토리도 추가했습니다.
캘린더 화면 통합
frontend/src/pages/AdminPage/tabs/CalendarSyncTab/*
기존 연동 설정 UI를 제거하고 새 연동 패널을 연결했습니다. Notion 연결 해제 상태와 이벤트 가시성 전환을 반영했습니다.
일정 입력과 분석 추적
.../AddEventSheet/*, .../CalendarBoard/*, .../DayEventsModal/*, frontend/src/constants/eventName.ts
일정 생성·수정·삭제·숨김·탐색 동작에 Mixpanel 이벤트를 추가했습니다. 종료 날짜 초기화와 고정 저장 영역도 변경했습니다.
모바일 시트 상호작용
frontend/src/components/common/BottomSheet/*, frontend/src/components/common/ResponsiveSheet/ResponsiveSheet.tsx
중첩 시트 표시를 지원합니다. 아래 방향으로 100px 이상 드래그하면 시트를 닫고, 짧은 드래그는 원위치로 복귀합니다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested labels: ✨ Feature, 🎨 Design

Suggested reviewers: lepitaaar

Sequence Diagram(s)

sequenceDiagram
  participant CalendarSyncTab
  participant AddEventSheet
  participant CalendarLinkPanel
  participant CalendarLinkCard
  participant DisconnectConfirmModal
  participant useDisconnectNotionCalendar
  CalendarSyncTab->>AddEventSheet: 일정 추가 시트 표시
  AddEventSheet->>CalendarLinkPanel: 캘린더 연동 패널 렌더링
  CalendarLinkPanel->>CalendarLinkCard: 연결 상태와 이벤트 전달
  CalendarLinkCard->>DisconnectConfirmModal: 연결 해제 확인 표시
  DisconnectConfirmModal->>useDisconnectNotionCalendar: 연결 해제 mutation 실행
  useDisconnectNotionCalendar-->>CalendarLinkPanel: 완료 상태와 캐시 갱신
Loading
🚥 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 관리자 캘린더의 Google·Notion 연동 UI 개편이라는 PR의 주요 변경 사항을 명확하게 요약합니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch calendar-sync-modal-ui

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 Aug 4, 2026

Copy link
Copy Markdown

✅ UI 변경사항 없음

구분 링크
📖 Storybook https://67904e61c16daa99a63b44a7-swimoshzsj.chromatic.com/

전체 119개 스토리 · 47개 컴포넌트

저장 버튼을 시트 하단에 고정하면서 실패 안내는 흐름에 남겨둬, 연동 섹션 때문에
스크롤이 생기면 안내가 화면 밖으로 밀려 눌러도 아무 반응이 없어 보였다.
안내를 고정 영역 안으로 옮겼다.

버튼 영역 배경은 투명으로 바꿨다. 안내 문구는 투명 배경에서 뒤 내용과 겹쳐
읽히지 않아 문구에만 시트 배경색을 깔았다.

날짜 시트가 위에 열려 있는 동안에는 저장할 일이 없어 버튼을 숨긴다.
반복 필드의 미지정 표시는 '종료 기간 없음'인데 그걸 되돌리는 시트 버튼만
'종료 없음'이라 같은 상태를 서로 다른 말로 가리키고 있었다.
바텀시트는 내용만큼만 높이를 차지해, 반복 탭처럼 내용이 짧으면 위에 뜬 날짜
시트가 뒤 시트를 통째로 덮었다. 저장 버튼까지 숨기면서 더 짧아져 손잡이와
제목 입력창 일부(73px)만 남았다.

BottomSheet에 expanded를 두어 위에 시트를 겹칠 때 높이를 최대로 펴고,
AddEventSheet가 날짜 시트를 열 때 이를 켠다. 딤드는 두 시트가 각자
오버레이를 그리므로 이미 두 겹이다.

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

Actionable comments posted: 5

🧹 Nitpick comments (6)
frontend/src/components/common/BottomSheet/BottomSheet.styles.ts (1)

1-1: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

타입 import를 별도 블록으로 분리하십시오.

Line 1은 React 런타임 import와 타입 import를 함께 선언합니다. 타입 import는 내부 모듈 import 뒤, styles import 앞에 배치하십시오.

수정 예시
-import { MouseEvent, PointerEvent, ReactNode, useRef, useState } from 'react';
+import { useRef, useState } from 'react';
 import useBodyScrollLock from '`@/hooks/useBodyScrollLock`';
 import useTopmostEscape from '`@/hooks/useTopmostEscape`';
 import Portal from '../Portal/Portal';
+import type { MouseEvent, PointerEvent, ReactNode } from 'react';
 import * as Styled from './BottomSheet.styles';

코딩 가이드에 따라 frontend/**/*.{ts,tsx}는 “Order imports as external libraries, internal modules, types, then styles.”를 따라야 합니다.

🤖 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 `@frontend/src/components/common/BottomSheet/BottomSheet.styles.ts` at line 1,
Update the imports in BottomSheet.styles.ts to separate type-only imports into
their own block, ordered after external and internal module imports and before
styles imports, while keeping the existing runtime styled-components import
separate.

Source: Coding guidelines

frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkCard/CalendarLinkCard.tsx (1)

1-5: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

import 순서를 가이드라인에 맞추십시오.

세 파일에서 type-only import가 internal module import와 섞여 있습니다.

  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkCard/CalendarLinkCard.tsx#L1-L5: CalendarLinkStatus type import를 internal value import 뒤, styles import 앞에 배치하십시오.
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkPanel/CalendarLinkPanel.tsx#L1-L16: HiddenCalendarEvent, CalendarLinkStatus, CalendarLinkEvent type import를 internal module import 뒤에 모으십시오.
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/AddEventSheet/AddEventSheet.tsx#L1-L20: CalendarLinkPanel을 포함한 internal module import를 type import보다 앞에 배치하십시오.

As per coding guidelines, “Order imports as external libraries, internal modules, types, then styles.”

🤖 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
`@frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkCard/CalendarLinkCard.tsx`
around lines 1 - 5, 세 파일의 import 순서를 외부 라이브러리, internal module, type, styles 순서로
정리하십시오.
frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkCard/CalendarLinkCard.tsx
1-5에서는 CalendarLinkStatus를 internal value import 뒤 styles import 앞에 배치하고,
frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkPanel/CalendarLinkPanel.tsx
1-16에서는 HiddenCalendarEvent, CalendarLinkStatus, CalendarLinkEvent를 모든 internal
module import 뒤에 모으십시오.
frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/AddEventSheet/AddEventSheet.tsx
1-20에서는 CalendarLinkPanel을 포함한 internal module import를 type import보다 앞에 배치하십시오.

Source: Coding guidelines

frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkCard/CalendarLinkCard.stories.tsx (1)

16-16: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

스토리 데코레이터의 인라인 스타일을 theme 기반 styled-components로 교체하세요.

width, background, padding을 styled wrapper로 이동하세요. 배경색은 하드코드한 '#F5F5F5' 대신 theme 색상을 사용하세요. 이렇게 하면 스토리도 제품 UI와 같은 디자인 토큰을 사용합니다.

As per coding guidelines: Use styled-components and the theme system for styling.

🤖 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
`@frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkCard/CalendarLinkCard.stories.tsx`
at line 16, Update the story decorator’s wrapper around the calendar link card
to use a styled-components wrapper instead of the inline style object. Move the
width, padding, and background styling into that wrapper, using the theme’s
appropriate color token instead of hardcoded `#F5F5F5` while preserving the
existing dimensions and spacing.

Source: Coding guidelines

frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkButton/CalendarLinkButton.stories.tsx (1)

1-2: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

타입 import를 내부 모듈 import 뒤로 이동하세요.

각 스토리 파일에서 external library import 다음에 내부 모듈 import를 두세요. 그 뒤에 import type를 두세요.

  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkButton/CalendarLinkButton.stories.tsx#L1-L2: CalendarLinkButton import 뒤로 Meta, StoryObj type import를 이동하세요.
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkCard/CalendarLinkCard.stories.tsx#L1-L3: CalendarLinkEvent를 별도 type import로 분리하고 CalendarLinkCard import 뒤로 이동하세요.
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/DisconnectConfirmModal/DisconnectConfirmModal.stories.tsx#L1-L2: DisconnectConfirmModal import 뒤로 Meta, StoryObj type import를 이동하세요.

As per coding guidelines: Order imports as external libraries, internal modules, types, then styles.

🤖 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
`@frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkButton/CalendarLinkButton.stories.tsx`
around lines 1 - 2, Reorder imports to follow external libraries, internal
modules, types, then styles. In
frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkButton/CalendarLinkButton.stories.tsx#L1-L2,
move the Meta and StoryObj type import after CalendarLinkButton; in
frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkCard/CalendarLinkCard.stories.tsx#L1-L3,
separate CalendarLinkEvent into a type import and place it after
CalendarLinkCard; in
frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/DisconnectConfirmModal/DisconnectConfirmModal.stories.tsx#L1-L2,
move the Meta and StoryObj type import after DisconnectConfirmModal.

Source: Coding guidelines

frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkSection/CalendarLinkSection.stories.tsx (1)

13-13: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

스토리 프리뷰 스타일을 styled-components와 테마로 이동하세요.

두 스토리가 인라인 style과 색상 리터럴을 사용합니다. 프리뷰 래퍼를 styled-components로 정의하고 색상과 간격에 테마 값을 사용하세요.

  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkSection/CalendarLinkSection.stories.tsx#L13-L13: decorator의 인라인 스타일을 테마 기반 래퍼 컴포넌트로 교체하세요.
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/EventCheckItem/EventCheckItem.stories.tsx#L25-L25: Template의 인라인 스타일을 같은 방식으로 교체하세요.

As per coding guidelines, "Use styled-components and the theme system for styling."

🤖 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
`@frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkSection/CalendarLinkSection.stories.tsx`
at line 13, Replace the inline preview styles in CalendarLinkSection.stories.tsx
at line 13 and EventCheckItem.stories.tsx at line 25 with a shared or equivalent
styled-components wrapper using theme-provided colors and spacing. Preserve the
existing preview dimensions and layout while removing hard-coded style values
and color literals.

Source: Coding guidelines

frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkPanel/CalendarLinkPanel.styles.ts (1)

6-6: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

오류 색상을 테마 토큰으로 통일하세요.

두 위치가 동일한 오류 색상 #dc2626을 직접 정의합니다. 오류용 테마 토큰을 사용하세요.

  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkPanel/CalendarLinkPanel.styles.ts#L6-L6: #dc2626을 오류 색상 테마 토큰으로 교체하세요.
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/AddEventSheet/AddEventSheet.styles.ts#L43-L43: 같은 오류 색상 테마 토큰을 사용하세요.

As per coding guidelines, "Use styled-components and the theme system for styling."

🤖 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
`@frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkPanel/CalendarLinkPanel.styles.ts`
at line 6, Replace the hardcoded `#dc2626` error color with the established error
color theme token in both CalendarLinkPanel.styles.ts:6-6 and
AddEventSheet.styles.ts:43-43, preserving the existing styled-components usage
and applying the same token at both sites.

Source: Coding guidelines

🤖 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 `@frontend/src/components/common/BottomSheet/BottomSheet.tsx`:
- Line 74: Update the BottomSheet pointer event handling so onPointerCancel uses
a dedicated handler that only resets dragOffset and does not invoke onClose or
perform close 판단. Keep close 판단 exclusively in handlePointerUp, while preserving
the existing pointerup behavior.

In
`@frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkPanel/CalendarLinkPanel.tsx`:
- Around line 51-75: Update CalendarLinkPanel’s useGetHiddenCalendarEvents
handling so loading or error states are not defaulted to an empty list and
interpreted as all events visible. Track and handle isLoading and isError,
disable visibility toggles until hidden-event data is successfully available,
and display an error state when the query fails.

In
`@frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/DisconnectConfirmModal/DisconnectConfirmModal.tsx`:
- Around line 17-24: Update the dialog element in DisconnectConfirmModal,
currently rendered as Styled.Card with role="dialog", to provide an accessible
name via aria-labelledby referencing Styled.Title or an appropriate fixed
aria-label.

In
`@frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/EventCheckItem/EventCheckItem.styles.ts`:
- Around line 13-19: Update the Input styled component so its :focus-visible
state applies an outline to the adjacent visual checkbox element. Preserve the
existing hidden-input behavior and target the neighboring checkbox selector used
by EventCheckItem rather than changing the input’s visibility.

In
`@frontend/src/pages/AdminPage/tabs/CalendarSyncTab/hooks/useNotionCalendarData.ts`:
- Around line 50-56: Update disconnectNotion so a successful disconnect also
clears the parent notionWorkspaceName state, while preserving the existing
pickedDatabaseId reset and error handling. Pass the success callback through the
relevant useCalendarSync and CalendarLinkPanel integration, and add coverage
confirming the card returns to idle only after a successful disconnect.

---

Nitpick comments:
In `@frontend/src/components/common/BottomSheet/BottomSheet.styles.ts`:
- Line 1: Update the imports in BottomSheet.styles.ts to separate type-only
imports into their own block, ordered after external and internal module imports
and before styles imports, while keeping the existing runtime styled-components
import separate.

In
`@frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkButton/CalendarLinkButton.stories.tsx`:
- Around line 1-2: Reorder imports to follow external libraries, internal
modules, types, then styles. In
frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkButton/CalendarLinkButton.stories.tsx#L1-L2,
move the Meta and StoryObj type import after CalendarLinkButton; in
frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkCard/CalendarLinkCard.stories.tsx#L1-L3,
separate CalendarLinkEvent into a type import and place it after
CalendarLinkCard; in
frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/DisconnectConfirmModal/DisconnectConfirmModal.stories.tsx#L1-L2,
move the Meta and StoryObj type import after DisconnectConfirmModal.

In
`@frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkCard/CalendarLinkCard.stories.tsx`:
- Line 16: Update the story decorator’s wrapper around the calendar link card to
use a styled-components wrapper instead of the inline style object. Move the
width, padding, and background styling into that wrapper, using the theme’s
appropriate color token instead of hardcoded `#F5F5F5` while preserving the
existing dimensions and spacing.

In
`@frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkCard/CalendarLinkCard.tsx`:
- Around line 1-5: 세 파일의 import 순서를 외부 라이브러리, internal module, type, styles 순서로
정리하십시오.
frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkCard/CalendarLinkCard.tsx
1-5에서는 CalendarLinkStatus를 internal value import 뒤 styles import 앞에 배치하고,
frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkPanel/CalendarLinkPanel.tsx
1-16에서는 HiddenCalendarEvent, CalendarLinkStatus, CalendarLinkEvent를 모든 internal
module import 뒤에 모으십시오.
frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/AddEventSheet/AddEventSheet.tsx
1-20에서는 CalendarLinkPanel을 포함한 internal module import를 type import보다 앞에 배치하십시오.

In
`@frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkPanel/CalendarLinkPanel.styles.ts`:
- Line 6: Replace the hardcoded `#dc2626` error color with the established error
color theme token in both CalendarLinkPanel.styles.ts:6-6 and
AddEventSheet.styles.ts:43-43, preserving the existing styled-components usage
and applying the same token at both sites.

In
`@frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkSection/CalendarLinkSection.stories.tsx`:
- Line 13: Replace the inline preview styles in CalendarLinkSection.stories.tsx
at line 13 and EventCheckItem.stories.tsx at line 25 with a shared or equivalent
styled-components wrapper using theme-provided colors and spacing. Preserve the
existing preview dimensions and layout while removing hard-coded style values
and color literals.
🪄 Autofix

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: CHILL

Plan: Pro Plus

Run ID: 19f55257-ab8f-48b7-bc9c-e6e0095b0cdb

📥 Commits

Reviewing files that changed from the base of the PR and between 09d064d and 82ef23f.

⛔ Files ignored due to path filters (2)
  • frontend/src/assets/images/icons/calendar_sync_checkbox_checked.svg is excluded by !**/*.svg
  • frontend/src/assets/images/icons/calendar_sync_warning.svg is excluded by !**/*.svg
📒 Files selected for processing (36)
  • frontend/src/apis/calendarOAuth.ts
  • frontend/src/apis/hiddenCalendarEvents.ts
  • frontend/src/components/common/BottomSheet/BottomSheet.styles.ts
  • frontend/src/components/common/BottomSheet/BottomSheet.tsx
  • frontend/src/components/common/ResponsiveSheet/ResponsiveSheet.tsx
  • frontend/src/hooks/Queries/useHiddenCalendarEvents.ts
  • frontend/src/hooks/Queries/useNotionCalendar.ts
  • frontend/src/index.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/CalendarSyncTab.styles.ts
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/CalendarSyncTab.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/AddEventSheet/AddEventSheet.styles.ts
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/AddEventSheet/AddEventSheet.test.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/AddEventSheet/AddEventSheet.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkButton/CalendarLinkButton.stories.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkButton/CalendarLinkButton.styles.ts
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkButton/CalendarLinkButton.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkCard/CalendarLinkCard.stories.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkCard/CalendarLinkCard.styles.ts
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkCard/CalendarLinkCard.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkPanel/CalendarLinkPanel.styles.ts
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkPanel/CalendarLinkPanel.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkSection/CalendarLinkSection.stories.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkSection/CalendarLinkSection.styles.ts
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkSection/CalendarLinkSection.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/DatePickerSheet/DatePickerSheet.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/DisconnectConfirmModal/DisconnectConfirmModal.stories.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/DisconnectConfirmModal/DisconnectConfirmModal.styles.ts
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/DisconnectConfirmModal/DisconnectConfirmModal.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/EventCheckItem/EventCheckItem.stories.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/EventCheckItem/EventCheckItem.styles.ts
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/EventCheckItem/EventCheckItem.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/LoadingDots/LoadingDots.styles.ts
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/LoadingDots/LoadingDots.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/RecurrenceFields/RecurrenceFields.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/hooks/useCalendarSync.ts
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/hooks/useNotionCalendarData.ts
💤 Files with no reviewable changes (2)
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/CalendarSyncTab.styles.ts
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/CalendarSyncTab.tsx

onPointerDown={handlePointerDown}
onPointerMove={handlePointerMove}
onPointerUp={handlePointerUp}
onPointerCancel={handlePointerUp}

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Files matching BottomSheet:"
fd -a 'BottomSheet\.tsx$' . | sed 's#^\./##'

file=$(fd 'BottomSheet\.tsx$' frontend/src/components/common/BottomSheet | head -n 1 || true)
echo "selected: ${file:-none}"

if [ -n "${file:-}" ]; then
  wc -l "$file"
  echo "Outline:"
  ast-grep outline "$file" --view compact || true
  echo "Relevant lines 1-140:"
  sed -n '1,140p' "$file" | nl -ba
fi

Repository: Moadong/moadong

Length of output: 613


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="frontend/src/components/common/BottomSheet/BottomSheet.tsx"
echo "File: $file"
lines=$(wc -l < "$file")
echo "Line count: $lines"

echo "Relevant lines:"
awk '{printf "%5d\t%s\n", NR, $0}' "$file"

echo "Pointer handler text:"
rg -n "handle(Pointer|PointerCancel|PointerUp|PointerMove|PointerDown)|setDragOffset|onClose|dragOffset|pointercancel" "$file" || true

Repository: Moadong/moadong

Length of output: 4192


pointercancel에서는 시트를 닫지 마십시오.

pointercancel은 취소된 포인터 인터랙션을 의미하므로 onClose를 실행하지 않아야 합니다. onPointerCancel 전용 핸들러에서 dragOffset만 초기화하고, 닫기 판단은 pointerup에서만 하십시오.

수정 예시
+  const handlePointerCancel = () => {
+    if (dragOffset === null) return;
+    setDragOffset(null);
+  };
+
   <Styled.DragHandle
     onPointerDown={handlePointerDown}
     onPointerMove={handlePointerMove}
     onPointerUp={handlePointerUp}
-    onPointerCancel={handlePointerUp}
+    onPointerCancel={handlePointerCancel}
   >
📝 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
onPointerCancel={handlePointerUp}
const handlePointerCancel = () => {
if (dragOffset === null) return;
setDragOffset(null);
};
onPointerCancel={handlePointerCancel}
🤖 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 `@frontend/src/components/common/BottomSheet/BottomSheet.tsx` at line 74,
Update the BottomSheet pointer event handling so onPointerCancel uses a
dedicated handler that only resets dragOffset and does not invoke onClose or
perform close 판단. Keep close 판단 exclusively in handlePointerUp, while preserving
the existing pointerup behavior.

Comment on lines +51 to +75
const { data: hiddenCalendarEvents = [] } = useGetHiddenCalendarEvents();
const hideMutation = useHideCalendarEvent();
const unhideMutation = useUnhideCalendarEvent();

/** 연동 해제는 되돌릴 수 없어 확인 모달을 거친다 */
const [disconnectTarget, setDisconnectTarget] = useState<
HiddenCalendarEvent['source'] | null
>(null);

const confirmDisconnect = () => {
if (disconnectTarget === 'GOOGLE') disconnectGoogle();
if (disconnectTarget === 'NOTION') disconnectNotion();
setDisconnectTarget(null);
};

const isNotionConnected =
notionDatabaseOptions.length > 0 || Boolean(notionWorkspaceName);

const hiddenKeys = new Set(
hiddenCalendarEvents.map((event) => `${event.source}:${event.eventId}`),
);

/** 체크 = 캘린더에 표시. 숨김 목록에 없으면 표시 상태다 */
const toVisibleIds = (source: HiddenCalendarEvent['source'], ids: string[]) =>
ids.filter((id) => !hiddenKeys.has(`${source}:${id}`));

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

숨김 일정 조회 오류를 빈 목록으로 처리하지 마십시오.

Line 51은 조회 중이거나 조회가 실패한 상태를 []로 처리합니다. 그러면 Line 69-75는 모든 이벤트를 표시 상태로 계산합니다. 사용자는 실제 숨김 상태와 다른 체크 상태를 볼 수 있습니다. isLoadingisError를 처리하고, 상태를 확인하기 전에는 토글을 비활성화하거나 오류 상태를 표시하십시오.

🤖 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
`@frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkPanel/CalendarLinkPanel.tsx`
around lines 51 - 75, Update CalendarLinkPanel’s useGetHiddenCalendarEvents
handling so loading or error states are not defaulted to an empty list and
interpreted as all events visible. Track and handle isLoading and isError,
disable visibility toggles until hidden-event data is successfully available,
and display an error state when the query fails.

Comment on lines +17 to +24
<Styled.Card role='dialog' aria-modal='true'>
<Styled.Message>
<Styled.Icon aria-hidden>
<WarningIcon />
</Styled.Icon>
<Styled.Title>연동을 해제할까요?</Styled.Title>
<Styled.Description>
가져온 일정은 캘린더에서 사라집니다.

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

대화상자에 접근 가능한 이름을 추가하십시오.

Line 17의 대화상자에는 aria-label 또는 aria-labelledby가 없습니다. 스크린 리더는 이름 없는 대화상자로 안내합니다. Styled.Title을 참조하는 aria-labelledby를 추가하거나 고정 aria-label을 설정하십시오.

🤖 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
`@frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/DisconnectConfirmModal/DisconnectConfirmModal.tsx`
around lines 17 - 24, Update the dialog element in DisconnectConfirmModal,
currently rendered as Styled.Card with role="dialog", to provide an accessible
name via aria-labelledby referencing Styled.Title or an appropriate fixed
aria-label.

Comment on lines +13 to +19
export const Input = styled.input`
position: absolute;
width: 1px;
height: 1px;
opacity: 0;
pointer-events: none;
`;

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

키보드 포커스 표시를 추가하세요.

실제 input은 투명하므로 Tab으로 포커스해도 현재 선택 위치가 보이지 않습니다. :focus-visible 상태에서 인접한 시각적 checkbox에 outline을 적용하세요.

수정 예시
 export const Input = styled.input`
   position: absolute;
   width: 1px;
   height: 1px;
   opacity: 0;
   pointer-events: none;
+
+  &:focus-visible + span {
+    outline: 2px solid ${colors.primary[900]};
+    outline-offset: 2px;
+  }
 `;
📝 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 Input = styled.input`
position: absolute;
width: 1px;
height: 1px;
opacity: 0;
pointer-events: none;
`;
export const Input = styled.input`
position: absolute;
width: 1px;
height: 1px;
opacity: 0;
pointer-events: none;
&:focus-visible + span {
outline: 2px solid ${colors.primary[900]};
outline-offset: 2px;
}
`;
🤖 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
`@frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/EventCheckItem/EventCheckItem.styles.ts`
around lines 13 - 19, Update the Input styled component so its :focus-visible
state applies an outline to the adjacent visual checkbox element. Preserve the
existing hidden-input behavior and target the neighboring checkbox selector used
by EventCheckItem rather than changing the input’s visibility.

Comment on lines +50 to +56
const disconnectNotion = () => {
clearError();
disconnectMutation.mutate(undefined, {
onSuccess: () => setPickedDatabaseId(''),
onError: (error: Error) => onError(error.message),
});
};

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Notion 연결 해제 성공 시 workspace 상태도 초기화하십시오.

Line 53은 pickedDatabaseId만 초기화합니다. useCalendarSync.tsnotionWorkspaceName은 OAuth 완료 후 유지되고, CalendarLinkPanel.tsx Line 66-67은 이 값만으로도 연결 상태를 true로 계산합니다. 따라서 DELETE가 성공해도 Notion 카드가 계속 연결됨으로 표시됩니다. 성공 콜백을 상위로 전달해 notionWorkspaceName을 성공 후에만 초기화하고, 카드가 idle 상태로 전환되는 테스트를 추가하십시오.

🤖 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
`@frontend/src/pages/AdminPage/tabs/CalendarSyncTab/hooks/useNotionCalendarData.ts`
around lines 50 - 56, Update disconnectNotion so a successful disconnect also
clears the parent notionWorkspaceName state, while preserving the existing
pickedDatabaseId reset and error handling. Pass the success callback through the
relevant useCalendarSync and CalendarLinkPanel integration, and add coverage
confirming the card returns to idle only after a successful disconnect.

높이를 최대로 펴니 내용이 짧은 반복 탭에서 시트만 커지고 아래쪽이 통째로
빈 회색으로 남았다. 높이는 내용에 맡기고 위치만 올리도록 바꿨다.

expanded를 stacked로 바꾸고 margin-bottom으로 180px 들어올린다. 들어올린
만큼 생기는 아래 틈은 위에 겹친 시트가 가린다.
미지정 상태 표시와 되돌리는 버튼에 '종료 기간 없음'을 같이 쓰니, 종료일을
고른 뒤에도 버튼이 현재 상태를 가리키는 것처럼 읽혔다. 버튼은 동작이므로
'종료 날짜 지우기'로 분리한다. 표시 문구는 그대로 둔다.
회색 배경에 회색 글자라 비활성으로 읽혔다. 저장 버튼과 같은 주황 배경에
흰 글자로 바꿔 누를 수 있는 동작임을 드러낸다.
종료 날짜가 없을 때도 주황 버튼이라 누를 수 있는 것처럼 보였지만 실제로는
아무 일도 일어나지 않았다. 지울 대상이 있을 때만 활성으로 바꾼다.
캘린더 화면에는 트래킹이 하나도 없어 어떤 기능이 쓰이는지 볼 수 없었다.
페이지뷰와 주요 동작 11종을 붙인다.

저장·삭제·숨김은 요청이 성공했을 때만 보내 실패를 성공으로 세지 않는다.
일정 유형, 반복 주기, 연동 제공자처럼 나눠 볼 값은 속성으로 함께 보낸다.
앞서 노이즈를 우려해 빼뒀던 입력 단계 동작까지 붙인다. 제목 초기화, 날짜
선택, 색상, 반복 주기·요일, 날짜 시트 열기, 종료 날짜 지우기, 스와이프,
연동 해제 취소 9종이다.

제목 지우기 버튼은 값이 비는 것만으로는 직접 지운 경우와 구분되지 않아
TitleInput에 onClear를 뒀다. 월 이동은 캘린더와 날짜 시트 양쪽에서 일어나
location으로 나눈다.
location은 이벤트마다 자동으로 붙는 url과 헷갈려 어느 달력인지 가리키는
이름으로 바꿨다. 값(board·picker)은 그대로다.

트래킹 헬퍼가 쓰는 곳보다 아래 선언돼 있어 위로 옮겼다.

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

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
`@frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/AddEventSheet/AddEventSheet.tsx`:
- Around line 300-305: Update each MiniCalendar instance in AddEventSheet,
including the calendars used for regular, range, and multi-event selection, so
its onMonthChange handler tracks ADMIN_EVENT.CALENDAR_MONTH_CHANGED before
calling setMonth. Pass a distinct calendarType for each calendar view, matching
the existing picker tracking behavior while preserving the current month state
updates.
🪄 Autofix

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: CHILL

Plan: Pro Plus

Run ID: 6d771103-f967-4ab2-b146-e75f5689c241

📥 Commits

Reviewing files that changed from the base of the PR and between 82ef23f and b900f95.

📒 Files selected for processing (13)
  • frontend/src/components/common/BottomSheet/BottomSheet.styles.ts
  • frontend/src/components/common/BottomSheet/BottomSheet.tsx
  • frontend/src/components/common/ResponsiveSheet/ResponsiveSheet.tsx
  • frontend/src/constants/eventName.ts
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/CalendarSyncTab.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/AddEventSheet/AddEventSheet.test.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/AddEventSheet/AddEventSheet.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarBoard/CalendarBoard.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkPanel/CalendarLinkPanel.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/DatePickerSheet/DatePickerSheet.styles.ts
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/DatePickerSheet/DatePickerSheet.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/DayEventsModal/DayEventsModal.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/TitleInput/TitleInput.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/CalendarSyncTab.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/CalendarLinkPanel/CalendarLinkPanel.tsx
  • frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/DatePickerSheet/DatePickerSheet.tsx

Comment on lines +300 to +305
onMonthChange={(nextMonth) => {
trackEvent(ADMIN_EVENT.CALENDAR_MONTH_CHANGED, {
calendarType: 'picker',
});
setMonth(nextMonth);
}}

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

인라인 캘린더의 월 이동도 추적해야 합니다.

Line 300은 날짜 선택기 월 이동만 CALENDAR_MONTH_CHANGED로 기록합니다. 그러나 Line 211, Line 226, Line 239의 MiniCalendarsetMonth를 직접 호출합니다. 일반, 기간, 다중 일정에서 월 이동 데이터가 누락됩니다.

MiniCalendaronMonthChange에도 같은 이벤트를 기록하고, calendarType으로 화면을 구분하세요.

🤖 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
`@frontend/src/pages/AdminPage/tabs/CalendarSyncTab/components/AddEventSheet/AddEventSheet.tsx`
around lines 300 - 305, Update each MiniCalendar instance in AddEventSheet,
including the calendars used for regular, range, and multi-event selection, so
its onMonthChange handler tracks ADMIN_EVENT.CALENDAR_MONTH_CHANGED before
calling setMonth. Pass a distinct calendarType for each calendar view, matching
the existing picker tracking behavior while preserving the current month state
updates.

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

Labels

💻 FE Frontend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant