-
Notifications
You must be signed in to change notification settings - Fork 2
♻️ refactor: 사이드바 무한스크롤 및 반응형 #102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
""" Walkthrough이 변경사항은 대시보드 관련 주요 컴포넌트와 사이드바에 반응형 디자인을 도입하고, 사이드바의 대시보드 목록에 무한 스크롤 기능을 추가합니다. 또한, 새로운 커스텀 훅 두 개가 추가되어 무한 스크롤과 페이지네이션을 지원합니다. 모든 변경은 UI 및 스타일 개선에 집중되어 있으며, 기존의 로직이나 API는 그대로 유지됩니다. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Sidebar
participant useDashboardsInfinite
participant useContainerInfiniteScroll
participant API
User->>Sidebar: 사이드바 진입/스크롤
Sidebar->>useDashboardsInfinite: 첫 페이지 대시보드 요청
useDashboardsInfinite->>API: GET /dashboards?page=1
API-->>useDashboardsInfinite: 대시보드 리스트 반환
useDashboardsInfinite-->>Sidebar: 데이터 반환
Sidebar->>useContainerInfiniteScroll: 컨테이너 ref 등록
User->>Sidebar: 컨테이너 스크롤
useContainerInfiniteScroll->>Sidebar: 스크롤 임계치 도달 시 알림
Sidebar->>useDashboardsInfinite: 다음 페이지 요청
useDashboardsInfinite->>API: GET /dashboards?page=2
API-->>useDashboardsInfinite: 다음 대시보드 리스트 반환
useDashboardsInfinite-->>Sidebar: 데이터 반환
Sidebar-->>User: 추가 대시보드 렌더링
Possibly related PRs
Suggested reviewers
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
npm error Exit handler never called! 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms (1)
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this 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 (7)
src/app/shared/components/common/sidebar/Sidebar.tsx (1)
96-100: 인라인 스타일 대신 CSS 클래스 사용 권장
minHeight인라인 스타일을 Tailwind CSS 클래스로 변경하는 것이 일관성 측면에서 좋습니다.<div ref={containerRef} className="tablet:space-y-6 mobile:space-y-4 flex-1 space-y-8 overflow-y-auto" - style={{ minHeight: '200px' }} + className="tablet:space-y-6 mobile:space-y-4 flex-1 space-y-8 overflow-y-auto min-h-[200px]" >src/app/mydashboard/components/InvitedDashboardTable/InvitedDashboardRow.tsx (2)
88-123: 모바일 카드 레이아웃이 사용성을 크게 개선합니다.모바일에서 테이블 대신 라벨이 있는 카드 형태로 표시하여 작은 화면에서의 가독성과 사용성을 향상시켰습니다.
향후 버튼 컴포넌트를 분리하여 코드 중복을 줄이는 것을 고려해보세요:
const ActionButtons = ({ onAccept, onReject, isProcessing, variant = 'desktop' }) => { const buttonClasses = variant === 'mobile' ? "h-32 w-109 text-12" : "tablet:w-72 tablet:h-30 tablet:text-12 h-32 w-70 text-14"; return ( <div className={variant === 'mobile' ? "flex gap-8" : "flex items-center justify-center gap-10"}> {/* 버튼들 */} </div> ); };
55-123: 코드 중복 최적화를 고려해보세요.두 레이아웃에서 동일한 로직이 반복됩니다. 공통 컴포넌트나 hooks로 추출하여 유지보수성을 향상시킬 수 있습니다.
예시 리팩터링:
const ButtonGroup = ({ isProcessing, onAccept, onReject, isMobile }) => ( <div className={`flex ${isMobile ? 'gap-8' : 'items-center justify-center gap-10'}`}> <button onClick={onAccept} disabled={isProcessing} className={`BG-blue ${isMobile ? 'h-32 w-109 text-12' : 'tablet:w-72 tablet:h-30 tablet:text-12 h-32 w-70 text-14'} flex items-center justify-center rounded-8 font-medium text-white transition-colors hover:bg-blue-600 disabled:cursor-not-allowed disabled:opacity-50`} > {isProcessing ? '처리 중' : '수락'} </button> {/* 거절 버튼도 유사하게 처리 */} </div> )src/app/mydashboard/page.tsx (4)
16-16: 메인 컨테이너 마진 클래스 가독성 개선
tablet:ml-160 mobile:ml-67 ml-300순서로 동작에는 문제가 없으나, 기본값 → tablet → mobile 순서로 클래스 배열을 재정렬하면 유지보수가 용이합니다.
21-21: 메인 콘텐츠 패딩 순서 재정렬 제안
tablet:p-24 mobile:p-16 p-40패딩 클래스도 기본값(p-40) → tablet → mobile 순으로 정리하면 클래스 스캔 시 이해도가 높아집니다.
25-25: 고정 너비 대신 max-width 사용 검토
w-1022같은 고정 폭은 해상도별 유연성을 떨어뜨릴 수 있습니다. 디자인 가이드에 맞춰 반응형max-w-[1022px]또는 유동적 그리드 레이아웃을 고려해 보세요.
26-26: 반응형 텍스트 크기 클래스 중복 제거
tablet:text-20과mobile:text-20이 동일해 중복입니다. 하나의 브레이크포인트만 남기거나 공통 설정으로 통합하여 코드량을 줄이세요.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
src/app/mydashboard/components/InvitedDashboardTable/InvitedDashboardRow.tsx(1 hunks)src/app/mydashboard/components/InvitedDashboardTable/InvitedDashboardTable.tsx(7 hunks)src/app/mydashboard/components/InvitedDashboardTable/SearchInput.tsx(1 hunks)src/app/mydashboard/components/MyDashboardGrid/AddDashboardCard.tsx(1 hunks)src/app/mydashboard/components/MyDashboardGrid/MyDashboardCard.tsx(2 hunks)src/app/mydashboard/components/MyDashboardGrid/MyDashboardGrid.tsx(3 hunks)src/app/mydashboard/page.tsx(1 hunks)src/app/shared/components/common/sidebar/DashboardItem.tsx(1 hunks)src/app/shared/components/common/sidebar/Sidebar.tsx(2 hunks)src/app/shared/hooks/useContainerInfiniteScroll.ts(1 hunks)src/app/shared/hooks/useDashboardInfinite.ts(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (4)
src/app/mydashboard/components/MyDashboardGrid/MyDashboardGrid.tsx (1)
src/app/mydashboard/components/MyDashboardGrid/AddDashboardCard.tsx (1)
AddDashboardCard(7-31)
src/app/mydashboard/page.tsx (1)
src/app/mydashboard/components/MyDashboardGrid/MyDashboardGrid.tsx (1)
MyDashboardGrid(10-120)
src/app/shared/hooks/useDashboardInfinite.ts (1)
src/app/shared/types/dashboard.ts (1)
DashboardListResponse(13-17)
src/app/shared/components/common/sidebar/Sidebar.tsx (5)
src/app/shared/hooks/useDashboardInfinite.ts (1)
useDashboardsInfinite(12-46)src/app/shared/hooks/useContainerInfiniteScroll.ts (1)
useContainerInfiniteScroll(14-47)src/app/shared/types/dashboard.ts (1)
Dashboard(2-10)src/app/shared/components/common/sidebar/CreateDashboardButton.tsx (1)
CreateDashboardButton(7-27)src/app/shared/components/common/sidebar/DashboardItem.tsx (1)
DashboardItem(7-47)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: eslint-check
🔇 Additional comments (35)
src/app/mydashboard/components/MyDashboardGrid/AddDashboardCard.tsx (1)
17-17: 반응형 디자인 구현이 적절합니다!버튼의 크기가 디바이스별로 적절하게 조정되며, PR 목표에 명시된 반응형 사양과 일치합니다.
src/app/shared/hooks/useDashboardInfinite.ts (1)
33-42: ```shell
#!/bin/bash
sed -n '1,200p' src/app/shared/hooks/useDashboardInfinite.ts</details> <details> <summary>src/app/shared/hooks/useContainerInfiniteScroll.ts (1)</summary> `14-47`: **잘 구현된 무한 스크롤 훅입니다!** 스크롤 이벤트 처리가 효율적이며, passive 리스너 사용과 적절한 cleanup으로 성능과 메모리 관리가 우수합니다. </details> <details> <summary>src/app/shared/components/common/sidebar/Sidebar.tsx (1)</summary> `23-154`: **무한 스크롤과 반응형 디자인 구현이 훌륭합니다!** - 페이지네이션 기반 무한 스크롤이 잘 구현되었습니다 - 로딩, 에러, 완료 상태 처리가 적절합니다 - 모바일/태블릿/데스크톱 반응형 UI가 PR 목표와 일치합니다 </details> <details> <summary>src/app/shared/components/common/sidebar/DashboardItem.tsx (1)</summary> `21-36`: **반응형 디자인이 잘 적용되었습니다!** 디바이스별 요소 크기와 가시성 조정이 적절하며, 특히 모바일에서 공간 활용을 위해 텍스트를 숨기고 아이콘만 표시하는 것이 좋은 UX 결정입니다. </details> <details> <summary>src/app/mydashboard/components/InvitedDashboardTable/SearchInput.tsx (4)</summary> `17-17`: **반응형 컨테이너 스타일링이 적절합니다.** 모바일에서 높이를 36 단위로 줄이고 전체 폭을 사용하도록 하여 작은 화면에서의 사용성을 개선했습니다. --- `23-23`: **일관성 있는 모바일 반응형 스타일링입니다.** 입력 요소의 높이, 텍스트 크기, 플레이스홀더 텍스트 크기를 모바일에서 일관성 있게 축소하여 더 나은 사용자 경험을 제공합니다. --- `17-17`: **모바일 반응형 높이 조정이 적절합니다.** 컨테이너의 높이를 모바일에서 36으로 조정한 것이 좋습니다. input 요소의 높이와 일치하여 일관성을 유지합니다. --- `23-23`: **모바일 최적화가 잘 구현되었습니다.** input 요소의 높이, 텍스트 크기, placeholder 텍스트 크기를 모바일에서 일관되게 조정하여 터치 기반 인터페이스에 적합합니다. </details> <details> <summary>src/app/mydashboard/components/MyDashboardGrid/MyDashboardCard.tsx (4)</summary> `22-22`: **적절한 반응형 카드 크기 조정과 호버 효과 개선입니다.** 각 브레이크포인트에 맞는 카드 크기 조정과 `BG-Input-hovered` 클래스 추가로 다크모드 호버 효과를 개선했습니다. --- `33-33`: **텍스트 크기와 최대 너비의 반응형 조정이 우수합니다.** 화면 크기에 따라 제목의 최대 너비와 폰트 크기를 조정하여 텍스트 오버플로우를 방지하고 가독성을 향상시켰습니다. --- `22-22`: **반응형 카드 크기 조정과 hover 효과가 잘 구현되었습니다.** `BG-Input-hovered` 클래스 추가로 다크모드 hover 효과가 개선되었고, 태블릿과 모바일의 카드 크기가 AddDashboardCard와 일관되게 설정되었습니다. --- `33-33`: **제목 텍스트의 반응형 처리가 적절합니다.** 모바일에서 텍스트 크기를 14로 줄이고 max-width를 조경하여 작은 화면에서의 가독성을 개선했습니다. 태블릿과 모바일의 서로 다른 max-width 설정도 적절합니다. </details> <details> <summary>src/app/mydashboard/components/MyDashboardGrid/MyDashboardGrid.tsx (7)</summary> `25-25`: **로딩 상태의 반응형 레이아웃이 잘 구현되었습니다.** 로딩 스켈레톤에도 동일한 반응형 그리드 시스템을 적용하여 일관성 있는 사용자 경험을 제공합니다. --- `33-33`: **스켈레톤 카드 크기가 실제 카드와 일치합니다.** 로딩 스켈레톤의 크기가 실제 대시보드 카드의 반응형 크기와 정확히 일치하여 레이아웃 시프트를 방지합니다. --- `64-64`: **효과적인 반응형 그리드 시스템 구현입니다.** 데스크톱(flex wrap), 태블릿(2컬럼 그리드), 모바일(세로 배치)로 단계적으로 레이아웃이 조정되며, 최대 너비 제한이 적절히 설정되었습니다. --- `79-79`: **페이지네이션의 반응형 스타일링이 일관성 있습니다.** 페이지네이션 컨테이너도 메인 그리드와 동일한 최대 너비 제한을 적용하여 전체 레이아웃의 일관성을 유지합니다. --- `25-25`: **반응형 그리드 레이아웃이 훌륭하게 구현되었습니다.** 데스크톱의 flex-wrap에서 태블릿의 2열 그리드, 모바일의 1열 flex-column으로의 전환이 자연스럽습니다. PR 목표의 3열->2열->1열 구조와 정확히 일치합니다. Also applies to: 64-64 --- `33-33`: **로딩 스켈레톤의 반응형 크기 조정이 일관됩니다.** 실제 카드 컴포넌트와 동일한 반응형 크기를 사용하여 로딩 상태에서도 레이아웃 일관성을 유지합니다. --- `79-79`: **페이지네이션 컨테이너의 반응형 처리가 적절합니다.** 그리드 컨테이너와 동일한 max-width를 사용하여 전체적인 레이아웃 정렬을 유지합니다. </details> <details> <summary>src/app/mydashboard/components/InvitedDashboardTable/InvitedDashboardRow.tsx (3)</summary> `55-86`: **데스크톱/태블릿 레이아웃의 반응형 조정이 적절합니다.** 기존 테이블 레이아웃을 유지하면서 태블릿에서 버튼 크기와 텍스트 크기를 적절히 조정했습니다. --- `55-86`: **데스크톱/태블릿 테이블 레이아웃이 잘 유지되었습니다.** 기존 그리드 레이아웃을 유지하면서 모바일에서 숨기는 방식이 적절합니다. 태블릿용 버튼 크기 조정도 공간 효율성을 고려한 좋은 선택입니다. --- `87-123`: **모바일 카드 레이아웃이 사용자 친화적으로 구현되었습니다.** 테이블 형태를 카드 형태로 변환하여 모바일에서의 가독성과 터치 접근성을 크게 개선했습니다. "이름"과 "초대자" 라벨을 추가한 것도 직관적입니다. </details> <details> <summary>src/app/mydashboard/components/InvitedDashboardTable/InvitedDashboardTable.tsx (12)</summary> `53-53`: **로딩 스켈레톤의 일관성 있는 높이 조정입니다.** 검색창 스켈레톤의 높이를 실제 SearchInput 컴포넌트의 모바일 높이와 일치시켜 레이아웃 일관성을 유지합니다. --- `56-56`: **모바일에서 테이블 헤더 숨김 처리가 적절합니다.** 모바일에서는 카드 레이아웃을 사용하므로 테이블 헤더를 숨기는 것이 올바른 접근입니다. Also applies to: 121-121 --- `70-70`: **모바일 스켈레톤 스타일링이 카드 레이아웃과 일치합니다.** 모바일에서 스켈레톤 행에 배경색, 패딩, 둥근 모서리를 추가하여 실제 카드 레이아웃과 시각적으로 일치시켰습니다. --- `85-85`: **모바일 텍스트 크기 조정이 일관성 있게 적용되었습니다.** 에러 메시지, 빈 상태 메시지, 검색 결과 메시지 등 모든 텍스트 요소에 일관된 모바일 크기 조정(주로 12px)을 적용했습니다. Also applies to: 88-88, 107-107, 136-136, 158-158 --- `99-99`: **모바일 빈 상태 이미지 크기 조정이 적절합니다.** 이미지 크기를 100x100에서 60x60으로 줄여 모바일 화면에서 더 적절한 비율을 제공합니다. --- `132-132`: **모바일 카드 레이아웃을 위한 적절한 간격 조정입니다.** 모바일에서 카드 간의 간격을 제거하여 InvitedDashboardRow 컴포넌트의 모바일 카드 레이아웃과 조화를 이룹니다. --- `53-53`: **검색창 스켈레톤의 반응형 높이가 SearchInput과 일치합니다.** SearchInput 컴포넌트의 모바일 높이와 동일하게 설정하여 로딩 상태에서도 일관된 UI를 제공합니다. --- `56-56`: **모바일에서 테이블 헤더 숨김 처리가 적절합니다.** InvitedDashboardRow의 카드 레이아웃과 완벽하게 매치되어 모바일에서 직관적인 UI를 제공합니다. Also applies to: 121-121 --- `70-70`: **스켈레톤 로딩의 모바일 스타일링이 일관됩니다.** 실제 카드 레이아웃과 동일한 스타일링(rounded, background, padding, margin)을 적용하여 로딩 상태에서도 자연스러운 전환을 제공합니다. --- `85-85`: **텍스트 크기의 모바일 최적화가 체계적입니다.** 에러 메시지, 빈 상태 메시지, 검색 결과 메시지 등 모든 텍스트 요소가 모바일에서 적절한 크기로 조정되어 가독성을 확보했습니다. Also applies to: 88-88, 107-107, 136-136, 158-158 --- `99-99`: **빈 상태 이미지의 모바일 크기 조정이 적절합니다.** 100x100에서 60x60으로 줄여 모바일 화면에서 균형잡힌 비율을 유지합니다. --- `132-132`: **모바일에서 spacing 제거가 InvitedDashboardRow의 카드 레이아웃과 잘 맞습니다.** 카드 레이아웃에서는 각 카드가 자체 마진을 가지므로 컨테이너의 space-y를 제거한 것이 적절합니다. </details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
📌 변경 사항 개요
사이드바 무한스크롤 기능 구현 및 전체 반응형 디자인 적용
✨ 요약
📝 상세 내용
🔄 사이드바 무한스크롤 구현
useDashboardInfinite훅으로 pagination 방식 무한스크롤 구현useContainerInfiniteScroll훅으로 컨테이너 스크롤 감지📱 사이드바 반응형 구현
🏠 내 대시보드 페이지 반응형 구현
🎨 UX 개선
BG-Input-hovered클래스로 다크모드 호버 효과 개선h-screen→min-h-screen)🔗 관련 이슈
🖼️ 스크린샷
✅ 체크리스트
💡 참고 사항
Summary by CodeRabbit
신규 기능
기능 개선