Skip to content

[Feature/#233] 플랫폼 연동 페이지 UI 구현#234

Open
YermIm wants to merge 9 commits into
developfrom
feature/#233
Open

[Feature/#233] 플랫폼 연동 페이지 UI 구현#234
YermIm wants to merge 9 commits into
developfrom
feature/#233

Conversation

@YermIm
Copy link
Copy Markdown
Collaborator

@YermIm YermIm commented May 24, 2026

🚨 관련 이슈

close #233

✨ 변경사항

  • 🐞 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.)

✏️ 작업 내용

스크린샷 2026-06-07 오후 6 16 03
  • 플랫폼 연동 페이지 (/integrations)

    • Meta / Google / Naver 연동 카드 UI (연동됨 · 미연동 · 연동 오류 · 동기화 중 배지)
    • 연동됨: 마지막 동기화 시각, 재연동·연결 해제 버튼
    • 미연동: 안내 문구 + 연동하기
    • 오류: 에러 메시지 + 재연동
  • 사이드바

    • 푸터에 플랫폼 연동 추가
    • 연동 목록에 error 상태가 있으면 펼침 시 연동 필요 뱃지

😅 미완성 작업

N/A

📢 논의 사항 및 참고 사항

API 연동하면서 필요한 UI 추가 예정입니다!

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

Summary by CodeRabbit

  • New Features
    • 플랫폼 연동 페이지 및 카드 추가: 플랫폼별 상태, 동기화 시간, 토큰 만료 정보, 오류 알림과 연동/재연동/연결 해제 액션 제공(액션 시 토스트 표시).
    • 로딩 스켈레톤 추가: 접근성 라벨을 갖춘 카드 형태 로딩 UX.
    • 예정 플랫폼 카드 추가: 카카오·Coming Soon 미리보기 카드 제공.
  • Refactor
    • 사이드바 개선: 연동 주의 배지 노출 및 항목의 후행 영역(trailing) 지원으로 가독성 향상.

@YermIm YermIm requested review from Seojegyeong and jjjsun May 24, 2026 17:04
@YermIm YermIm self-assigned this May 24, 2026
@YermIm YermIm added 🎨 Html&css 마크업 & 스타일링 ✨ Feature 기능 개발 labels May 24, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 24, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

플랫폼 연동 화면을 추가했습니다: 타입·매핑 유틸·훅·목, 카드·스켈레톤·예정 카드 UI, 사이드바 배지, 라우트 및 레이아웃 연동을 통해 연결 현황을 조회·표시하고 상태별 액션을 제공합니다.

Changes

플랫폼 연동 기능 전체 흐름

Layer / File(s) Summary
타입 정의 및 연동 계약
src/types/integration/platformConnection.ts
플랫폼 계정 API 및 UI 연결 항목 타입(IPlatformAccountApi, IPlatformConnectionItem), 상태 리터럴과 관련 타입을 추가합니다.
플랫폼 계정 → UI 매핑 유틸
src/utils/integration/mapPlatformAccounts.ts
토큰 만료/임박 판정, 만료 톤 결정, 날짜 포맷 함수, API 상태→UI 상태 매핑과 제공자 순서 변환(mapPlatformAccountsToConnections)을 구현합니다.
데이터 훅 및 주의 판정
src/hooks/integration/usePlatformConnections.ts
usePlatformConnections는 선택된 워크스페이스 orgId로 mock 데이터를 조회(800ms 지연)하며, needsIntegrationAttention은 에러 상태 존재 여부를 반환합니다.
플랫폼 연동 카드 컴포넌트
src/components/integration/PlatformIntegrationCard.tsx
플랫폼별 로고·라벨·상태 뱃지 매핑, syncedAt/tokenExpireAt 포맷·톤 적용, 에러 알림과 상태별 버튼(onConnect/onReconnect/onDisconnect) 렌더링을 구현합니다.
로딩 스켈레톤 및 예정 카드
src/components/integration/skeleton/PlatformIntegrationsSkeleton.tsx, src/components/integration/UpcomingPlatformCard.tsx
카드형 스켈레톤(3개 반복)과 예정 서비스 카드(Kakao/ComingSoon)를 추가합니다.
플랫폼 연동 페이지 + mock
src/pages/integration/PlatformIntegrationsPage.tsx, src/pages/integration/platformIntegrations.mock.ts
훅으로 데이터를 받아 로딩/에러/성공 분기를 처리하고, 3열 그리드로 카드를 렌더링하며 하단에 예정 카드들을 배치합니다. 목 데이터는 API 응답 형태를 모사합니다.
사이드바 메뉴 및 주의 배지
src/constants/sidebarNav.ts, src/components/sidebar/Sidebar.tsx
footerNavintegrations 항목을 추가하고, 사이드바가 펼쳐진 상태에서 needsIntegrationAttention이 true일 때 Badge(infoRed)를 trailing으로 표시합니다.
SidebarItem 트레일링 슬롯 지원
src/components/sidebar/SidebarItem.tsx
trailing?: ReactNode prop을 추가하고 itemClassName으로 클래스 재사용, 접힘/펼침에 따른 렌더링 변경을 적용합니다.
라우트 및 레이아웃 조정
src/routes/MainRoutes.tsx, src/layout/main/MainLayout.tsx
페이지를 동적 임포트하여 workspace/:workspaceId/integrations 라우트를 등록하고, Outlet 래퍼의 너비 제약 구조를 내부로 이동했습니다.

Sequence Diagram

sequenceDiagram
  participant Page as PlatformIntegrationsPage
  participant Hook as usePlatformConnections
  participant MockAPI as platformAccountsApiMock
  participant Mapper as mapPlatformAccountsToConnections
  participant Card as PlatformIntegrationCard

  Page->>Hook: usePlatformConnections(orgId)
  Hook->>MockAPI: fetch mock data (800ms delay)
  MockAPI-->>Hook: IPlatformAccountApi[]
  Hook->>Mapper: mapPlatformAccountsToConnections(accounts)
  Mapper-->>Hook: IPlatformConnectionItem[]
  Hook-->>Page: platformConnections
  Page->>Card: render each connection with callbacks
  Card-->>Page: onConnect/onReconnect/onDisconnect events (toast)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • jjjsun
  • Seojegyeong

📋 리뷰 포인트

  1. 타입·매핑 유틸
  • 문제: mapPlatformAccountsToConnections가 accounts null/빈 배열 경로에 대한 방어가 약할 수 있음.
  • 제안: 입력 검증 추가(if (!Array.isArray(accounts)) return defaultConnections), 경계 케이스에 대한 로그나 안전한 폴백을 추가하세요.
  1. 날짜 파싱·포맷
  • 문제: parseDate/new Date 직접 사용은 브라우저별 파싱 차이를 야기할 수 있음(특히 로컬 YYYY-MM-DD 처리).
  • 제안: ISO(UTC) 명시 또는 date-fns/dayjs 같은 신뢰 가능한 파서 사용을 권장합니다. 파싱 실패 시 null 대신 명확한 폴백(예: undefined)과 console.warn을 남기세요.
  1. 토큰 만료 판정
  • 문제: 경고 임계값(7일)이 하드코딩되어 있음.
  • 제안: TOKEN_EXPIRE_WARNING_DAYS를 상수 외부화하고 단위 테스트(만료·임박·정상 시나리오)를 추가하세요.
  1. usePlatformConnections 훅
  • 문제: 현재 mock 지연 사용이 개발용으로 남아 있을 가능성.
  • 제안: TODO 주석 또는 env 플래그로 mock 전환을 명시하고, 쿼리 키/활성화 논리에 필요한 의존성(orgId 등)이 정확히 포함됐는지 확인하세요.
  1. PlatformIntegrationCard
  • 문제: 버튼 핸들러가 undefined일 때 안전성 처리 미비, 에러 영역의 보조 접근성 속성 부족.
  • 제안: 콜백이 없으면 버튼을 disabled로 처리하거나 noop으로 보호하고, 에러 영역에 aria-live="polite" 추가를 고려하세요.
  1. 스켈레톤·ARIA
  • 관찰: 페이지 수준에 aria-busy 적용은 적절합니다.
  • 제안: 개별 카드 skeleton에 aria-hidden 유지하면서 스크린리더가 혼동하지 않도록 의미적 레이블 관리를 검토하세요.
  1. Sidebar / SidebarItem
  • 문제: useMemo 의존성 배열에 platformConnections 관련 값(예: length 또는 배열 레퍼런스)이 누락되면 배지 상태가 갱신되지 않을 수 있음.
  • 제안: useMemo 의존성에 platformConnections 또는 그 길이를 명시적으로 포함하세요. 배지는 시각 알림이므로 스크린리더용 텍스트(aria-label)도 함께 제공을 고려하세요.
  1. 라우팅·레이아웃
  • 문제: MainLayout 래퍼 변경으로 중앙 정렬/반응형 레이아웃이 약간 달라질 수 있음.
  • 제안: Integrations 페이지와 주요 페이지에서 레이아웃 확인(중앙 정렬, max-width 충돌)하고 시각 회귀 테스트를 권장합니다.
  1. 테스트·로깅
  • 제안: 매핑 유틸과 카드 상태별 렌더링(connected/disconnected/error)에 대한 단위 테스트를 추가하세요. 훅의 mock 지연은 테스트에서 fake timer 사용으로 검증합니다.
  1. 국제화
  • 문제: 한국어 문자열이 컴포넌트 내부에 하드코딩됨.
  • 제안: i18n 적용 계획을 세우거나 상위 리소스에서 문자열을 주입하도록 개선하세요.

요약: 전체 흐름은 명확히 구성되어 있으며, 안정성(날짜 파싱·폴백), 접근성(aria-live/label), 방어 코드와 테스트 보강에 집중하면 좋습니다.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.55% 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 제목은 이슈 번호 #233과 함께 플랫폼 연동 페이지 UI 구현이라는 주요 변경 사항을 명확하고 간결하게 표현하고 있습니다.
Description check ✅ Passed PR 설명은 템플릿을 따르며 관련 이슈, 변경사항 체크박스, 작업 내용(스크린샷 포함), 미완성 작업, 리뷰 가이드를 포함하고 있습니다.
Linked Issues check ✅ Passed 플랫폼 연동 페이지 UI 구현, 사이드바 footerNav 추가, 메타/구글/네이버 연동 상태 UI 등 #233의 모든 주요 요구사항이 구현되었습니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 플랫폼 연동 페이지 UI 구현이라는 명확한 스코프 내에 있으며, 불필요한 기능이나 범위 외 코드는 포함되지 않았습니다.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/#233

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
Copy link
Copy Markdown

github-actions Bot commented May 24, 2026

📚 Storybook 배포 완료

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/pages/integration/PlatformIntegrationsPage.tsx (1)

9-14: ⚡ Quick win

에러 상태에서 즉시 재시도 액션을 추가해 주세요.

현재는 실패 메시지만 보여서 사용자가 복구를 위해 페이지를 벗어나야 합니다. refetch를 노출해서 에러 영역에 다시 시도 버튼을 두면 UX가 좋아집니다.

제안 diff
 export default function PlatformIntegrationsPage() {
   const {
     data: platformConnections = [],
     isLoading,
     isError,
     error,
+    refetch,
   } = usePlatformConnections();

@@
       ) : isError ? (
         <div className="flex min-h-40 items-center justify-center rounded-3xl bg-surface-100 p-8 shadow-Soft">
-          <p className="text-center font-body2 text-text-muted">
-            {error?.message ??
-              "플랫폼 연동 정보를 불러오지 못했습니다. 잠시 후 다시 시도해 주세요."}
-          </p>
+          <div className="flex flex-col items-center gap-3">
+            <p className="text-center font-body2 text-text-muted">
+              {error?.message ??
+                "플랫폼 연동 정보를 불러오지 못했습니다. 잠시 후 다시 시도해 주세요."}
+            </p>
+            <button
+              type="button"
+              onClick={() => void refetch()}
+              className="rounded-xl border border-surface-300 px-4 py-2 font-body2 text-text-title hover:bg-surface-200"
+            >
+              다시 시도
+            </button>
+          </div>
         </div>

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

Also applies to: 20-26

🤖 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 `@src/pages/integration/PlatformIntegrationsPage.tsx` around lines 9 - 14, The
error UI in PlatformIntegrationsPage doesn't offer a retry; update the component
to use the refetch function from usePlatformConnections (add refetch to the
destructuring alongside data/isLoading/isError/error) and render a "다시 시도"
button in the error branch that calls refetch when clicked; ensure the error
block still displays a helpful message (using error) and disables the button
while isLoading to prevent duplicate calls.
🤖 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 `@src/components/sidebar/SidebarItem.tsx`:
- Around line 33-45: The collapsed-state rendering in SidebarItem currently
shows only the Icon with aria-hidden, which leaves the NavLink/button (rendered
elsewhere) without an accessible name; update the collapsed branch in the
content JSX so that when isCollapsed is true you add an accessible label (e.g.,
aria-label and optionally title) derived from item.label to the interactive
element that uses content (ensure the same label is applied when Icon exists or
is null), and keep aria-hidden on the decorative Icon; check NavLink/button
usages that consume content to ensure they forward the aria-label when
collapsed.

---

Nitpick comments:
In `@src/pages/integration/PlatformIntegrationsPage.tsx`:
- Around line 9-14: The error UI in PlatformIntegrationsPage doesn't offer a
retry; update the component to use the refetch function from
usePlatformConnections (add refetch to the destructuring alongside
data/isLoading/isError/error) and render a "다시 시도" button in the error branch
that calls refetch when clicked; ensure the error block still displays a helpful
message (using error) and disables the button while isLoading to prevent
duplicate calls.
🪄 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: CHILL

Plan: Pro

Run ID: 30ec8865-4f6e-4c5f-9b42-4ced4d53adee

📥 Commits

Reviewing files that changed from the base of the PR and between d4d7b94 and 8693a0a.

⛔ Files ignored due to path filters (1)
  • src/assets/icon/sidebar/connect.svg is excluded by !**/*.svg and included by src/**
📒 Files selected for processing (11)
  • src/components/integration/PlatformIntegrationCard.tsx
  • src/components/integration/skeleton/PlatformIntegrationsSkeleton.tsx
  • src/components/sidebar/Sidebar.tsx
  • src/components/sidebar/SidebarItem.tsx
  • src/constants/sidebarNav.ts
  • src/hooks/integration/usePlatformConnections.ts
  • src/layout/main/MainLayout.tsx
  • src/pages/integration/PlatformIntegrationsPage.tsx
  • src/pages/integration/platformIntegrations.mock.ts
  • src/routes/MainRoutes.tsx
  • src/types/integration/platformConnection.ts

Comment thread src/components/sidebar/SidebarItem.tsx
@jjjsun
Copy link
Copy Markdown
Collaborator

jjjsun commented May 25, 2026

P3: 혹시 지금 페이지 아래에는 비어있는듯한 느낌이 들어서, 플랫폼을 세로로 flex로 배치하고, 재연동/연결해제/연동하기 버튼들을 우측에 맞춰서 flex로 넣으면 어떨까요?
근데, 플랫폼을 flex로 배치하면 아래에서 비어보이는 이미지는 사라지지만, 안에 내용이 비어보이는 느낌이 있어서 애매하다는 생각이 들기도 합니다...
이러한 의견도 추가로 한번 제안드려봅니다...!!

@YermIm
Copy link
Copy Markdown
Collaborator Author

YermIm commented May 25, 2026

P3: 혹시 지금 페이지 아래에는 비어있는듯한 느낌이 들어서, 플랫폼을 세로로 flex로 배치하고, 재연동/연결해제/연동하기 버튼들을 우측에 맞춰서 flex로 넣으면 어떨까요? 근데, 플랫폼을 flex로 배치하면 아래에서 비어보이는 이미지는 사라지지만, 안에 내용이 비어보이는 느낌이 있어서 애매하다는 생각이 들기도 합니다... 이러한 의견도 추가로 한번 제안드려봅니다...!!

저도 이 부분 고민하다가 버튼이 멀어지면 가독성이 떨어질 것 같아서 일단 가로 배치했습니다. 화면적으로 봤을 때는 세로 배치가 더 좋을 것 같습니다. 수정해본 화면인데 이대로 진행할까요?!

screencapture-localhost-5173-integrations-2026-05-25-19_44_49

@jjjsun
Copy link
Copy Markdown
Collaborator

jjjsun commented May 25, 2026

P3: 혹시 지금 페이지 아래에는 비어있는듯한 느낌이 들어서, 플랫폼을 세로로 flex로 배치하고, 재연동/연결해제/연동하기 버튼들을 우측에 맞춰서 flex로 넣으면 어떨까요? 근데, 플랫폼을 flex로 배치하면 아래에서 비어보이는 이미지는 사라지지만, 안에 내용이 비어보이는 느낌이 있어서 애매하다는 생각이 들기도 합니다... 이러한 의견도 추가로 한번 제안드려봅니다...!!

저도 이 부분 고민하다가 버튼이 멀어지면 가독성이 떨어질 것 같아서 일단 가로 배치했습니다. 화면적으로 봤을 때는 세로 배치가 더 좋을 것 같습니다. 수정해본 화면인데 이대로 진행할까요?!

screencapture-localhost-5173-integrations-2026-05-25-19_44_49

음 저는 이 세로 배치가 더 나은것같습니다! 혹시 옆에 버튼들(재연동/연결해제)은 위아래로 배치해서 오른쪽에 붙게 하는건 어떨까요?

+)추가로 버튼들이 안에 텍스트 크기에 따라서 너비가 다른것같은데 너비 고정해서 너비 맞추는 것도 깔끔해보일것같아요!

@Seojegyeong
Copy link
Copy Markdown
Collaborator

P4: 저는 아래 이미지처럼 카드형 가로 배치가 좋을 것 같습니다! 이유는 아래와 같음

  • 가로 배치는 카드가 나란히 배치되어서 3개 플랫폼 상태를 한 눈에 비교할 수 있다. 세로 배치는 위아래로 시선을 이동해 비교해야 해서 직관적이지 않음
  • 버튼과 콘텐츠 연관성, 오류 상태 등이 잘 보임
  • 세로 배치는 버튼이 오른쪽 끝에 몰려 있어서 텍스트와 버튼 사이의 거리가 너무 멀다
스크린샷 2026-05-25 오후 10 19 39

하단이 비어보이는 문제는 아래 방법을 통해 보완할 수 있을 것 같습니다!

  • 카드 안에 정보를 더 추가해 높이 늘리기
  • 하단 공간 활용하기 - 연동 가능한 다른 플랫폼 섹션 아래에 추가(추후 지원 예정인 플랫폼을 비활성화 카드로 보여줌)

@jjjsun
Copy link
Copy Markdown
Collaborator

jjjsun commented May 26, 2026

P4: 저는 아래 이미지처럼 카드형 가로 배치가 좋을 것 같습니다! 이유는 아래와 같음

  • 가로 배치는 카드가 나란히 배치되어서 3개 플랫폼 상태를 한 눈에 비교할 수 있다. 세로 배치는 위아래로 시선을 이동해 비교해야 해서 직관적이지 않음
  • 버튼과 콘텐츠 연관성, 오류 상태 등이 잘 보임
  • 세로 배치는 버튼이 오른쪽 끝에 몰려 있어서 텍스트와 버튼 사이의 거리가 너무 멀다
스크린샷 2026-05-25 오후 10 19 39 하단이 비어보이는 문제는 아래 방법을 통해 보완할 수 있을 것 같습니다!
  • 카드 안에 정보를 더 추가해 높이 늘리기
  • 하단 공간 활용하기 - 연동 가능한 다른 플랫폼 섹션 아래에 추가(추후 지원 예정인 플랫폼을 비활성화 카드로 보여줌)

저는 가로배치가 아래부분이 비어보이는 점이 수정되었으면 좋겠다는 점에서 세로배치를 제안드렸는데,
제경님 말씀처럼 안에 추가내용으로 높이를 늘리고, 하단에 추가 섹션을 넣는다면 가로 배치로 진행하는것도 좋다고 생각합니다.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 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 `@src/components/integration/UpcomingPlatformCard.tsx`:
- Around line 26-27: The UpcomingPlatformCard component currently sets the prop
default disabled = true which causes the interactive control (the button
rendered in the component—see the Button / <button> usage around the block that
starts at Line 61) to always be disabled; update UpcomingPlatformCard to honor
the incoming disabled prop by removing or changing the hard-coded true and
passing the component's disabled prop down to the rendered button (or using
disabled={disabled} on the Button element) so the prop contract matches runtime
behavior.

In `@src/types/integration/platformConnection.ts`:
- Line 6: TPlatformAccountApiStatus is missing a syncing variant so the UI badge
never appears; add the corresponding API status (e.g., "SYNCING" or the exact
casing your backend emits) to the TPlatformAccountApiStatus union and update the
mapApiStatusToUi function to handle that new API value by returning "syncing"
(or the appropriate TPlatformConnectionStatus) so the UI branch is covered;
adjust any code that constructs API status strings to use the same casing to
keep types and runtime values consistent.

In `@src/utils/integration/mapPlatformAccounts.ts`:
- Around line 16-19: The parseDate function currently uses new Date(value),
which parses YYYY-MM-DD as UTC and can shift the date across timezones; update
parseDate to detect date-only strings (e.g., /^\d{4}-\d{2}-\d{2}$/) and
construct the Date via new Date(year, monthIndex, day) (using
Number(parsedYear), Number(parsedMonth)-1, Number(parsedDay)) to create a
local-midnight Date, preserving the intended calendar day; then ensure
isTokenExpired and isTokenExpiringSoon call the updated parseDate and perform
comparisons using getTime() (or Date objects) so mapApiStatusToUi uses correct
expiry decisions.
🪄 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: CHILL

Plan: Pro

Run ID: 74383a45-a30e-4cec-9897-e2f123a131dd

📥 Commits

Reviewing files that changed from the base of the PR and between 8693a0a and 276e955.

📒 Files selected for processing (12)
  • src/components/integration/PlatformIntegrationCard.tsx
  • src/components/integration/UpcomingPlatformCard.tsx
  • src/components/integration/skeleton/PlatformIntegrationsSkeleton.tsx
  • src/components/sidebar/Sidebar.tsx
  • src/constants/sidebarNav.ts
  • src/hooks/integration/usePlatformConnections.ts
  • src/layout/main/MainLayout.tsx
  • src/pages/integration/PlatformIntegrationsPage.tsx
  • src/pages/integration/platformIntegrations.mock.ts
  • src/routes/MainRoutes.tsx
  • src/types/integration/platformConnection.ts
  • src/utils/integration/mapPlatformAccounts.ts
🚧 Files skipped from review as they are similar to previous changes (6)
  • src/layout/main/MainLayout.tsx
  • src/components/sidebar/Sidebar.tsx
  • src/routes/MainRoutes.tsx
  • src/constants/sidebarNav.ts
  • src/components/integration/skeleton/PlatformIntegrationsSkeleton.tsx
  • src/pages/integration/PlatformIntegrationsPage.tsx

Comment thread src/components/integration/UpcomingPlatformCard.tsx
Comment thread src/types/integration/platformConnection.ts
Comment thread src/utils/integration/mapPlatformAccounts.ts
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
src/utils/integration/mapPlatformAccounts.ts (2)

69-98: ⚡ Quick win

parseDate 실패 시 원본 문자열을 반환하면 invalid 값이 UI에 노출될 수 있습니다.

Lines 72, 92에서 parseDate 실패 시 원본 value를 그대로 반환하고 있습니다. 서버가 잘못된 날짜 형식을 보내는 경우, raw string이 UI에 표시될 수 있습니다. null을 반환하면 PlatformConnectionMeta에서 해당 필드를 렌더링하지 않아 더 안전합니다.

♻️ 제안 수정안
 export function formatConnectionDateTime(value?: string): string | null {
   if (!value) return null;
   const date = parseDate(value);
-  if (!date) return value;
+  if (!date) return null;
   if (value.includes("T")) {
     return date.toLocaleString("ko-KR", {
       year: "numeric",
       month: "2-digit",
       day: "2-digit",
       hour: "2-digit",
       minute: "2-digit",
     });
   }
   return date.toLocaleDateString("ko-KR", {
     year: "numeric",
     month: "2-digit",
     day: "2-digit",
   });
 }

 export function formatConnectionDate(value?: string): string | null {
   if (!value) return null;
   const date = parseDate(value);
-  if (!date) return value;
+  if (!date) return null;
   return date.toLocaleDateString("ko-KR", {
     year: "numeric",
     month: "2-digit",
     day: "2-digit",
   });
 }
🤖 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 `@src/utils/integration/mapPlatformAccounts.ts` around lines 69 - 98,
formatConnectionDateTime and formatConnectionDate currently return the original
raw value when parseDate(value) fails, which can expose invalid strings in the
UI; change both functions so that if parseDate(value) returns a falsy value you
return null instead of value, keeping the functions' return type (string | null)
and preventing invalid raw dates from being rendered; update the logic in
formatConnectionDateTime (the branch after const date = parseDate(value)) and in
formatConnectionDate to return null on parseDate failure.

125-129: 💤 Low value

에러 메시지를 상수로 분리하면 유지보수성이 향상됩니다.

Line 128의 에러 메시지가 하드코딩되어 있습니다. 향후 메시지 변경이나 다국어 지원 시 관리가 어려울 수 있으므로, 파일 상단에 상수로 분리하는 것을 권장합니다.

♻️ 제안 수정안
 const INTEGRATION_PROVIDERS: TIntegrationProvider[] = [
   "META",
   "GOOGLE",
   "NAVER",
 ];

 const TOKEN_EXPIRE_WARNING_DAYS = 7;
+const TOKEN_EXPIRED_ERROR_MESSAGE = "토큰이 만료되었습니다. 다시 연동해 주세요.";
 const DATE_ONLY_PATTERN = /^(\d{4})-(\d{2})-(\d{2})$/;
   if (status === "error") {
     return {
       ...base,
-      errorMessage: "토큰이 만료되었습니다. 다시 연동해 주세요.",
+      errorMessage: TOKEN_EXPIRED_ERROR_MESSAGE,
     };
   }
🤖 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 `@src/utils/integration/mapPlatformAccounts.ts` around lines 125 - 129, The
hard-coded Korean error string returned in the status === "error" branch should
be moved to a top-level constant for maintainability and i18n; add a constant
(e.g., TOKEN_EXPIRED_MSG or MAP_PLATFORM_TOKEN_EXPIRED) at the top of the file
and replace the inline "토큰이 만료되었습니다. 다시 연동해 주세요." in the return object inside
the if (status === "error") block (within mapPlatformAccounts) with that
constant.
🤖 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.

Nitpick comments:
In `@src/utils/integration/mapPlatformAccounts.ts`:
- Around line 69-98: formatConnectionDateTime and formatConnectionDate currently
return the original raw value when parseDate(value) fails, which can expose
invalid strings in the UI; change both functions so that if parseDate(value)
returns a falsy value you return null instead of value, keeping the functions'
return type (string | null) and preventing invalid raw dates from being
rendered; update the logic in formatConnectionDateTime (the branch after const
date = parseDate(value)) and in formatConnectionDate to return null on parseDate
failure.
- Around line 125-129: The hard-coded Korean error string returned in the status
=== "error" branch should be moved to a top-level constant for maintainability
and i18n; add a constant (e.g., TOKEN_EXPIRED_MSG or MAP_PLATFORM_TOKEN_EXPIRED)
at the top of the file and replace the inline "토큰이 만료되었습니다. 다시 연동해 주세요." in the
return object inside the if (status === "error") block (within
mapPlatformAccounts) with that constant.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2ed54318-bfe5-4241-81de-b891c9ac3bfc

📥 Commits

Reviewing files that changed from the base of the PR and between 276e955 and e3a8a6b.

📒 Files selected for processing (4)
  • src/components/integration/PlatformIntegrationCard.tsx
  • src/components/integration/UpcomingPlatformCard.tsx
  • src/types/integration/platformConnection.ts
  • src/utils/integration/mapPlatformAccounts.ts
💤 Files with no reviewable changes (1)
  • src/components/integration/PlatformIntegrationCard.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/integration/UpcomingPlatformCard.tsx

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

Labels

✨ Feature 기능 개발 🎨 Html&css 마크업 & 스타일링

Projects

None yet

Development

Successfully merging this pull request may close these issues.

✨ [Feature] 플랫폼 연동 화면 UI 구현

3 participants