Skip to content

Conversation

@Bangdayeon
Copy link
Member

관련 이슈

PR 설명

  • 기존 구현되어 있던 Header, MenuSection 파일 구분

@Bangdayeon Bangdayeon self-assigned this Jan 6, 2026
@Bangdayeon Bangdayeon linked an issue Jan 6, 2026 that may be closed by this pull request
@coderabbitai
Copy link

coderabbitai bot commented Jan 6, 2026

개요

SideNavigation 컴포넌트의 복잡도를 줄이기 위해 기존의 모달 기반 메뉴 항목 관리 및 인라인 메뉴 항목 렌더링 방식을 새로운 공개 컴포넌트인 SideNavigationHeader와 MenuSection으로 분리했습니다. 모달 스토어 의존성과 인라인 MENU_ITEMS 로직을 제거하고, isOpen 상태에 따라 두 개의 새로운 컴포넌트를 직접 렌더링하도록 구조를 단순화했습니다. SideNavToggle의 displayName 할당도 제거되었습니다.

Walkthrough

SideNavigation에서 인라인 MENU_ITEMS와 모달 스토어 의존 로직을 제거하고, SideNavigationHeader(isOpen, onClick) 및 MenuSection(isOpen) 컴포넌트를 직접 렌더링하도록 변경했습니다. MenuSection은 내부에서 모달 타입을 조회해 AddLinkModal을 조건부 렌더링하며 NewChatButton, AddLinkButton, AllLinkButton 등 개별 버튼 컴포넌트를 사용합니다. SideNavToggle의 displayName 할당이 삭제되었습니다.

Possibly related PRs

  • linkiving PR 327 — 리팩터로 인해 MenuSection에서 사용하는 NavItem/LinkNavItem의 경로·시그니처와 className 변경이 포함되어 MenuSection 및 버튼 컴포넌트와 코드 수준에서 직접 연관됩니다.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 제목은 사이드네비게이션의 섹션 구분이라는 주요 변화를 명확하게 설명하고 있으며, 실제 변경사항과 일치합니다.
Description check ✅ Passed PR 설명은 Header와 MenuSection 파일 분리라는 변경사항과 관련 이슈 #320을 명시하고 있어 변경사항과 연관됩니다.
Linked Issues check ✅ Passed SideNavigation.tsx의 복잡도를 줄이기 위해 Header와 MenuSection 컴포넌트로 파일을 분리한 요구사항을 완벽히 충족합니다.
Out of Scope Changes check ✅ Passed SideNavToggle과 NavItem의 displayName 제거, 그리고 import 경로 업데이트는 파일 구조 재조직의 필수적인 부분으로 범위 내입니다.

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

✨ Finishing touches
  • 📝 Generate docstrings

Warning

Tools execution failed with the following error:

Failed to run tools: 13 INTERNAL: Received RST_STREAM with code 2 (Internal server error)


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.

Copy link

@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

🤖 Fix all issues with AI Agents
In @src/components/layout/SideNavigation/components/MenuSection/MenuSection.tsx:
- Around line 38-42: The JSX has a redundant !isOpen check and a motion.div with
only a transition (no animate/initial), so remove the inner duplicated condition
and either drop the motion.div’s transition if no animation is needed or add
proper Framer Motion props (e.g., initial and animate or exit) to the motion.div
so the transition actually runs; update the block that renders item.item to
either render directly when !isOpen or convert the motion.div inside MenuSection
to include animate/initial/exit to implement the intended closing animation.
🧹 Nitpick comments (1)
src/components/layout/SideNavigation/components/MenuSection/MenuSection.tsx (1)

16-20: MENU_ITEMS를 컴포넌트 외부로 이동하는 것을 고려해보세요.

현재 MENU_ITEMS 배열이 컴포넌트 내부에 정의되어 있어 매 렌더링마다 새로 생성됩니다. 성능 최적화를 위해 컴포넌트 외부로 이동하거나 useMemo로 메모이제이션하는 것을 고려해보세요. 다만 현재 규모에서는 성능에 큰 영향은 없을 것으로 보입니다.

🔎 제안하는 리팩토링

컴포넌트 외부로 이동 (단, open 함수는 여전히 props로 전달 필요):

+const MENU_ITEMS = (onAddLinkClick: () => void) => [
+  { id: 'new-chat', item: <NewChatButton /> },
+  { id: 'add-link', item: <AddLinkButton onClick={onAddLinkClick} /> },
+  { id: 'all-link', item: <AllLinkButton /> },
+];
+
 const MenuSection = ({ isOpen }: Props) => {
   const { type, open } = useModalStore();
 
-  const MENU_ITEMS = [
-    { id: 'new-chat', item: <NewChatButton /> },
-    { id: 'add-link', item: <AddLinkButton onClick={() => open('ADD_LINK')} /> },
-    { id: 'all-link', item: <AllLinkButton /> },
-  ];
+  const menuItems = MENU_ITEMS(() => open('ADD_LINK'));
 
   return (
     <>
       <nav className="flex flex-col gap-4">
-        {MENU_ITEMS.map(item => (
+        {menuItems.map(item => (
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 52cee50 and 24f965c.

📒 Files selected for processing (8)
  • src/components/layout/SideNavigation/SideNavigation.tsx
  • src/components/layout/SideNavigation/components/Header/SideNavToggle.tsx
  • src/components/layout/SideNavigation/components/Header/SideNavigationHeader.tsx
  • src/components/layout/SideNavigation/components/MenuSection/AddLinkButton.tsx
  • src/components/layout/SideNavigation/components/MenuSection/AddLinkModal.tsx
  • src/components/layout/SideNavigation/components/MenuSection/AllLinkButton.tsx
  • src/components/layout/SideNavigation/components/MenuSection/MenuSection.tsx
  • src/components/layout/SideNavigation/components/MenuSection/NewChatButton.tsx
💤 Files with no reviewable changes (1)
  • src/components/layout/SideNavigation/components/Header/SideNavToggle.tsx
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-23T14:52:20.769Z
Learnt from: Bangdayeon
Repo: Team-SoFa/linkiving PR: 102
File: src/components/layout/SideNavigation/components/AddLinkModal/AddLinkModal.tsx:23-23
Timestamp: 2025-11-23T14:52:20.769Z
Learning: In src/components/layout/SideNavigation/components/AddLinkModal/AddLinkModal.tsx, the hardcoded '/file.svg' thumbnail is intentional as a placeholder because the backend API for fetching link metadata/thumbnails is still in preparation. The actual thumbnail fetch logic will be implemented after the backend is ready.

Applied to files:

  • src/components/layout/SideNavigation/components/MenuSection/MenuSection.tsx
  • src/components/layout/SideNavigation/components/Header/SideNavigationHeader.tsx
  • src/components/layout/SideNavigation/SideNavigation.tsx
🧬 Code graph analysis (1)
src/components/layout/SideNavigation/components/MenuSection/MenuSection.tsx (1)
src/stores/modalStore.ts (1)
  • useModalStore (18-23)
🔇 Additional comments (4)
src/components/layout/SideNavigation/SideNavigation.tsx (2)

6-7: 리팩토링이 잘 되었습니다!

새로운 컴포넌트들을 적절하게 import하여 코드의 복잡도를 효과적으로 줄였습니다.


20-21: 컴포넌트 분리가 깔끔합니다!

SideNavigationHeader와 MenuSection으로 책임을 명확히 분리하여 가독성과 유지보수성이 향상되었습니다.

src/components/layout/SideNavigation/components/Header/SideNavigationHeader.tsx (1)

1-18: 간단하고 명확한 헤더 컴포넌트입니다!

Props 타입이 정확하게 정의되어 있고, SideNavToggle에 적절히 props를 전달하고 있습니다. 컴포넌트의 책임이 명확하여 좋습니다.

src/components/layout/SideNavigation/components/MenuSection/MenuSection.tsx (1)

13-49: 메뉴 섹션 구현이 잘 되었습니다!

modal store를 활용하여 AddLinkModal을 제어하고, Framer Motion으로 열림/닫힘 상태에 따른 애니메이션을 구현한 것이 좋습니다. 전반적인 구조와 로직이 명확합니다.

Copy link

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

Caution

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

⚠️ Outside diff range comments (1)
src/components/layout/SideNavigation/components/MenuSection/AllLinkButton.tsx (1)

9-9: displayName에 오타가 있습니다.

'AllLinkLinkButton'에 "Link"가 중복되어 있습니다. 컴포넌트 이름과 일치하도록 수정해야 합니다.

✏️ 수정 제안
-AllLinkButton.displayName = 'AllLinkLinkButton';
+AllLinkButton.displayName = 'AllLinkButton';
🧹 Nitpick comments (1)
src/components/layout/SideNavigation/components/MenuSection/MenuSection.tsx (1)

16-20: MENU_ITEMS 배열이 매 렌더링마다 재생성됩니다.

MENU_ITEMS 배열이 컴포넌트 내부에 정의되어 있어 렌더링될 때마다 새로 생성됩니다. useMemo를 사용하여 메모이제이션하면 불필요한 재생성을 방지할 수 있습니다.

♻️ 제안하는 수정 사항
+import { useMemo } from 'react';
+
 const MenuSection = ({ isOpen }: Props) => {
   const { type, open } = useModalStore();
 
-  const MENU_ITEMS = [
+  const MENU_ITEMS = useMemo(() => [
     { id: 'new-chat', item: <NewChatButton /> },
     { id: 'add-link', item: <AddLinkButton onClick={() => open('ADD_LINK')} /> },
     { id: 'all-link', item: <AllLinkButton /> },
-  ];
+  ], [open]);
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 24f965c and 880454a.

📒 Files selected for processing (8)
  • src/components/layout/SideNavigation/SideNavigation.tsx
  • src/components/layout/SideNavigation/components/Header/SideNavToggle.tsx
  • src/components/layout/SideNavigation/components/Header/SideNavigationHeader.tsx
  • src/components/layout/SideNavigation/components/MenuSection/AddLinkButton.tsx
  • src/components/layout/SideNavigation/components/MenuSection/AddLinkModal.tsx
  • src/components/layout/SideNavigation/components/MenuSection/AllLinkButton.tsx
  • src/components/layout/SideNavigation/components/MenuSection/MenuSection.tsx
  • src/components/layout/SideNavigation/components/MenuSection/NewChatButton.tsx
💤 Files with no reviewable changes (1)
  • src/components/layout/SideNavigation/components/Header/SideNavToggle.tsx
✅ Files skipped from review due to trivial changes (1)
  • src/components/layout/SideNavigation/components/MenuSection/NewChatButton.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/components/layout/SideNavigation/components/Header/SideNavigationHeader.tsx
  • src/components/layout/SideNavigation/SideNavigation.tsx
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: Bangdayeon
Repo: Team-SoFa/linkiving PR: 102
File: src/components/layout/SideNavigation/components/AddLinkModal/AddLinkModal.tsx:23-23
Timestamp: 2025-11-23T14:52:20.769Z
Learning: In src/components/layout/SideNavigation/components/AddLinkModal/AddLinkModal.tsx, the hardcoded '/file.svg' thumbnail is intentional as a placeholder because the backend API for fetching link metadata/thumbnails is still in preparation. The actual thumbnail fetch logic will be implemented after the backend is ready.
📚 Learning: 2025-11-23T14:52:20.769Z
Learnt from: Bangdayeon
Repo: Team-SoFa/linkiving PR: 102
File: src/components/layout/SideNavigation/components/AddLinkModal/AddLinkModal.tsx:23-23
Timestamp: 2025-11-23T14:52:20.769Z
Learning: In src/components/layout/SideNavigation/components/AddLinkModal/AddLinkModal.tsx, the hardcoded '/file.svg' thumbnail is intentional as a placeholder because the backend API for fetching link metadata/thumbnails is still in preparation. The actual thumbnail fetch logic will be implemented after the backend is ready.

Applied to files:

  • src/components/layout/SideNavigation/components/MenuSection/AllLinkButton.tsx
  • src/components/layout/SideNavigation/components/MenuSection/MenuSection.tsx
  • src/components/layout/SideNavigation/components/MenuSection/AddLinkButton.tsx
📚 Learning: 2025-11-23T12:03:33.890Z
Learnt from: Bangdayeon
Repo: Team-SoFa/linkiving PR: 97
File: src/components/basics/LinkCard/LinkCard.tsx:12-19
Timestamp: 2025-11-23T12:03:33.890Z
Learning: In src/components/basics/LinkCard/LinkCard.tsx, the summary prop should remain required (string type) because the backend always provides it as a string value. The isHaveSummary flag controls whether to display the summary text or show the AddSummaryButton, not whether the data exists.

Applied to files:

  • src/components/layout/SideNavigation/components/MenuSection/AddLinkButton.tsx
🧬 Code graph analysis (2)
src/components/layout/SideNavigation/components/MenuSection/AllLinkButton.tsx (4)
src/components/layout/SideNavigation/components/AllLinkButton.tsx (1)
  • LinkNavItem (3-7)
src/components/layout/SideNavigation/components/NewChatButton.tsx (1)
  • LinkNavItem (3-5)
src/components/layout/SideNavigation/components/NavItem/LinkNavItem.tsx (2)
  • LinkNavItemProps (8-15)
  • props (17-49)
src/components/layout/SideNavigation/components/NavItem/NavItem.tsx (2)
  • props (12-36)
  • NavItemProps (7-10)
src/components/layout/SideNavigation/components/MenuSection/MenuSection.tsx (4)
src/stores/modalStore.ts (1)
  • useModalStore (19-24)
src/components/layout/SideNavigation/components/NewChatButton.tsx (1)
  • LinkNavItem (3-5)
src/components/layout/SideNavigation/components/AddLinkModal.tsx (2)
  • TextArea (73-83)
  • useModalStore (22-112)
src/components/layout/SideNavigation/components/AddLinkButton.tsx (1)
  • AddLinkButtonProps (7-11)
🔇 Additional comments (3)
src/components/layout/SideNavigation/components/MenuSection/AddLinkButton.tsx (1)

1-1: LGTM!

새로운 MenuSection 디렉토리 구조에 맞게 import 경로가 올바르게 업데이트되었습니다.

src/components/layout/SideNavigation/components/MenuSection/AllLinkButton.tsx (1)

1-1: LGTM!

새로운 MenuSection 디렉토리 구조에 맞게 import 경로가 올바르게 업데이트되었습니다.

src/components/layout/SideNavigation/components/MenuSection/MenuSection.tsx (1)

46-46: AddLinkModal 컴포넌트는 MenuSection 디렉토리에 올바르게 위치하고 있으며, ./AddLinkModal import 경로는 정확합니다.

Copy link

@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

🤖 Fix all issues with AI agents
In @src/components/layout/SideNavigation/components/MenuSection/MenuSection.tsx:
- Around line 42-46: In MenuSection.tsx the inner {!isOpen} check inside the
motion.div is redundant because the outer condition already gates rendering;
remove the nested conditional and render item.item directly inside the
motion.div. Also either remove the unused transition prop on the motion.div or
make the animation real by adding animate and initial props (for example
opacity/scale variants) so the transition has effect; refer to the MenuSection
component, the motion.div element, the isOpen boolean and the item.item render
to locate and update the code.
🧹 Nitpick comments (1)
src/components/layout/SideNavigation/components/MenuSection/MenuSection.tsx (1)

17-24: useMemo의 의존성 배열을 재검토하세요.

open 함수는 zustand 스토어에서 제공하는 안정적인 참조이므로, 실제로 MENU_ITEMS 배열이 재생성될 필요가 없습니다. 이 경우 useMemo를 제거하거나 의존성 배열을 빈 배열로 변경하는 것을 고려해보세요.

♻️ 제안하는 수정 사항

옵션 1: useMemo 제거

-  const MENU_ITEMS = useMemo(
-    () => [
+  const MENU_ITEMS = [
       { id: 'new-chat', item: <NewChatButton /> },
       { id: 'add-link', item: <AddLinkButton onClick={() => open('ADD_LINK')} /> },
       { id: 'all-link', item: <AllLinkButton /> },
-    ],
-    [open]
-  );
+  ];

옵션 2: 빈 의존성 배열 사용

   const MENU_ITEMS = useMemo(
     () => [
       { id: 'new-chat', item: <NewChatButton /> },
       { id: 'add-link', item: <AddLinkButton onClick={() => open('ADD_LINK')} /> },
       { id: 'all-link', item: <AllLinkButton /> },
     ],
-    [open]
+    []
   );
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 880454a and 098499a.

📒 Files selected for processing (8)
  • src/components/layout/SideNavigation/SideNavigation.tsx
  • src/components/layout/SideNavigation/components/Header/SideNavToggle.tsx
  • src/components/layout/SideNavigation/components/Header/SideNavigationHeader.tsx
  • src/components/layout/SideNavigation/components/MenuSection/AddLinkButton.tsx
  • src/components/layout/SideNavigation/components/MenuSection/AddLinkModal.tsx
  • src/components/layout/SideNavigation/components/MenuSection/AllLinkButton.tsx
  • src/components/layout/SideNavigation/components/MenuSection/MenuSection.tsx
  • src/components/layout/SideNavigation/components/MenuSection/NewChatButton.tsx
💤 Files with no reviewable changes (1)
  • src/components/layout/SideNavigation/components/Header/SideNavToggle.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/components/layout/SideNavigation/components/MenuSection/NewChatButton.tsx
  • src/components/layout/SideNavigation/components/MenuSection/AddLinkButton.tsx
  • src/components/layout/SideNavigation/components/Header/SideNavigationHeader.tsx
  • src/components/layout/SideNavigation/SideNavigation.tsx
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-23T14:52:20.769Z
Learnt from: Bangdayeon
Repo: Team-SoFa/linkiving PR: 102
File: src/components/layout/SideNavigation/components/AddLinkModal/AddLinkModal.tsx:23-23
Timestamp: 2025-11-23T14:52:20.769Z
Learning: In src/components/layout/SideNavigation/components/AddLinkModal/AddLinkModal.tsx, the hardcoded '/file.svg' thumbnail is intentional as a placeholder because the backend API for fetching link metadata/thumbnails is still in preparation. The actual thumbnail fetch logic will be implemented after the backend is ready.

Applied to files:

  • src/components/layout/SideNavigation/components/MenuSection/AllLinkButton.tsx
  • src/components/layout/SideNavigation/components/MenuSection/MenuSection.tsx
🧬 Code graph analysis (2)
src/components/layout/SideNavigation/components/MenuSection/AllLinkButton.tsx (2)
src/components/layout/SideNavigation/components/AllLinkButton.tsx (1)
  • LinkNavItem (3-7)
src/components/layout/SideNavigation/components/NavItem/LinkNavItem.tsx (2)
  • LinkNavItemProps (8-15)
  • props (17-49)
src/components/layout/SideNavigation/components/MenuSection/MenuSection.tsx (4)
src/stores/modalStore.ts (1)
  • useModalStore (19-24)
src/components/layout/SideNavigation/components/NewChatButton.tsx (1)
  • LinkNavItem (3-5)
src/components/layout/SideNavigation/components/AddLinkModal.tsx (1)
  • useModalStore (22-112)
src/components/layout/SideNavigation/components/AddLinkButton.tsx (1)
  • AddLinkButtonProps (7-11)
🔇 Additional comments (1)
src/components/layout/SideNavigation/components/MenuSection/AllLinkButton.tsx (1)

1-9: 리팩토링 변경사항이 정상적으로 적용되었습니다.

import 경로가 새로운 디렉토리 구조에 맞게 업데이트되었고, 컴포넌트 로직은 올바르게 동작합니다.

Comment on lines +42 to +46
{!isOpen && (
<motion.div transition={{ duration: 1 }} className="absolute inset-0">
{!isOpen && item.item}
</motion.div>
)}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

중복된 조건 검사와 불필요한 transition이 있습니다.

Line 42에서 이미 !isOpen을 검사하고 있는데, Line 44에서 다시 !isOpen을 검사하는 것은 중복입니다. 또한 Line 43의 motion.divtransition 속성만 있고 animateinitial 속성이 없어서 실제로 전환 애니메이션이 작동하지 않습니다.

🔎 제안하는 수정 사항
          {/* 닫혔을 때 */}
          {!isOpen && (
-            <motion.div transition={{ duration: 1 }} className="absolute inset-0">
-              {!isOpen && item.item}
-            </motion.div>
+            <div className="absolute inset-0">
+              {item.item}
+            </div>
          )}
🤖 Prompt for AI Agents
In @src/components/layout/SideNavigation/components/MenuSection/MenuSection.tsx
around lines 42 - 46, In MenuSection.tsx the inner {!isOpen} check inside the
motion.div is redundant because the outer condition already gates rendering;
remove the nested conditional and render item.item directly inside the
motion.div. Also either remove the unused transition prop on the motion.div or
make the animation real by adding animate and initial props (for example
opacity/scale variants) so the transition has effect; refer to the MenuSection
component, the motion.div element, the isOpen boolean and the item.item render
to locate and update the code.

@Seong-Myeong
Copy link
Contributor

rebase 진행 및 코드 래빗 리뷰 조치여부 확인부탁드립니다.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SideNavigation 기존 아이템들 section별로 구분

3 participants