-
Notifications
You must be signed in to change notification settings - Fork 2
✨ Feat: 카드 목록, 모달 내 댓글 목록에 무한 스크롤 구현 #101
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
✨ Feat: 카드 목록, 모달 내 댓글 목록에 무한 스크롤 구현 #101
Conversation
Walkthrough이 PR은 카드 및 댓글 목록의 무한 스크롤 기능을 도입하며, 관련 API와 훅, 스타일을 이에 맞게 리팩토링합니다. 기존의 페이지네이션 방식 훅과 API 함수는 삭제 또는 변경되었으며, 카드/댓글 모달 및 컬럼 컴포넌트의 레이아웃과 반응형 스타일도 일부 수정되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Column
participant useInfiniteCards
participant fetchCards
participant API
User->>Column: 스크롤하여 하단 접근
Column->>useInfiniteCards: fetchNextPage() 호출
useInfiniteCards->>fetchCards: 다음 페이지 요청(cursorId 포함)
fetchCards->>API: GET /cards?columnId&cursorId
API-->>fetchCards: 카드 데이터 반환
fetchCards-->>useInfiniteCards: 카드 데이터 반환
useInfiniteCards-->>Column: 새 카드 데이터 전달
Column-->>User: 카드 목록 업데이트
sequenceDiagram
participant User
participant CardModal
participant Comments
participant useInfiniteComments
participant fetchComments
participant API
User->>CardModal: 댓글 영역 스크롤
CardModal->>Comments: scrollRef 전달
Comments->>useInfiniteComments: fetchNextPage() 호출
useInfiniteComments->>fetchComments: 다음 댓글 페이지 요청(cursorId 포함)
fetchComments->>API: GET /comments?cardId&cursorId
API-->>fetchComments: 댓글 데이터 반환
fetchComments-->>useInfiniteComments: 댓글 데이터 반환
useInfiniteComments-->>Comments: 새 댓글 데이터 전달
Comments-->>User: 댓글 목록 업데이트
Possibly related PRs
Suggested labels
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! ✨ 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: 5
🧹 Nitpick comments (6)
src/app/globals.css (1)
112-114: 새 클래스Input-readOnly-217도입
데스크톱(217px)과 모바일(280px) 대응을 위해 별도 클래스를 추가하셨습니다. 다만 대부분 스타일이 중복되므로, 공통 속성을 베이스 클래스로 분리해 재사용성을 높이는 것을 고려해 보세요.src/app/features/dashboard_Id/hooks/useInfiniteScroll.ts (1)
11-16: 타입 안전성 개선이 필요합니다
fetchNextPage매개변수가() => void타입으로 정의되어 있지만, 실제로는 Promise를 반환할 수 있는 함수입니다. 타입을 더 정확하게 정의하는 것이 좋겠습니다.export const useInfiniteScroll = ( - fetchNextPage: () => void, + fetchNextPage: () => void | Promise<void>, hasNextPage: boolean, isFetchingNextPage: boolean, targetRef?: React.RefObject<HTMLElement>, ) => {src/app/features/dashboard_Id/api/useInfiniteComments.ts (2)
12-12: 주석이 부정확합니다주석에서 "마지막 카드의 id를 다음 cursor로 사용"이라고 되어 있지만, 실제로는 댓글의 cursor를 사용합니다.
- // 마지막 카드의 id를 다음 cursor로 사용 + // 마지막 댓글의 cursor를 다음 페이지 요청에 사용
6-17: 코드 중복을 줄이기 위한 제네릭 훅 고려
useInfiniteCards와useInfiniteComments가 거의 동일한 패턴을 가지고 있습니다. 제네릭 훅을 만들어 코드 중복을 줄이는 것을 고려해보세요.다음과 같은 제네릭 훅을 만들 수 있습니다:
function useInfiniteData<T>( queryKey: string[], fetchFn: (pageParam: number | null) => Promise<T>, getNextPageParam: (lastPage: T) => number | undefined ) { return useInfiniteQuery<T>({ queryKey, queryFn: ({ pageParam = null }) => fetchFn(pageParam), getNextPageParam, initialPageParam: null, }) }src/app/features/dashboard_Id/Card/cardModal/CardContent.tsx (1)
33-36: 스크롤 컨테이너 스타일링 검토 필요overflow-auto와 overflow-y-scroll이 함께 사용되어 중복적일 수 있습니다. overflow-y-scroll만으로도 충분할 것 같습니다.
- className="BG-white relative max-h-764 min-h-764 w-730 overflow-auto overflow-y-scroll rounded-16 px-18 py-30 shadow-lg [mask-image:radial-gradient(white_100%,transparent_100%)] mobile:w-327 mobile:p-16 tablet:w-678 tablet:px-32 tablet:py-24" + className="BG-white relative max-h-764 min-h-764 w-730 overflow-y-scroll rounded-16 px-18 py-30 shadow-lg [mask-image:radial-gradient(white_100%,transparent_100%)] mobile:w-327 mobile:p-16 tablet:w-678 tablet:px-32 tablet:py-24"src/app/features/dashboard_Id/Card/cardModal/Comments.tsx (1)
26-28: 에러 처리 개선 고려현재 에러 발생 시에도 컴포넌트가 계속 렌더링됩니다. 에러 상태에서 early return을 고려해보세요.
if (isError) { toast.error('댓글 불러오기 실패') + return <div className="text-center text-red-500">댓글을 불러올 수 없습니다.</div> }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (18)
src/app/features/dashboard_Id/Card/Card.tsx(0 hunks)src/app/features/dashboard_Id/Card/cardFormModals/CreateCardForm.tsx(1 hunks)src/app/features/dashboard_Id/Card/cardFormModals/CreateCardModal.tsx(1 hunks)src/app/features/dashboard_Id/Card/cardFormModals/ModifyCardForm.tsx(3 hunks)src/app/features/dashboard_Id/Card/cardModal/CardContent.tsx(3 hunks)src/app/features/dashboard_Id/Card/cardModal/CardModal.tsx(1 hunks)src/app/features/dashboard_Id/Card/cardModal/Comments.tsx(1 hunks)src/app/features/dashboard_Id/Column/Column.tsx(5 hunks)src/app/features/dashboard_Id/api/fetchCards.ts(1 hunks)src/app/features/dashboard_Id/api/fetchComments.ts(1 hunks)src/app/features/dashboard_Id/api/useCards.ts(0 hunks)src/app/features/dashboard_Id/api/useCommentsQuery.ts(0 hunks)src/app/features/dashboard_Id/api/useInfiniteCards.ts(1 hunks)src/app/features/dashboard_Id/api/useInfiniteComments.ts(1 hunks)src/app/features/dashboard_Id/api/usePutCardMutation.ts(0 hunks)src/app/features/dashboard_Id/api/useUploadCardImage.ts(1 hunks)src/app/features/dashboard_Id/hooks/useInfiniteScroll.ts(1 hunks)src/app/globals.css(1 hunks)
💤 Files with no reviewable changes (4)
- src/app/features/dashboard_Id/api/usePutCardMutation.ts
- src/app/features/dashboard_Id/Card/Card.tsx
- src/app/features/dashboard_Id/api/useCommentsQuery.ts
- src/app/features/dashboard_Id/api/useCards.ts
🧰 Additional context used
🧬 Code Graph Analysis (6)
src/app/features/dashboard_Id/api/useInfiniteCards.ts (2)
src/app/features/dashboard_Id/type/Card.type.ts (1)
CardResponse(21-25)src/app/features/dashboard_Id/api/fetchCards.ts (1)
fetchCards(6-26)
src/app/features/dashboard_Id/api/useInfiniteComments.ts (2)
src/app/features/dashboard_Id/type/Comment.type.ts (1)
CommentsResponse(14-17)src/app/features/dashboard_Id/api/fetchComments.ts (1)
fetchComments(6-26)
src/app/features/dashboard_Id/Card/cardModal/CardContent.tsx (1)
src/app/features/dashboard_Id/Card/cardModal/Comments.tsx (1)
Comments(8-46)
src/app/features/dashboard_Id/api/fetchCards.ts (1)
src/app/features/dashboard_Id/type/Card.type.ts (1)
CardResponse(21-25)
src/app/features/dashboard_Id/api/fetchComments.ts (1)
src/app/features/dashboard_Id/type/Comment.type.ts (1)
CommentsResponse(14-17)
src/app/features/dashboard_Id/Column/Column.tsx (4)
src/app/features/dashboard_Id/type/Column.type.ts (1)
Column(1-8)src/app/features/dashboard_Id/api/useInfiniteCards.ts (1)
useInfiniteCards(6-17)src/app/features/dashboard_Id/hooks/useInfiniteScroll.ts (1)
useInfiniteScroll(11-39)src/app/features/dashboard_Id/type/Card.type.ts (1)
Card(6-19)
🔇 Additional comments (33)
src/app/globals.css (2)
106-108:.Input에 모바일 너비 적용 확인
.Input클래스에mobile:w-280을 추가하여 모바일에서 폭이 280px로 조정됩니다. Tailwind 설정에 해당 유틸리티가 존재하는지 확인해 주세요.
109-111:.Input-readOnly에 모바일 너비 적용 확인
.Input-readOnly클래스에도 동일하게mobile:w-280을 추가했습니다. Tailwind 설정에 이 유틸리티가 포함되어 있는지 확인해 주세요.src/app/features/dashboard_Id/Card/cardFormModals/CreateCardModal.tsx (1)
17-17: 모바일 레이아웃/패딩 보강
모달 컨테이너에mobile:h-766 mobile:w-327 mobile:px-16 mobile:py-24를 추가해 모바일 대응을 강화했습니다. 반응형 디자인 기조에 부합하며, UI 테스트 시 의도대로 표시되는지 확인만 부탁드립니다.src/app/features/dashboard_Id/Card/cardFormModals/ModifyCardForm.tsx (2)
134-134: 모바일에서 컬럼·담당자 영역 세로 정렬
.flex gap-32컨테이너에mobile:flex-col을 추가해 모바일에서 세로 방향으로 전환하도록 했습니다. 레이아웃 의도에 맞으며 적절합니다.
153-153: 드롭다운 아이콘 좌측 오프셋 조정
mobile:left-11을 추가해 모바일에서 드롭다운 화살표 아이콘의 좌측 마진을 조정했습니다. 디자인 의도에 부합하며, 정상 동작하는 것으로 확인됩니다.src/app/features/dashboard_Id/Card/cardFormModals/CreateCardForm.tsx (1)
129-129: 모바일 화살표 위치 수정
드롭다운 아이콘에mobile:right-8을 추가해 모바일에서 오른쪽 여백을 확보했습니다. 반응형 UX 개선에 기여하며 적절해 보입니다.src/app/features/dashboard_Id/hooks/useInfiniteScroll.ts (2)
17-30: 스크롤 계산 로직이 잘 구현되었습니다스크롤 위치 계산과 80% 임계점 설정이 적절하며, 조건 체크(
hasNextPage && !isFetchingNextPage)도 올바르게 구현되어 있습니다. useCallback으로 최적화도 잘 되어 있습니다.
32-38: 이벤트 리스너 정리 시 타입 불일치 문제가 있습니다이벤트 리스너 추가 시에는
el을 사용하지만, 정리 시에는 다시 계산하지 않고 있습니다. 이로 인해targetRef가 변경되는 경우 문제가 발생할 수 있습니다.useEffect(() => { const el = targetRef?.current ?? window el.addEventListener('scroll', handleScroll, { passive: true }) return () => { - el.removeEventListener('scroll', handleScroll) + const currentEl = targetRef?.current ?? window + currentEl.removeEventListener('scroll', handleScroll) } }, [handleScroll, targetRef])Likely an incorrect or invalid review comment.
src/app/features/dashboard_Id/Card/cardModal/CardModal.tsx (1)
17-17: 이전 검색에서--type tsx옵션이 인식되지 않아 제대로 확인되지 않았습니다. CardModal.tsx 파일을 직접 찾아 클래스명, 인라인 스타일, CSS 모듈 import 여부를 점검하겠습니다.#!/bin/bash set -e # CardModal.tsx 경로 찾기 FILE=$(fd --extension tsx "CardModal.tsx" | head -n 1) echo "■ 대상 파일: $FILE" # 파일 상단(1~200라인) 출력 echo "----- 상위 200라인 -----" sed -n '1,200p' "$FILE" # className 사용 여부 echo "----- className 검색 -----" rg "className" -n "$FILE" || echo "=> className 없음" # 인라인 style 속성 여부 echo "----- style= 검색 -----" rg "style=" -n "$FILE" || echo "=> 인라인 style 없음" # CSS 모듈(import .module.css/.scss) import 여부 echo "----- CSS 모듈 import 검색 -----" rg "import.*\\.module\\." -n "$FILE" || echo "=> CSS 모듈 import 없음"src/app/features/dashboard_Id/api/useUploadCardImage.ts (1)
16-17: 에러 처리 개선이 잘 되었습니다서버에서 제공하는 에러 메시지를 추출하여 콘솔에 로깅하는 것은 디버깅에 도움이 됩니다. 구현도 안전하게 옵셔널 체이닝과 nullish coalescing을 사용했습니다.
src/app/features/dashboard_Id/api/useInfiniteCards.ts (1)
11-14: 페이지네이션 로직이 잘 구현되었습니다
getNextPageParam에서 카드 목록이 비어있으면undefined를 반환하여 더 이상 페이지가 없음을 표시하고, 있으면cursorId를 반환하는 로직이 올바릅니다.src/app/features/dashboard_Id/Card/cardModal/CardContent.tsx (3)
2-2: useRef import 추가 승인무한 스크롤을 위한 modalScrollRef 생성에 필요한 useRef를 적절히 import했습니다.
30-30: modalScrollRef 생성 승인HTMLDivElement 타입으로 올바르게 ref를 생성했습니다.
167-167: Comments 컴포넌트에 scrollRef 전달 승인modalScrollRef를 Comments 컴포넌트의 scrollRef prop으로 올바르게 전달했습니다. 무한 스크롤 구현에 필요한 변경사항입니다.
src/app/features/dashboard_Id/api/fetchCards.ts (3)
6-14: 함수 시그니처 변경 승인cursor 기반 무한 스크롤을 지원하기 위한 함수 시그니처 변경이 적절합니다. 객체 파라미터 구조와 타입 정의가 올바릅니다.
8-8: 기본 size 값 변경 승인size 기본값을 10에서 6으로 줄인 것은 무한 스크롤에서 더 빠른 로딩과 더 나은 UX를 위한 합리적인 결정입니다.
15-24: API 호출 방식 개선 승인params 객체를 사용한 API 호출 방식과 cursorId의 조건부 포함 로직이 깔끔하고 올바르게 구현되었습니다.
src/app/features/dashboard_Id/api/fetchComments.ts (3)
6-14: 함수 시그니처 변경 승인fetchCards와 일관된 패턴으로 cursor 기반 무한 스크롤을 지원하도록 변경되었습니다. 구조와 타입 정의가 올바릅니다.
8-8: 댓글 기본 size 값 적절댓글의 기본 size를 5로 설정한 것은 모달 내에서 보여줄 댓글 수로 적절합니다.
15-24: API 호출 방식 승인params 객체를 사용한 API 호출과 cursorId 조건부 포함 로직이 올바르게 구현되었습니다.
src/app/features/dashboard_Id/Card/cardModal/Comments.tsx (6)
3-4: 새로운 훅 import 승인무한 스크롤 구현을 위한 useInfiniteComments와 useInfiniteScroll 훅의 import가 적절합니다.
8-14: 컴포넌트 Props 변경 승인scrollRef prop 추가로 스크롤 컨테이너를 지정할 수 있게 된 것은 무한 스크롤 구현에 필수적인 변경사항입니다.
15-22: useInfiniteComments 훅 사용 승인무한 스크롤에 필요한 모든 상태값들을 적절히 구조분해할당으로 받아왔습니다.
24-24: useInfiniteScroll 훅 사용 승인무한 스크롤 트리거를 위한 훅 사용이 올바르게 구현되었습니다.
30-37: 댓글 렌더링 로직 승인pages 배열을 순회하며 각 페이지의 댓글들을 렌더링하는 로직이 올바르게 구현되었습니다.
39-43: 로딩 상태 표시 승인isFetchingNextPage 상태에 따른 로딩 메시지 표시가 적절합니다. 사용자 경험을 향상시킵니다.
src/app/features/dashboard_Id/Column/Column.tsx (7)
3-3: toast import 추가 승인에러 처리를 위한 toast import가 적절합니다.
8-8: 새로운 훅 import 승인무한 스크롤 구현을 위한 useInfiniteCards와 useInfiniteScroll 훅의 import가 적절합니다.
Also applies to: 12-12
18-25: useInfiniteCards 훅 사용 승인무한 스크롤에 필요한 모든 상태값들을 적절히 구조분해할당으로 받아왔습니다.
27-27: useInfiniteScroll 훅 사용 승인window 기반 무한 스크롤 트리거가 올바르게 구현되었습니다. 컬럼 컴포넌트에서는 window 스크롤을 사용하는 것이 적절합니다.
79-79: totalCount 접근 방식 승인첫 번째 페이지에서 totalCount를 가져오는 방식이 적절하며, null 체크도 올바르게 되어 있습니다.
104-108: 카드 렌더링 로직 승인pages 배열을 순회하며 각 페이지의 카드들을 렌더링하는 로직이 올바르게 구현되었습니다.
119-130: 무한 스크롤 상태 표시 승인isFetchingNextPage와 hasNextPage 상태에 따른 적절한 피드백 메시지가 구현되어 사용자 경험을 향상시킵니다.
| value={selectedColumn?.columnTitle ?? ''} | ||
| readOnly | ||
| className="Input-readOnly w-217" | ||
| className="Input-readOnly-217" |
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.
입력 필드 크기 불일치
Input-readOnly-217 인풋 너비(217px)가 래퍼의 w-207(207px)보다 커 오버플로우가 발생할 수 있습니다. 래퍼 또는 인풋 클래스 중 하나를 w-217 또는 w-207으로 일치시키는 패치가 필요합니다.
- <div className="relative w-207">
+ <div className="relative w-217">Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/app/features/dashboard_Id/Card/cardFormModals/ModifyCardForm.tsx at line
147, the input field has a class setting its width to 217px, but its wrapper has
a width of 207px, causing overflow issues. To fix this, adjust either the
input's class to match the wrapper's width by changing it to 207px or update the
wrapper's width class to 217px so both widths are consistent and prevent
overflow.
|
|
||
| export function useInfiniteCards(columnId: number) { | ||
| return useInfiniteQuery<CardResponse>({ | ||
| queryKey: ['columnId', columnId], |
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.
🛠️ Refactor suggestion
쿼리 키 네이밍이 부정확합니다
쿼리 키에 'columnId'라는 문자열이 사용되었지만, 실제로는 cards 데이터를 가져오는 쿼리입니다. 의미가 더 명확한 키 이름을 사용하는 것이 좋겠습니다.
- queryKey: ['columnId', columnId],
+ queryKey: ['cards', columnId],📝 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.
| queryKey: ['columnId', columnId], | |
| queryKey: ['cards', columnId], |
🤖 Prompt for AI Agents
In src/app/features/dashboard_Id/api/useInfiniteCards.ts at line 8, the query
key uses the string 'columnId' which is misleading since the query fetches cards
data. Rename the query key to a more descriptive name like 'cards' or
'cardsByColumn' to accurately reflect the data being queried.
| queryFn: ({ pageParam = null }) => | ||
| fetchCards({ columnId, cursorId: pageParam as number }), |
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.
타입 캐스팅 안전성을 개선해야 합니다
pageParam as number로 강제 타입 캐스팅을 하고 있지만, initialPageParam이 null이므로 첫 번째 호출 시 타입 불일치가 발생할 수 있습니다.
queryFn: ({ pageParam = null }) =>
- fetchCards({ columnId, cursorId: pageParam as number }),
+ fetchCards({ columnId, cursorId: pageParam as number | null }),📝 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.
| queryFn: ({ pageParam = null }) => | |
| fetchCards({ columnId, cursorId: pageParam as number }), | |
| queryFn: ({ pageParam = null }) => | |
| fetchCards({ columnId, cursorId: pageParam as number | null }), |
🤖 Prompt for AI Agents
In src/app/features/dashboard_Id/api/useInfiniteCards.ts around lines 9 to 10,
the code forcibly casts pageParam to number using 'pageParam as number', but
since initialPageParam can be null, this causes a type mismatch on the first
call. To fix this, add a runtime check to handle the case when pageParam is null
before casting, ensuring the fetchCards function receives a valid number or
handles null appropriately without unsafe casting.
| queryFn: ({ pageParam = null }) => | ||
| fetchComments({ cardId, cursorId: pageParam as number }), |
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.
타입 캐스팅 안전성을 개선해야 합니다
useInfiniteCards와 동일한 문제입니다. pageParam as number로 강제 타입 캐스팅을 하고 있지만, initialPageParam이 null이므로 첫 번째 호출 시 타입 불일치가 발생할 수 있습니다.
queryFn: ({ pageParam = null }) =>
- fetchComments({ cardId, cursorId: pageParam as number }),
+ fetchComments({ cardId, cursorId: pageParam as number | null }),📝 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.
| queryFn: ({ pageParam = null }) => | |
| fetchComments({ cardId, cursorId: pageParam as number }), | |
| queryFn: ({ pageParam = null }) => | |
| fetchComments({ cardId, cursorId: pageParam as number | null }), |
🤖 Prompt for AI Agents
In src/app/features/dashboard_Id/api/useInfiniteComments.ts around lines 9 to
10, the code forcibly casts pageParam to number despite initialPageParam being
null, causing a type mismatch on the first call. To fix this, add a runtime
check to handle the null case properly before casting, ensuring that
fetchComments receives a valid number or handles null safely without forced
casting.
| if (isLoading) return <p>loading...</p> // 스켈레톤 적용???⭐️ | ||
| if (isError) return toast.error('할 일 불러오기 실패') |
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.
🛠️ Refactor suggestion
로딩과 에러 처리 개선 필요
현재 로딩 상태에서 간단한 텍스트만 표시하고, 에러 상태에서도 컴포넌트가 계속 렌더링됩니다. 개선을 고려해보세요.
- if (isLoading) return <p>loading...</p> // 스켈레톤 적용???⭐️
- if (isError) return toast.error('할 일 불러오기 실패')
+ if (isLoading) {
+ return (
+ <div className="BG-gray Border-column flex w-354 shrink-0 flex-col gap-16 p-20 tablet:w-584">
+ <div className="mb-24 flex items-center justify-between">
+ <div className="flex items-center">
+ <div className="BG-blue mb-7 mr-8 size-8 rounded-25"></div>
+ <h2 className="mb-3 mr-12 h-21 text-18 font-bold">{title}</h2>
+ </div>
+ </div>
+ <p className="text-center text-gray-500">카드를 불러오는 중...</p>
+ </div>
+ )
+ }
+ if (isError) {
+ toast.error('할 일 불러오기 실패')
+ return (
+ <div className="BG-gray Border-column flex w-354 shrink-0 flex-col gap-16 p-20 tablet:w-584">
+ <div className="mb-24 flex items-center justify-between">
+ <div className="flex items-center">
+ <div className="BG-blue mb-7 mr-8 size-8 rounded-25"></div>
+ <h2 className="mb-3 mr-12 h-21 text-18 font-bold">{title}</h2>
+ </div>
+ </div>
+ <p className="text-center text-red-500">카드를 불러올 수 없습니다.</p>
+ </div>
+ )
+ }📝 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.
| if (isLoading) return <p>loading...</p> // 스켈레톤 적용???⭐️ | |
| if (isError) return toast.error('할 일 불러오기 실패') | |
| if (isLoading) { | |
| return ( | |
| <div className="BG-gray Border-column flex w-354 shrink-0 flex-col gap-16 p-20 tablet:w-584"> | |
| <div className="mb-24 flex items-center justify-between"> | |
| <div className="flex items-center"> | |
| <div className="BG-blue mb-7 mr-8 size-8 rounded-25"></div> | |
| <h2 className="mb-3 mr-12 h-21 text-18 font-bold">{title}</h2> | |
| </div> | |
| </div> | |
| <p className="text-center text-gray-500">카드를 불러오는 중...</p> | |
| </div> | |
| ) | |
| } | |
| if (isError) { | |
| toast.error('할 일 불러오기 실패') | |
| return ( | |
| <div className="BG-gray Border-column flex w-354 shrink-0 flex-col gap-16 p-20 tablet:w-584"> | |
| <div className="mb-24 flex items-center justify-between"> | |
| <div className="flex items-center"> | |
| <div className="BG-blue mb-7 mr-8 size-8 rounded-25"></div> | |
| <h2 className="mb-3 mr-12 h-21 text-18 font-bold">{title}</h2> | |
| </div> | |
| </div> | |
| <p className="text-center text-red-500">카드를 불러올 수 없습니다.</p> | |
| </div> | |
| ) | |
| } |
🤖 Prompt for AI Agents
In src/app/features/dashboard_Id/Column/Column.tsx around lines 37 to 38, the
current loading state only shows simple text and the error state triggers a
toast but still renders the component. Improve this by replacing the loading
text with a proper skeleton loader component and prevent rendering the main
component when there is an error by returning null or an error message component
instead of continuing to render.
📌 변경 사항 개요
✨ 요약
📝 상세 내용
🔗 관련 이슈
🖼️ 스크린샷
✅ 체크리스트
💡 참고 사항
Summary by CodeRabbit
신규 기능
스타일
버그 수정
리팩터
삭제