Skip to content

Conversation

@LeeCh0129
Copy link

@LeeCh0129 LeeCh0129 commented Jun 11, 2025

📌 변경 사항 개요

사이드바 컴포넌트 구현 및 대시보드 네비게이션

✨ 요약

  • 고정형 사이드바 레이아웃 구현
  • 대시보드 목록 표시 및 네비게이션
  • 대시보드 생성 버튼 컴포넌트

📝 상세 내용

1. Sidebar.tsx - 메인 사이드바 컨테이너

  • Coplan 로고
  • Dash Boards 섹션 헤더 + 생성 버튼
  • 대시보드 목록

2. DashBoardItem.tsx - 개별 대시보드 아이템

  • 대시보드 제목, 컬러 도트, 내가 만든 경우(왕관) 표시
  • 클릭 시 /dashboard/{id}로 라우팅

3. CreateDashboardButton.tsx - 대시보드 생성 버튼

  • 새 대시보드 생성 트리거(기능은 추후)

4. dashboard.ts - 타입 정의

  • APi 명세 기반으로 Dashboard 인터페이스

🔗 관련 이슈

#41

🖼️ 스크린샷

image

✅ 체크리스트

  • 브랜치 네이밍 컨벤션을 준수했습니다
  • 커밋 컨벤션을 준수했습니다
  • 코드가 프로젝트의 스타일 가이드라인을 준수합니다

💡 참고 사항

  • API 연동 예정(목데이터 구조를 APi 명세와 일치하도록함)
  • 알아보기 편하도록 섹션별로 주석으로 구분

Summary by CodeRabbit

  • 신규 기능
    • 사이드바 컴포넌트가 추가되어 대시보드 목록과 생성 버튼을 표시합니다.
    • 각 대시보드 항목에 소유자 표시와 색상 아이콘, 활성 상태 표시 기능이 추가되었습니다.
    • "새 대시보드 생성" 버튼이 추가되어 대시보드 생성 동작을 지원합니다.
    • 테스트 페이지가 사이드바와 메인 콘텐츠 영역의 2단 레이아웃으로 개선되었습니다.

@LeeCh0129 LeeCh0129 added this to the 1차 구현 기간 milestone Jun 11, 2025
@LeeCh0129 LeeCh0129 self-assigned this Jun 11, 2025
@LeeCh0129 LeeCh0129 added the ✨Feat 기능 개발 label Jun 11, 2025
@coderabbitai
Copy link

coderabbitai bot commented Jun 11, 2025

Walkthrough

이 변경 사항은 사이드바와 대시보드 관련 UI 컴포넌트, 타입 정의, 그리고 테스트 페이지 레이아웃을 추가 및 리팩토링합니다. 사이드바와 대시보드 항목, 생성 버튼 컴포넌트가 새로 도입되었으며, 관련 타입스크립트 인터페이스도 추가되었습니다. 테스트 페이지는 새로운 2단 레이아웃으로 재구성되었습니다.

Changes

파일/경로 변경 요약
src/app/shared/components/common/sidebar/CreateDashboardButton.tsx 대시보드 생성 버튼 컴포넌트 신규 추가
src/app/shared/components/common/sidebar/DashboardItem.tsx 대시보드 항목 버튼 컴포넌트 신규 추가
src/app/shared/components/common/sidebar/Sidebar.tsx 사이드바 컴포넌트 신규 추가, 대시보드 목록 및 생성 버튼 포함
src/app/shared/types/dashboard.ts 대시보드, 대시보드 목록 응답, 생성 요청, 컴포넌트 props 등 타입 인터페이스 신규 정의
src/app/tester/page.tsx 기존 단순 테스트 레이아웃을 사이드바와 메인 영역이 있는 2단 구조로 리팩토링, UI 테스트 섹션 추가

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Sidebar
    participant DashboardItem
    participant CreateDashboardButton
    participant Router

    User->>Sidebar: 페이지 진입
    Sidebar->>DashboardItem: 대시보드 목록 렌더링
    User->>DashboardItem: 대시보드 항목 클릭
    DashboardItem->>Sidebar: onClick(dashboardId)
    Sidebar->>Router: 대시보드 상세 페이지로 이동

    User->>CreateDashboardButton: 대시보드 생성 버튼 클릭
    CreateDashboardButton->>Sidebar: onClick()
    Sidebar->>Sidebar: (현재 콘솔 로그, 추후 모달 등 구현 예정)
Loading

Poem

🐰
사이드바에 토끼가 뛰노네,
대시보드 버튼이 반짝이며 인사해.
새로운 타입이 질서 있게 줄서고,
테스트 페이지도 옷을 갈아입네!
오늘도 코드밭에 봄바람 솔솔,
토끼는 신나서 깡총깡총!

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

npm error Exit handler never called!
npm error This is an error with npm itself. Please report this error at:
npm error https://github.com/npm/cli/issues
npm error A complete log of this run can be found in: /.npm/_logs/2025-06-11T08_30_45_380Z-debug-0.log


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f2d0a00 and 355eb98.

📒 Files selected for processing (2)
  • src/app/shared/components/common/sidebar/CreateDashboardButton.tsx (1 hunks)
  • src/app/shared/components/common/sidebar/DashboardItem.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/app/shared/components/common/sidebar/DashboardItem.tsx
  • src/app/shared/components/common/sidebar/CreateDashboardButton.tsx
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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

🧹 Nitpick comments (5)
src/app/shared/components/common/sidebar/CreateDashboardButton.tsx (1)

11-15: 버튼 type 속성 명시 권장

폼 내부에서 사용될 가능성을 대비해 type="button"을 명시해 두면 예기치 않게 submit 동작이 발생하는 것을 방지할 수 있습니다.

-    <button
+    <button
+      type="button"
       onClick={onClick}
       className="flex size-20 items-center justify-center rounded-6 transition-colors hover:bg-gray-50"
       aria-label="새 대시보드 생성"
src/app/tester/page.tsx (1)

21-26: flex 컨테이너 불필요 / 레이아웃 간결화 제안

Sidebarposition: fixed 이므로 부모에 flex 를 걸어둘 필요가 없습니다.
오히려 불필요한 flex 컨텍스트로 인해 예상치 못한 정렬 이슈가 생길 수 있습니다.

-    <div className="flex">
+    <div>

또는 콘텐츠 영역에 pl-300(padding-left) 를 주어 사이드바 넓이만큼 공간을 확보하는 편이 더 단순합니다.

src/app/shared/components/common/sidebar/DashboardItem.tsx (1)

17-21: 접근성과 기본 동작 개선 – type·aria-current 추가

  1. 버튼 기본 type을 명시해 폼 안에서의 암묵적 submit 방지
  2. 현재 선택된 대시보드임을 스크린리더에 전달하기 위해 aria-current="page" 사용
-    <button
-      onClick={handleClick}
+    <button
+      type="button"
+      aria-current={isActive ? 'page' : undefined}
+      onClick={handleClick}
src/app/shared/components/common/sidebar/Sidebar.tsx (2)

14-61: mockDashboards 재생성 방지

컴포넌트가 리렌더링될 때마다 새로운 배열·객체가 생성되어 자식 DashboardItem 의 불필요한 리렌더를 유발할 수 있습니다. 상수라면 파일 최상단으로 빼거나 useMemo 로 메모이즈하는 편이 좋습니다.

-  const mockDashboards = [
+const mockDashboards = [
   /* ... */
-  ]
+] as const

63-70: 이벤트 핸들러 useCallback 래핑 고려

handleDashboardClick / handleCreateDashboard 가 렌더마다 새로 생성되어 하위 컴포넌트에 전달됩니다. 리렌더 최적화를 원한다면 useCallback 으로 래핑해 불필요한 prop 변경을 줄일 수 있습니다.

-  const handleDashboardClick = (dashboardId: number) => {
-    router.push(`/dashboard/${dashboardId}`)
-  }
+  const handleDashboardClick = useCallback(
+    (dashboardId: number) => router.push(`/dashboard/${dashboardId}`),
+    [router],
+  )

[nitpick]

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 70eba7b and f2d0a00.

⛔ Files ignored due to path filters (1)
  • public/images/logo-light2.svg is excluded by !**/*.svg
📒 Files selected for processing (5)
  • src/app/shared/components/common/sidebar/CreateDashboardButton.tsx (1 hunks)
  • src/app/shared/components/common/sidebar/DashboardItem.tsx (1 hunks)
  • src/app/shared/components/common/sidebar/Sidebar.tsx (1 hunks)
  • src/app/shared/types/dashboard.ts (1 hunks)
  • src/app/tester/page.tsx (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
src/app/shared/components/common/sidebar/CreateDashboardButton.tsx (1)
src/app/shared/types/dashboard.ts (1)
  • CreateDashboardButtonProps (26-28)
src/app/shared/components/common/sidebar/DashboardItem.tsx (1)
src/app/shared/types/dashboard.ts (1)
  • DashboardItemProps (20-24)
src/app/shared/components/common/sidebar/Sidebar.tsx (2)
src/app/shared/components/common/sidebar/CreateDashboardButton.tsx (1)
  • CreateDashboardButton (7-26)
src/app/shared/components/common/sidebar/DashboardItem.tsx (1)
  • DashboardItem (7-45)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: eslint-check
🔇 Additional comments (1)
src/app/shared/types/dashboard.ts (1)

1-35: 타입 정의 전반적으로 양호

도메인 모델과 컴포넌트 Props 가 명확히 분리되어 있어 가독성이 좋습니다.
추후 날짜 필드는 string 대신 Date 파싱 결과 객체로 전환할 여지가 있으나, 현 단계에서는 문제 없습니다.

Copy link
Contributor

@dkslel1225 dkslel1225 left a comment

Choose a reason for hiding this comment

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

사이드바 구현 수고하셨습니다~~ 컴포넌트 분리해서 구현해주셨군요!👍👍 API 연결까지 마무리되면 가져다 쓰겠습니당⛄️

Copy link

@Insung-Jo Insung-Jo left a comment

Choose a reason for hiding this comment

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

작업 수고 많으셨습니다! 접근성도 고려하신 부분도 보이는 거 같아서 공부가 되는 거 같습니다! 궁금한 점은 리뷰로 남겼으니 자유롭게 답변해주시면 감사하겠습니다!👍 👍

import CreateDashboardButton from './CreateDashboardButton'
import DashboardItem from './DashboardItem'

export default function Sidebar(): JSX.Element {

Choose a reason for hiding this comment

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

ReactNode는 사용해본 기억이 있는데 JSX.Element는 처음 보는 거 같습니다! 어떤 타입인지 설명해주실 수 있을까요?

Copy link
Author

Choose a reason for hiding this comment

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

JSX.Element는 JSX로 작성된 React 엘리먼트만을 나타내는 타입이예요. <div>, <Component /> 같은 JSX 표현식의 결과물을 의미한다고 보시면 됩니다. Sidebar 컴포넌트에서는 항상 <aside> JSX를 반환하고 조건부 렌더링이나 null 변환이 없어서 JSX.Element가 더 명확하다고 생각해서 사용했습니다.

Comment on lines +89 to +107
<div className="px-20 py-24">
{/* 섹션 헤더 */}
<div className="mb-24 flex items-center justify-between">
<h2 className="Text-gray text-12 font-semibold">Dash Boards</h2>
<CreateDashboardButton onClick={handleCreateDashboard} />
</div>

{/* 대시보드 목록 */}
<div className="space-y-8">
{mockDashboards.map((dashboard) => (
<DashboardItem
key={dashboard.id}
dashboard={dashboard}
isActive={pathname === `/dashboard/${dashboard.id}`}
onClick={handleDashboardClick}
/>
))}
</div>
</div>

Choose a reason for hiding this comment

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

이 부분은 추후에 시멘틱까지 고려한다면 nav, ul,li 태그를 활용해볼 수 있을 거 같습니다!

Copy link
Author

Choose a reason for hiding this comment

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

감사합니다 :) 추후에 여유가 생기면 시멘틱까지 고려해서 수정해봐야겠네요.

Copy link
Contributor

Choose a reason for hiding this comment

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

👍👍

return (
<button
type="button"
aria-current={isActive ? 'page' : undefined}

Choose a reason for hiding this comment

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

aria-label은 사용해 봤는데 aria-current는 처음 보는 거 같습니다! 이것은 어떤 역할은 하는 건가요?

Copy link
Author

Choose a reason for hiding this comment

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

저도 처음에는 ARIA없이 구현을 했었는데, 따로 AI 코드리뷰 과정에서 스크린 리더 사용자들은 시각적 표현을 인식할 수 없어서 현재 위치를 알기 어렵다는 피드백을 주더라구요. 그래서 따로 웹 접근성을 고려해 한번 추가해봤습니다. 물론 기능적으로는 없어도 동작하지만요. 필수는 아니지만 그냥 습관을 기른다고 생각하는 차원에서 반영해봤어요. 리뷰 덕분에 WAI-ARIA 관련해서 이런것들이 있구나 하고 찾아보게 되었네요 :)
알면 알수록 점점 알아갈게 많아지는거 같네요...

Copy link
Contributor

@yuj2n yuj2n left a comment

Choose a reason for hiding this comment

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

찬호님 작업 수고하셨습니다~~

<button
type="button"
onClick={onClick}
className="flex size-20 items-center justify-center rounded-6 transition-colors hover:bg-gray-50"
Copy link
Contributor

Choose a reason for hiding this comment

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

background 색상의 경우 global 스타일로 빼서 사용하면 좋지 않을까 합니다!!

Copy link
Author

@LeeCh0129 LeeCh0129 Jun 12, 2025

Choose a reason for hiding this comment

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

감사합니다 :) 중복으로 사용할 일이 생기면 global 스타일로 빼서 올려두겠습니다 👍

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

Labels

✨Feat 기능 개발

Projects

None yet

Development

Successfully merging this pull request may close these issues.

✨ Feat: 사이드바 컴포넌트 구현

5 participants