-
Notifications
You must be signed in to change notification settings - Fork 3
Feat/116/reviewable gathering list api #154
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
|
Important Review skippedReview was skipped due to path filters โ Files ignored due to path filters (1)
CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including You can disable this status message by setting the Walkthrough์ด ๋ณ๊ฒฝ ์ฌํญ์ ์ฌ๋ฌ ํ์ผ์์ ์ค์ , ์์กด์ฑ, ์ปดํฌ๋ํธ ๋ฐ ํ์
์ ์์ ๋ํ ์์ ๋ฐ ์ถ๊ฐ๋ฅผ ํฌํจํฉ๋๋ค. Changes
Suggested labels
Suggested reviewers
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? ๐ชง TipsChatThere are 3 ways to chat with CodeRabbit:
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 (
|
|
๐storybook: https://67206cc6ff9d7a05a3528ff8-qaztldpuya.chromatic.com/ |
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: 13
๐งน Outside diff range and nitpick comments (18)
src/types/reviewable-gathering-card.d.ts (2)
Line range hint
6-14: ํ๋ ์ค๋ช ์ฃผ์์ ๋ชจ๋ ์์ฑ์ ์ถ๊ฐํ๋ฉด ์ข๊ฒ ์ต๋๋ค.ํ์ฌ ์ผ๋ถ ํ๋์๋ง ํ๊ธ ์ฃผ์์ด ์์ต๋๋ค. ๋ชจ๋ ํ๋์ ๋ํ ์ค๋ช ์ ์ถ๊ฐํ๋ฉด ํ์ ์ ์ฌ์ฉ์ฑ์ด ํฅ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ๋ชจ๋ ํ๋์ ์ฃผ์์ ์ถ๊ฐํ๋ ๊ฒ์ ์ ์ํฉ๋๋ค:
export type ReviewableGatheringCardInform = { id: number; // ์ฝ์ ID title: string; // ์ฝ์ ์ด๋ฆ - dateTime: string; + dateTime: string; // ์ฝ์ ๋ ์ง ๋ฐ ์๊ฐ - location: string; + location: string; // ์ฝ์ ์ฅ์ - currentCount: number; + currentCount: number; // ํ์ฌ ์ฐธ๊ฐ์ ์ - totalCount: number; + totalCount: number; // ์ ์ฒด ์ฐธ๊ฐ์ ์ - imageUrl: string; + imageUrl: string; // ๋ชจ์ ๋ํ ์ด๋ฏธ์ง URL - participants: ParticipantType[]; + participants: ParticipantType[]; // ์ฐธ๊ฐ์ ๋ชฉ๋ก };
Line range hint
16-20: ์ฐธ๊ฐ์ ํ์ ์ ๋ํ ์ค๋ช ์ฃผ์์ด ํ์ํฉ๋๋ค.
ParticipantType์ ๊ฐ ํ๋์ ๋ํ ์ค๋ช ์ ์ถ๊ฐํ๋ฉด ์ข๊ฒ ์ต๋๋ค.๋ค์๊ณผ ๊ฐ์ด ์ฃผ์์ ์ถ๊ฐํ๋ ๊ฒ์ ์ ์ํฉ๋๋ค:
export type ParticipantType = { - id: number; + id: number; // ์ฐธ๊ฐ์ ๊ณ ์ ID - profileImageUrl?: string; + profileImageUrl?: string; // ์ฐธ๊ฐ์ ํ๋กํ ์ด๋ฏธ์ง URL (์ ํ์ฌํญ) - nickname: string; + nickname: string; // ์ฐธ๊ฐ์ ๋๋ค์ };src/_apis/gathering/reviewable-gathering.ts (1)
10-12: ์๋ฌ ์ฒ๋ฆฌ ๊ฐ์ ํ์ํ์ฌ ์๋ฌ ๋ฉ์์ง๊ฐ ๋๋ฌด ์ผ๋ฐ์ ์ ๋๋ค. API ์๋ต์ ๊ตฌ์ฒด์ ์ธ ์๋ฌ ์ ๋ณด๋ฅผ ํฌํจํ๋ฉด ๋๋ฒ๊น ์ ๋์์ด ๋ ๊ฒ ๊ฐ์ต๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์์ ํ๋ ๊ฒ์ ์ ์๋๋ฆฝ๋๋ค:
if (!response.data) { - throw new Error('Failed to get reviewable gatherings'); + throw new Error(`Failed to get reviewable gatherings: ${JSON.stringify(response)}`); }src/hooks/use-infinite-scroll.ts (4)
Line range hint
6-13: ์ ๋ค๋ฆญ ํ์ ๊ณผ ๋งค๊ฐ๋ณ์ ์ ์๊ฐ ๋ช ํํฉ๋๋ค.ํ์ ์์ ์ฑ์ด ์ ๋ณด์ฅ๋์ด ์์ผ๋ฉฐ, ํ์ํ ๋งค๊ฐ๋ณ์๋ค์ด ์ ์ ํ๊ฒ ์ ์๋์ด ์์ต๋๋ค. ๋ค๋ง, ํ์ ๋ฌธ์ํ๋ฅผ ์ํ JSDoc ์ฃผ์ ์ถ๊ฐ๋ฅผ ๊ณ ๋ คํด๋ณด์๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
๋ค์๊ณผ ๊ฐ์ด JSDoc ์ฃผ์์ ์ถ๊ฐํ๋ ๊ฒ์ ์ ์๋๋ฆฝ๋๋ค:
+/** + * ๋ฌดํ ์คํฌ๋กค ๊ธฐ๋ฅ์ ๊ตฌํํ๋ ์ปค์คํ ํ + * @template TData - ํ์ด์ง ๋ฐ์ดํฐ์ ํ์ + * @param {Object} params - ํ ํ๋ผ๋ฏธํฐ + * @param {string[]} params.queryKey - React Query ์บ์ ํค + * @param {Function} params.queryFn - ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ํจ์ + * @param {Function} params.getNextPageParam - ๋ค์ ํ์ด์ง ํ๋ผ๋ฏธํฐ๋ฅผ ๊ฒฐ์ ํ๋ ํจ์ + */ export const useInfiniteScroll = <TData>({
Line range hint
21-24: Intersection Observer ์ค์ ์ threshold ๊ฐ ๊ฒํ ๊ฐ ํ์ํฉ๋๋ค.threshold๊ฐ 1๋ก ์ค์ ๋์ด ์์ด ์์๊ฐ 100% ๋ณด์ฌ์ผ๋ง ๊ฐ์ง๋ฉ๋๋ค. ์ด๋ ์ฌ์ฉ์ ๊ฒฝํ ์ธก๋ฉด์์ ๋๋ฌด ๋ฆ์ ์์ ์ผ ์ ์์ต๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์์ ํ๋ ๊ฒ์ ์ ์๋๋ฆฝ๋๋ค:
const { ref, inView } = useInView({ - threshold: 1, + threshold: 0.5, // ์์๊ฐ 50% ๋ณด์ผ ๋ ๊ฐ์ง + rootMargin: '100px', // ๋ทฐํฌํธ ํ๋จ 100px ์ ์ ๋ฏธ๋ฆฌ ๊ฐ์ง });
Line range hint
25-27: ๋ฌดํ ์คํฌ๋กค ๋ก์ง์ด ๊ฐ๊ฒฐํ๊ฒ ๊ตฌํ๋์์ต๋๋ค.์กฐ๊ฑด๋ฌธ์ด ๋ช ํํ๊ณ ์ดํดํ๊ธฐ ์ฝ๊ฒ ์์ฑ๋์์ต๋๋ค. ๋ค๋ง, ์๋ฌ ์ฒ๋ฆฌ๋ ์ฌ์๋ ๋ก์ง์ด ์๋ ์ ์ด ์ฐ๋ ค๋ฉ๋๋ค.
๋ค์๊ณผ ๊ฐ์ ์๋ฌ ์ฒ๋ฆฌ ๋ก์ง ์ถ๊ฐ๋ฅผ ์ ์๋๋ฆฝ๋๋ค:
-if (inView && hasNextPage && !isFetchingNextPage) { - fetchNextPage(); +if (inView && hasNextPage && !isFetchingNextPage) { + fetchNextPage().catch((error) => { + console.error('Failed to fetch next page:', error); + // ํ์ํ ๊ฒฝ์ฐ ์๋ฌ ์ฒ๋ฆฌ ๋ก์ง ์ถ๊ฐ + }); }
Line range hint
29-29: ๋ฐํ๊ฐ์ ํ์ ๋ช ์๊ฐ ํ์ํฉ๋๋ค.๋ฐํ ๊ฐ์ฒด์ ํ์ ์ ๋ช ์์ ์ผ๋ก ์ ์ํ๋ฉด ํ์ ์์ ์ฑ์ด ํฅ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์์ ํ๋ ๊ฒ์ ์ ์๋๋ฆฝ๋๋ค:
-return { data, error, isLoading, ref, isFetchingNextPage, refetch }; +type InfiniteScrollResult<T> = { + data: InfiniteData<T> | undefined; + error: Error | null; + isLoading: boolean; + ref: (node?: Element | null) => void; + isFetchingNextPage: boolean; + refetch: () => Promise<void>; +}; + +return { + data, + error, + isLoading, + ref, + isFetchingNextPage, + refetch, +} as InfiniteScrollResult<TData>;src/_queries/my-gathering/reviewable-gathering-list.tsx (1)
13-17: ์๋ฌ ์ฒ๋ฆฌ๋ฅผ ๋ ๊ตฌ์ฒด์ ์ผ๋ก ๊ฐ์ ํด ์ฃผ์ธ์ํ์ฌ ์๋ฌ ์ฒ๋ฆฌ๊ฐ ๋๋ฌด ์ผ๋ฐ์ ์ ๋๋ค. API ์๋ต์ ๊ตฌ์ฒด์ ์ธ ์๋ฌ ์ผ์ด์ค๋ฅผ ์ฒ๋ฆฌํ๋ ๊ฒ์ด ์ข๊ฒ ์ต๋๋ค.
- if (response === undefined || response === null) { - throw new Error('์ฝ์ ๋ชฉ๋ก์ ๋ถ๋ฌ์ค๋ ๋ฐ ์คํจํ์ต๋๋ค.'); - } - return response; + if (!response?.data) { + throw new Error('์ฝ์ ๋ชฉ๋ก ๋ฐ์ดํฐ๊ฐ ์กด์ฌํ์ง ์์ต๋๋ค.'); + } + if (response.error) { + throw new Error(`์ฝ์ ๋ชฉ๋ก ์กฐํ ์คํจ: ${response.error.message}`); + } + return response.data;src/app/(crew)/my-page/_components/profile-card/presenter.tsx (1)
28-28: priority prop์ ๋ชฉ์ ์ ๋ฌธ์ํํด์ฃผ์ธ์.์ด๋ฏธ์ง ๋ก๋ฉ ์ฐ์ ์์์ ๊ด๋ จ๋ prop์ด ์ถ๊ฐ๋์์ต๋๋ค. ๋ค๋ฅธ ๊ฐ๋ฐ์๋ค์ ์ดํด๋ฅผ ๋๊ธฐ ์ํด ์ฃผ์์ผ๋ก ์ค๋ช ์ ์ถ๊ฐํ๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
- <Profile editable imageUrl={data?.profileImageUrl ?? ''} priority /> + {/* ํ๋กํ ์ด๋ฏธ์ง์ ๋น ๋ฅธ ๋ก๋ฉ์ ์ํด priority prop ์ฌ์ฉ */} + <Profile editable imageUrl={data?.profileImageUrl ?? ''} priority />src/components/my-page/reviewable-gatherings/reviewable-gathering-card-list.tsx (2)
9-13: ํ์ด์ง๋ค์ด์ ์ค์ ์ ์ ์ฐ์ฑ ๊ฐ์ ํ์ํ์ด์ง ํฌ๊ธฐ๊ฐ ํ๋์ฝ๋ฉ๋์ด ์์ด ํ๋ฉด ํฌ๊ธฐ์ ๋ฐ๋ฅธ ์ต์ ํ๊ฐ ์ด๋ ค์ธ ์ ์์ต๋๋ค. ํ๊ฒฝ ์ค์ ์ด๋ props๋ก ๊ด๋ฆฌํ๋ ๊ฒ์ ๊ณ ๋ คํด๋ณด์ธ์.
+interface ReviewableGatheringCardListProps { + pageSize?: number; +} + -export default function ReviewableGatheringCardList() { +export default function ReviewableGatheringCardList({ pageSize = 6 }: ReviewableGatheringCardListProps) { const { data, ref, isFetchingNextPage } = useInfiniteScroll( useGetReviewableQuery({ - pageable: { page: 0, size: 6, sort: ['dateTime,desc'] }, + pageable: { page: 0, size: pageSize, sort: ['dateTime,desc'] }, }), );
15-18: ๋น ์ํ ํ์ธ ๋ก์ง ๋จ์ํ ํ์ํ์ฌ ๋น ์ํ ํ์ธ ๋ก์ง์ด ๋ค์ ๋ณต์กํฉ๋๋ค. ๊ฐ๋ ์ฑ์ ๋์ด๊ธฐ ์ํด ๋ณ๋์ ์ ํธ๋ฆฌํฐ ํจ์๋ก ๋ถ๋ฆฌํ๋ ๊ฒ์ ์ถ์ฒ๋๋ฆฝ๋๋ค.
+const isPageEmpty = (page: any) => + Array.isArray(page.content) && page.content.length === 0; + const isDataEmpty = !data || data.pages.length === 0 || - data.pages.every((page) => Array.isArray(page.content) && page.content.length === 0); + data.pages.every(isPageEmpty);src/app/(crew)/my-page/_components/review-tabs.tsx (1)
27-27: ๋ผ์ฐํฐ ์๋ฌ ์ฒ๋ฆฌ ์ถ๊ฐ ๊ถ์ฅ
router.push()ํธ์ถ ์ ๋ฐ์ํ ์ ์๋ ์๋ฌ์ ๋ํ ์ฒ๋ฆฌ๊ฐ ์์ต๋๋ค. ๋ค๋น๊ฒ์ด์ ์คํจ ์ ์ฌ์ฉ์์๊ฒ ์ ์ ํ ํผ๋๋ฐฑ์ ์ ๊ณตํ๊ธฐ ์ํด try-catch ๋ธ๋ก ์ถ๊ฐ๋ฅผ ๊ณ ๋ คํด ์ฃผ์ธ์.- router.push(selectedTab.route); + try { + await router.push(selectedTab.route); + } catch (error) { + console.error('ํ์ด์ง ์ด๋ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค:', error); + // ์๋ฌ ์ฒ๋ฆฌ ๋ก์ง ์ถ๊ฐ + }src/components/my-page/reviewable-gatherings/reviewable-gathering-card.tsx (4)
1-10: ์ํฌํธ ๊ตฌ๋ฌธ ๊ทธ๋ฃนํ ์ ์์ํฌํธ ๊ตฌ๋ฌธ์ ๋ค์๊ณผ ๊ฐ์ด ๋ ผ๋ฆฌ์ ์ผ๋ก ๊ทธ๋ฃนํํ๋ฉด ์ฝ๋์ ๊ฐ๋ ์ฑ์ด ํฅ์๋ ๊ฒ ๊ฐ์ต๋๋ค:
- React ๊ด๋ จ
- Next.js ๊ด๋ จ
- ์ปดํฌ๋ํธ
- ํ์
- ์์
'use client'; import { useState } from 'react'; import Image from 'next/image'; + import Profiles from '@/src/components/common/crew-list/profiles'; import Button from '@/src/components/common/input/button'; import ReviewingModal from '../reviewing-modal/reviewing-modal'; + import { ParticipantType } from '@/src/types/reviewable-gathering-card'; + import person from '@/public/assets/icons/person.svg';
Line range hint
11-18: ์ธํฐํ์ด์ค ๋ฌธ์ํ ์ถ๊ฐ ์ ์์ธํฐํ์ด์ค์ JSDoc ๋ฌธ์๋ฅผ ์ถ๊ฐํ์ฌ ๊ฐ ํ๋กํผํฐ์ ๋ชฉ์ ๊ณผ ์ฌ์ฉ๋ฒ์ ๋ช ํํ ์ค๋ช ํ๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
+/** + * ๋ฆฌ๋ทฐ ๊ฐ๋ฅํ ๋ชจ์ ์นด๋์ ํ๋กํผํฐ๋ฅผ ์ ์ํ๋ ์ธํฐํ์ด์ค + */ interface ReviewableGatheringCardProps { + /** ๋ชจ์์ ๊ณ ์ ์๋ณ์ */ id: number; + /** ๋ชจ์์ ์ด๋ฆ */ gatheringName: string; + /** ๋ชจ์ ๋ ์ง์ ์๊ฐ (ISO ๋ฌธ์์ด) */ dateTime: string; + /** ํ์ฌ ์ฐธ์ฌ์ ์ */ currentCount: number; + /** ์ด ์ฐธ์ฌ ๊ฐ๋ฅ ์ธ์ */ totalCount: number; + /** ๋ชจ์ ๋ํ ์ด๋ฏธ์ง URL */ imageUrl: string; + /** ์ฐธ์ฌ์ ๋ชฉ๋ก */ participants: ParticipantType[]; }
Line range hint
20-30: ๋ ์ง ํฌ๋งทํ ์ ํธ๋ฆฌํฐ ํจ์ ๊ฐ์ ํ์
- NOTE ์ฃผ์์ ์ธ๊ธ๋ ๋๋ก ์ด ํจ์๋ ์ถํ ํตํฉ์ด ํ์ํด ๋ณด์ ๋๋ค.
- ์๊ฐ ์ ๋ณด๋ ์ฒ๋ฆฌํ ์ ์๋๋ก ๊ธฐ๋ฅ์ ํ์ฅํ๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
์ด ํจ์๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๊ฐ์ ํ๋ ๊ฒ์ ์ ์๋๋ฆฝ๋๋ค:
src/utils/date.ts์ ๊ฐ์ ๊ณตํต ์ ํธ๋ฆฌํฐ ํ์ผ๋ก ์ด๋- ์๊ฐ ํฌ๋งทํ ๊ธฐ๋ฅ ์ถ๊ฐ
- ๊ตญ์ ํ(i18n) ์ง์ ๊ณ ๋ ค
๊ณตํต ์ ํธ๋ฆฌํฐ๋ก์ ๋ฆฌํฉํ ๋ง์ ๋์๋๋ฆด๊น์?
Let me generate the final response based on the gathered information.
fill์์ฑ์ด ์๋ Image ์ปดํฌ๋ํธ์object-fit๊ด๋ จ ์์ฑ ์ถ๊ฐ ํ์์ฝ๋๋ฒ ์ด์ค ๋ถ์ ๊ฒฐ๊ณผ, ๋ค๋ฅธ ์ปดํฌ๋ํธ๋ค์
Image์ฌ์ฉ ํจํด์ ๋ณด๋ฉดfill์์ฑ๊ณผ ํจ๊ปobject-fit๊ด๋ จ ์์ฑ์ ํจ๊ป ์ฌ์ฉํ๊ณ ์์ต๋๋ค:
detail-crew-presenter.tsx:objectFit="cover"์์ฑ ์ฌ์ฉfile-input/index.tsx:className="object-cover"์ฌ์ฉscheduled-gathering-card/presenter.tsx:className="object-cover"์ฌ์ฉcrew-card.tsx๋ฐdetail-crew-card.tsx:style={{ objectFit: 'cover' }}์ฌ์ฉ๋ฐ๋ผ์ ์ด๋ฏธ์ง ๋น์จ ์ ์ง๋ฅผ ์ํด ๋ค์๊ณผ ๊ฐ์ด ์์ ์ด ํ์ํฉ๋๋ค:
- <Image src={imageUrl} alt={gatheringName} fill /> + <Image src={imageUrl} alt={gatheringName} fill className="object-cover" /> - <Image alt="์ฐธ์ฌ ์ธ์" src={person} fill /> + <Image alt="์ฐธ์ฌ ์ธ์" src={person} fill className="object-cover" />๐ Analysis chain
Line range hint
32-88: ์ปดํฌ๋ํธ ๊ตฌํ ๊ฐ์ ์ฌํญ
๋ชจ๋ฌ ์ํ ๊ด๋ฆฌ:
- ๋ชจ๋ฌ ์ํ๋ฅผ ์์ ์ปดํฌ๋ํธ๋ก ๋์ด์ฌ๋ฆฌ๋ ๊ฒ์ด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
- ์ด๋ ๊ฒ ํ๋ฉด ๋ชจ๋ฌ ์ํ๋ฅผ ๋ค๋ฅธ ์ปดํฌ๋ํธ์ ๊ณต์ ํ๊ธฐ ์ฌ์์ง๋๋ค.
์ด๋ฏธ์ง ์ฒ๋ฆฌ:
objectFitํ๋กํผํฐ๊ฐ ์ ๊ฑฐ๋์๋๋ฐ, ์ด๋ฏธ์ง ๋น์จ ์ ์ง๋ฅผ ์ํด ํ์ํ ์ ์์ต๋๋ค.์คํ์ผ๋ง:
- ์ธ๋ผ์ธ ์คํ์ผ์ Tailwind ํด๋์ค๋ก ์ถ์ถํ๋ฉด ์ฌ์ฌ์ฉ์ฑ์ด ํฅ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
-<Image src={imageUrl} alt={gatheringName} fill /> +<Image + src={imageUrl} + alt={gatheringName} + fill + className="object-cover" +/>์ด๋ฏธ์ง ๋น์จ ๊ด๋ จ ์ด์๋ฅผ ํ์ธํ๊ธฐ ์ํด ๋ค์ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํด๋ณด๊ฒ ์ต๋๋ค:
๐ Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # ์ด๋ฏธ์ง ์ปดํฌ๋ํธ์ objectFit ์ฌ์ฉ ํจํด ํ์ธ rg -A 2 "<Image.*fill.*>"Length of output: 2368
src/components/common/crew-list/detail-crew-card.tsx (2)
13-26: ์ธํฐํ์ด์ค์ JSDoc ๋ฌธ์ํ ์ถ๊ฐ ํ์์ธํฐํ์ด์ค์ ๊ฐ ํ๋์ ๋ํ ์ค๋ช ์ด ์์ด ๋ค๋ฅธ ๊ฐ๋ฐ์๋ค์ด ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ ๋ ์ด๋ ค์์ด ์์ ์ ์์ต๋๋ค.
๋ค์๊ณผ ๊ฐ์ด JSDoc์ ์ถ๊ฐํ๋ ๊ฒ์ ์ถ์ฒ๋๋ฆฝ๋๋ค:
+/** + * DetailCrewCard ์ปดํฌ๋ํธ์ props ์ธํฐํ์ด์ค + */ interface DetailCrewCardProps { data: { + /** ํฌ๋ฃจ์ ๊ณ ์ ์๋ณ์ */ id: number; + /** ํฌ๋ฃจ์ ์ ๋ชฉ */ title: string; // ... ๋๋จธ์ง ํ๋์ ๋ํ ์ค๋ช ์ถ๊ฐ }; }
28-44: ๋ชจ๋ฌ ๊ด๋ จ ๋ก์ง์ ์ปค์คํ ํ ์ผ๋ก ๋ถ๋ฆฌ ๊ถ์ฅ๋ชจ๋ฌ ์ํ ๊ด๋ฆฌ ๋ก์ง์ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ปค์คํ ํ ์ผ๋ก ๋ถ๋ฆฌํ๋ฉด ์ฝ๋์ ๊ฐ๋ ์ฑ๊ณผ ์ฌ์ฌ์ฉ์ฑ์ด ํฅ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
๋ค์๊ณผ ๊ฐ์ ์ปค์คํ ํ ์์ฑ์ ์ ์๋๋ฆฝ๋๋ค:
function useConfirmationModal() { const [opened, { open, close }] = useDisclosure(); return { opened, openModal: open, closeModal: close }; }
๐ Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
โ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
๐ Files selected for processing (20)
.vscode/settings.json(1 hunks)package.json(1 hunks)src/_apis/gathering/reviewable-gathering.ts(1 hunks)src/_queries/my-gathering/reviewable-gathering-list.tsx(1 hunks)src/app/(crew)/api/mock-api/writable-gathering.ts(0 hunks)src/app/(crew)/my-page/_components/profile-card/presenter.tsx(1 hunks)src/app/(crew)/my-page/_components/review-tabs.tsx(2 hunks)src/app/(crew)/my-page/reviewable/page.tsx(1 hunks)src/components/common/crew-list/crew-card.tsx(1 hunks)src/components/common/crew-list/detail-crew-card.tsx(1 hunks)src/components/common/gathering-card/presenter.tsx(1 hunks)src/components/common/profile/index.tsx(3 hunks)src/components/common/writable-gathering-card/writable-gathering-card-list.stories.tsx(0 hunks)src/components/common/writable-gathering-card/writable-gathering-card-list.tsx(0 hunks)src/components/my-page/reviewable-gatherings/reviewable-gathering-card-list.tsx(1 hunks)src/components/my-page/reviewable-gatherings/reviewable-gathering-card.tsx(4 hunks)src/components/my-page/reviewing-modal/reviewing-modal.tsx(1 hunks)src/hooks/use-infinite-scroll.ts(1 hunks)src/mock/writable-gathering-data.ts(0 hunks)src/types/reviewable-gathering-card.d.ts(1 hunks)
๐ค Files with no reviewable changes (4)
- src/app/(crew)/api/mock-api/writable-gathering.ts
- src/components/common/writable-gathering-card/writable-gathering-card-list.stories.tsx
- src/components/common/writable-gathering-card/writable-gathering-card-list.tsx
- src/mock/writable-gathering-data.ts
โ Files skipped from review due to trivial changes (2)
- src/components/common/crew-list/crew-card.tsx
- src/components/common/gathering-card/presenter.tsx
๐งฐ Additional context used
๐ช Biome
src/components/common/profile/index.tsx
[error] 73-73: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
๐ Additional comments (15)
src/app/(crew)/my-page/reviewable/page.tsx (1)
1-3: import ๊ฒฝ๋ก ๋ณ์นญ(@/src)์ด ์ฌ๋ฐ๋ฅด๊ฒ ๊ตฌ์ฑ๋์ด ์๋์ง ํ์ธ์ด ํ์ํฉ๋๋ค.
import ๋ฌธ์์ ์ฌ์ฉ๋ '@/src' ๊ฒฝ๋ก ๋ณ์นญ์ด ํ๋ก์ ํธ์ tsconfig.json ๋๋ ๋ค๋ฅธ ๊ตฌ์ฑ ํ์ผ์์ ์ฌ๋ฐ๋ฅด๊ฒ ์ค์ ๋์ด ์๋์ง ํ์ธํด์ฃผ์ธ์.
โ Verification successful
import ๊ฒฝ๋ก ๋ณ์นญ(@/src)์ด ์ ์์ ์ผ๋ก ์ค์ ๋์ด ์๊ณ ์ปดํฌ๋ํธ ํ์ผ๋ ์ฌ๋ฐ๋ฅธ ์์น์ ์กด์ฌํฉ๋๋ค.
๐ Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify path alias configuration
# Check tsconfig.json for path aliases
echo "Checking tsconfig.json for path aliases..."
cat tsconfig.json | jq '.compilerOptions.paths'
# Check if the imported component exists
echo "Checking if the imported component exists..."
fd -t f "reviewable-gathering-card-list.tsx" src/components/my-page/reviewable-gatherings
Length of output: 953
src/types/reviewable-gathering-card.d.ts (1)
1-3: ์๋ต ํ์
์ ์๊ฐ ๋ช
ํํ๊ณ ์ ์ ํฉ๋๋ค!
ํ์ด์ง๋ค์ด์
์ ์ํ hasNext์ ๋ฐ์ดํฐ๋ฅผ ์ํ content ๋ฐฐ์ด์ด ์ ์ ์๋์ด ์์ต๋๋ค.
src/hooks/use-infinite-scroll.ts (2)
1-5: ํ์ํ ์์กด์ฑ์ด ๋ชจ๋ import ๋์์ต๋๋ค.
ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋ ๋๋ง์ ์ํ 'use client' ์ง์๋ฌธ๊ณผ ํ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ด ์ฌ๋ฐ๋ฅด๊ฒ import ๋์์ต๋๋ค.
Line range hint 14-20: React Query ์ค์ ์ด ์ ์ ํ๊ฒ ๊ตฌ์ฑ๋์์ต๋๋ค.
์ด๊ธฐ ํ์ด์ง ํ๋ผ๋ฏธํฐ๊ฐ 0์ผ๋ก ์ค์ ๋์ด ์๋๋ฐ, ์ด๋ ๋ฐฑ์๋ API์ ํ์ด์ง๋ค์ด์ ๊ตฌํ๊ณผ ์ผ์นํ๋์ง ํ์ธ์ด ํ์ํฉ๋๋ค.
๋ค์ ์คํฌ๋ฆฝํธ๋ก API ๊ตฌํ์ ํ์ธํด๋ณด์๊ธฐ ๋ฐ๋๋๋ค:
โ Verification successful
ํ์ด์ง๋ค์ด์ ๊ตฌํ์ด ๋ฐฑ์๋ API์ ์ผ์นํจ์ด ํ์ธ๋์์ต๋๋ค
์ฝ๋๋ฒ ์ด์ค ๋ถ์ ๊ฒฐ๊ณผ, ๋ค์๊ณผ ๊ฐ์ ์ด์ ๋ก initialPageParam: 0 ์ค์ ์ด ์ ์ ํฉ๋๋ค:
- ๋ชจ๋ API ํธ์ถ์์
pageParam = 0์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ฌ์ฉํ๊ณ ์์ต๋๋ค. - ๋ฐฑ์๋ API ํธ์ถ ์
page: pageParam์ผ๋ก ์ ๋ฌ๋์ด ์ผ๊ด์ฑ์ด ์ ์ง๋ฉ๋๋ค. getNextPageParam๊ตฌํ์์๋ 0๋ถํฐ ์์ํ๋ ํ์ด์ง ๋ฒํธ ์ฒด๊ณ๋ฅผ ์ ์ ๋ก ๋์ํฉ๋๋ค.
๐ Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# API ๊ตฌํ์์ ํ์ด์ง๋ค์ด์
์์ ๊ฐ ํ์ธ
rg -A 5 "page.*param" --type ts
Length of output: 33
Script:
#!/bin/bash
# ํ์ด์ง๋ค์ด์
๊ด๋ จ ์ฝ๋ ๊ฒ์์ ์ํ ๋ค์ํ ํจํด ํ์ธ
rg -A 5 "getNextPageParam|pageParam|initialPage" --type ts
# API ํธ์ถ ๋ถ๋ถ์์ ํ์ด์ง ํ๋ผ๋ฏธํฐ ์ฌ์ฉ ํ์ธ
ast-grep --pattern 'queryFn = async ({ pageParam }) => { $$$ }'
# ํ์ด์ง๋ค์ด์
๊ด๋ จ ํ์
์ด๋ ์ธํฐํ์ด์ค ๊ฒ์
rg -A 3 "interface.*Page|type.*Page" --type ts
Length of output: 9490
src/_queries/my-gathering/reviewable-gathering-list.tsx (1)
1-6: ์ฝ๋๊ฐ ๊น๋ํ๊ณ ์ ๊ตฌ์ฑ๋์ด ์์ต๋๋ค!
ํ์ ์ ์์ import ๊ตฌ๋ฌธ์ด ๋ช ํํ๊ฒ ์์ฑ๋์ด ์์ต๋๋ค.
src/app/(crew)/my-page/_components/profile-card/presenter.tsx (1)
28-28: Profile ์ปดํฌ๋ํธ์ priority prop ํ์
๊ฒ์ฆ์ด ํ์ํฉ๋๋ค.
Profile ์ปดํฌ๋ํธ์ priority prop์ด ์ถ๊ฐ๋์์ต๋๋ค. ํ์ ์์ ์ฑ์ ์ํด ํ์ ์ ์๋ฅผ ํ์ธํด์ฃผ์ธ์.
โ Verification successful
Profile ์ปดํฌ๋ํธ์ priority prop์ด ์ฌ๋ฐ๋ฅด๊ฒ ์ ์๋์ด ์์ต๋๋ค.
ProfileProps ์ธํฐํ์ด์ค์ priority prop์ด boolean ํ์ ์ผ๋ก ์ ์๋์ด ์์ด ํ์ ์์ ์ฑ์ด ํ๋ณด๋์์ต๋๋ค.
๐ Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Profile ์ปดํฌ๋ํธ์ ํ์
์ ์ ํ์ธ
# Profile ์ปดํฌ๋ํธ์ ํ์
์ ์ ๊ฒ์
ast-grep --pattern 'interface ProfileProps {
$$$
}'
# priority prop์ด ์ฌ์ฉ๋ ๋ค๋ฅธ ๊ณณ ๊ฒ์
rg "priority.*Profile"
Length of output: 611
Script:
#!/bin/bash
# Profile ์ปดํฌ๋ํธ์ ๊ตฌํ๋ถ ํ์ธ
ast-grep --pattern 'const Profile = ({ $$ }: ProfileProps) => {
$$$
}'
# Profile ์ปดํฌ๋ํธ ์ฌ์ฉ ํจํด ๊ฒ์
rg -A 2 "<Profile.*priority"
Length of output: 424
src/components/my-page/reviewable-gatherings/reviewable-gathering-card-list.tsx (1)
3-6: ํ์
๊ณผ API ์๋ต ์ผ์น ์ฌ๋ถ ํ์ธ ํ์
ReviewableGatheringCardInformResponse ํ์
์ด API ์๋ต ๊ตฌ์กฐ์ ์ผ์นํ๋์ง ํ์ธ์ด ํ์ํฉ๋๋ค.
โ Verification successful
Let me gather more information about the type definition.
Let me try one more search to find the type definition:
ํ์ ์ ์๊ฐ API ์๋ต๊ณผ ์ฌ๋ฐ๋ฅด๊ฒ ์ผ์นํจ์ ํ์ธํ์ต๋๋ค
API ์๋ต ํ์
ReviewableGatheringCardInformResponse๊ฐ ๋ค์๊ณผ ๊ฐ์ด ์ ์ ํ๊ฒ ์ ์๋์ด ์์ต๋๋ค:
- ํ์ด์ง๋ค์ด์
์ ์ํ
content๋ฐฐ์ด๊ณผhasNextํ๋๋ฅผ ํฌํจ content๋ฐฐ์ด์ ๊ฐ ํญ๋ชฉ์ReviewableGatheringCardInformํ์ ์ผ๋ก ๋ชจ๋ ํ์ ํ๋ ํฌํจ- API ํธ์ถ ํจ์
getReviewableGatherings์์ ๋์ผํ ํ์ ์ ์ฌ์ฉํ์ฌ ์๋ต ์ฒ๋ฆฌ
๐ Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# API ์๋ต ํ์
๊ณผ ์ค์ ํ์
์ ์ ๋น๊ต
ast-grep --pattern 'interface ReviewableGatheringCardInformResponse {
$$$
}'
# API ์๋ต ์ฒ๋ฆฌ ๋ก์ง ํ์ธ
rg -A 5 'getReviewableGatherings'
Length of output: 3303
Script:
#!/bin/bash
# Check the type definition file
fd reviewable-gathering-card.ts --exec cat {}
# Check the API response handling
rg -A 5 'ReviewableGatheringCardInformResponse' --type typescript
Length of output: 2996
Script:
#!/bin/bash
# Search for the type definition in all files
rg -A 10 'type ReviewableGatheringCardInformResponse'
rg -A 10 'interface ReviewableGatheringCardInformResponse'
# Check the API response structure in the API file
fd reviewable-gathering.ts --exec cat {}
Length of output: 1491
src/app/(crew)/my-page/_components/review-tabs.tsx (2)
6-13: ์ฌ์ฉ๋์ง ์๋ import ๋ฌธ ํ์ธ ํ์
ํ์ฌ ์ฃผ์ ์ฒ๋ฆฌ๋ ์ฝ๋๋ก ์ธํด ๋ค์ import ๋ฌธ๋ค์ด ์ฌ์ฉ๋์ง ์๊ณ ์์ต๋๋ค:
getReviewableGatheringsuseInfiniteScrollfetchMyReviewDataReviewableGatheringCardListReviewInformResponseReviewableGatheringCardInformResponse
๋ฌดํ ์คํฌ๋กค ๊ธฐ๋ฅ์ ๊ตฌํํ ๊ณํ์ด ์๋ค๋ฉด ์ ์งํ๊ณ , ๊ทธ๋ ์ง ์๋ค๋ฉด ์ ๊ฑฐํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
Line range hint 31-49: ์ฃผ์ ์ฒ๋ฆฌ๋ ๋ฌดํ ์คํฌ๋กค ์ฝ๋ ๊ตฌํ ๊ณํ ํ์ธ ํ์
ํ์ฌ ์ฃผ์ ์ฒ๋ฆฌ๋ ๋ฌดํ ์คํฌ๋กค ๊ตฌํ ์ฝ๋๊ฐ ์์ต๋๋ค. ์ด ๊ธฐ๋ฅ์ ๊ตฌํ ๊ณํ๊ณผ ์ผ์ ์ ๋ช ํํ ํ๊ณ , ๋ค์ ์ค ํ๋์ ์กฐ์น๋ฅผ ์ทจํ๋ ๊ฒ์ด ์ข์ต๋๋ค:
-
๊ธฐ๋ฅ ๊ตฌํ์ด ์์ ๋์ด ์๋ค๋ฉด:
- TODO ์ฃผ์์ ์ถ๊ฐํ์ฌ ๊ตฌํ ๊ณํ์ ๋ช ์
- ๊ด๋ จ ์ด์ ๋ฒํธ๋ฅผ ์ฃผ์์ผ๋ก ์ถ๊ฐ
-
๊ธฐ๋ฅ ๊ตฌํ์ด ๋ถํ์ํ๋ค๋ฉด:
- ์ฃผ์ ์ฒ๋ฆฌ๋ ์ฝ๋ ์ ๊ฑฐ
- ๊ด๋ จ import ๋ฌธ ์ ๋ฆฌ
src/components/common/profile/index.tsx (3)
26-26: ์ธํฐํ์ด์ค์ priority ์์ฑ์ด ์ ์ถ๊ฐ๋์์ต๋๋ค.
priority ์์ฑ์ด ์ ํ์ boolean ํ์
์ผ๋ก ์ ์ ํ๊ฒ ์ ์๋์์ต๋๋ค.
35-35: ๊ธฐ๋ณธ๊ฐ ์ค์ ์ด ์ ์ ํฉ๋๋ค.
priority prop์ ๊ธฐ๋ณธ๊ฐ์ false๋ก ์ค์ ํ ๊ฒ์ด ์ ์ ํฉ๋๋ค. ํ์ํ ๊ฒฝ์ฐ์๋ง true๋ก ์ค์ ํ์ฌ ์ต์ ํํ ์ ์์ต๋๋ค.
72-75: Image ์ปดํฌ๋ํธ ์์ฑ ๋ณ๊ฒฝ์ ๋ํ ๊ฒํ ๊ฐ ํ์ํฉ๋๋ค.
Next.js Image ์ปดํฌ๋ํธ์ ์์ฑ์ด ๋ณ๊ฒฝ๋์์ต๋๋ค:
fill๊ณผstyle={{ objectFit: 'cover' }}๋ก์ ๋ณ๊ฒฝ์ ์ต์ Next.js ๋ฒ์ ๊ณผ ํธํ๋ฉ๋๋ค.priority์์ฑ ์ถ๊ฐ๋ LCP(Largest Contentful Paint) ์ต์ ํ์ ๋์์ด ๋ ์ ์์ต๋๋ค.
ํ์ง๋ง ๋ค์ ์ฌํญ์ ํ์ธํด์ฃผ์ธ์:
- ์ด๋ฏธ์ง URL์ด ์์ ๋ defaultImage๋ฅผ ์ฌ์ฉํ๋ ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ ์ฑ๋ฅ
- priority ์์ฑ์ด ์ค์ ๋ก ํ์ํ ํ์ด์ง์์๋ง ์ฌ์ฉ๋๋์ง ์ฌ๋ถ
๋ค์ ์คํฌ๋ฆฝํธ๋ก priority ์์ฑ์ ์ฌ์ฉ์ ํ์ธํ ์ ์์ต๋๋ค:
โ Verification successful
Image ์ปดํฌ๋ํธ ์์ฑ ๋ณ๊ฒฝ์ด ์ ์ ํ๊ฒ ๊ตฌํ๋์์ต๋๋ค.
๊ฒ์ฆ ๊ฒฐ๊ณผ:
- Profile ์ปดํฌ๋ํธ๋ ๋ง์ดํ์ด์ง์ ํ๋กํ ์นด๋(
src/app/(crew)/my-page/_components/profile-card/presenter.tsx)์์๋งpriority์์ฑ์ด ์ฌ์ฉ๋๊ณ ์์ต๋๋ค. - ๋ค๋ฅธ ํ์ด์ง์์๋
priority์์ฑ ์์ด ์ ์ ํ๊ฒ ์ฌ์ฉ๋๊ณ ์์ด, LCP ์ต์ ํ๊ฐ ํ์ํ ๊ณณ์์๋ง ์ ํ์ ์ผ๋ก ์ ์ฉ๋์์ต๋๋ค. fill๊ณผobjectFit: 'cover'์คํ์ผ์ ํ๋กํ ์ด๋ฏธ์ง์ ์ผ๊ด๋ ํ์๋ฅผ ์ํด ์ ์ ํ๊ฒ ์ฌ์ฉ๋์์ต๋๋ค.
๐ Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Profile ์ปดํฌ๋ํธ์์ priority prop์ด true๋ก ์ค์ ๋ ๊ณณ์ ๊ฒ์
# Test: priority prop์ด true๋ก ์ค์ ๋ ๊ณณ ๊ฒ์
rg -l "Profile.*priority.*true"
Length of output: 33
Script:
#!/bin/bash
# 1. Profile ์ปดํฌ๋ํธ์ ์ฌ์ฉ์ฒ ๊ฒ์
rg -A 3 "<Profile"
# 2. priority prop์ด ์ฌ์ฉ๋ ๋ชจ๋ Image ์ปดํฌ๋ํธ ๊ฒ์
rg -A 2 "Image.*priority.*true"
# 3. Profile ์ปดํฌ๋ํธ์ ์ ์ฒด ๊ตฌํ ํ์ธ
fd "profile" --type f --exec cat {}
Length of output: 9737
๐งฐ Tools
๐ช Biome
[error] 73-73: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
package.json (1)
28-28: @tanstack/react-query ๋ฒ์ ์
๋ฐ์ดํธ ๊ฒํ ํ์
react-query์ ๋ฒ์ ์ ๋ฐ์ดํธ(^5.59.16 โ ^5.60.5)๊ฐ ์๋ก์ด ๋ฌดํ ์คํฌ๋กค ๊ธฐ๋ฅ๊ณผ ๊ด๋ จ์ด ์์ต๋๋ค. ์ ๋ฐ์ดํธ๋ ๋ฒ์ ์ ๋ณ๊ฒฝ ์ฌํญ์ ๊ฒํ ํ์ฌ ํธํ์ฑ ๋ฌธ์ ๊ฐ ์๋์ง ํ์ธํด์ฃผ์ธ์.
โ Verification successful
@tanstack/react-query ๋ฒ์ ์ ๋ฐ์ดํธ๋ ์์ ํด ๋ณด์ ๋๋ค
์ฝ๋๋ฒ ์ด์ค ๋ถ์ ๊ฒฐ๊ณผ, react-query์ ๊ธฐ๋ณธ์ ์ธ ์ฌ์ฉ(QueryClient ์ค์ )์ด ํ์ธ๋์์ผ๋ฉฐ, ํ์ฌ ๊ตฌํ๋ ๊ธฐ๋ฅ๋ค์ ๋ฒ์ ์ ๋ฐ์ดํธ๋ก ์ธํ ์ํฅ์ ๋ฐ์ง ์์ ๊ฒ์ผ๋ก ๋ณด์ ๋๋ค. QueryClient ์ค์ ์์๋ ๊ธฐ๋ณธ์ ์ธ staleTime๊ณผ ์๋ฌ ์ฒ๋ฆฌ ๋ก์ง๋ง ์ฌ์ฉํ๊ณ ์์ด ^5.60.5 ๋ฒ์ ์ผ๋ก์ ๋ง์ด๋ ์ ๋ฐ์ดํธ๋ ์์ ํ ๊ฒ์ผ๋ก ํ๋จ๋ฉ๋๋ค.
src/components/client-provider.tsx์์ ํ์ธ๋ QueryClient ์ค์ ์ด ์ ๋ฒ์ ๊ณผ ํธํ๋ฉ๋๋ค.- ์คํ ๋ฆฌ๋ถ ํ์ผ๋ค์ ๊ธฐ๋ณธ QueryClient ์ธ์คํด์ค ์์ฑ๋ ์ํฅ๋ฐ์ง ์์ต๋๋ค.
๐ Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check changelog and breaking changes for @tanstack/react-query
# Fetch the changelog between versions
curl -s "https://raw.githubusercontent.com/TanStack/query/main/CHANGELOG.md" | grep -A 10 "5.60.5\|5.59.16"
Length of output: 107
Script:
#!/bin/bash
# Let's check for any usage of @tanstack/react-query features in the codebase
# This will help us understand the impact of the version update
# Search for react-query hooks and features
rg -l "useQuery|useInfiniteQuery|useMutation|useQueryClient" --type ts --type tsx
# Search for QueryClient configuration
ast-grep --pattern 'new QueryClient'
Length of output: 2526
Script:
#!/bin/bash
# Let's check for specific react-query features usage, especially infinite query
# which might be related to the version update
# Search for infinite query usage
rg "useInfiniteQuery" -A 5 --type js --type jsx --type ts
# Search for any query key definitions to understand data fetching patterns
rg "queryKey:" -A 2 --type js --type jsx --type ts
Length of output: 164
.vscode/settings.json (2)
77-77: TypeScript ํฌ๋งทํฐ ์ค์ ์ด ์ ์ ํฉ๋๋ค!
JavaScript์ ๋์ผํ๊ฒ Prettier๋ฅผ ์ฌ์ฉํ๋๋ก ์ค์ ํ์ฌ ์ผ๊ด์ฑ์ ์ ์งํ๊ณ ์์ต๋๋ค.
78-78: Git ๋ฌด์ ํ๋ ๊ฒฝ๊ณ ์ค์ ์ ๋ํด ๊ฒํ ๊ฐ ํ์ํฉ๋๋ค.
git.ignoreLimitWarning ์ค์ ์ ์ถ๊ฐํ ๊ฒ์ ํ๋ก์ ํธ์ ๋ง์ ์์ ๋ฌด์๋ ํ์ผ์ด ์๋ค๋ ๊ฒ์ ์๋ฏธํ ์ ์์ต๋๋ค. ์ด๋ ์ ์ฌ์ ์ธ ๋ฌธ์ ๋ฅผ ๋ํ๋ผ ์ ์์ต๋๋ค.
๋ค์ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ์ฌ .gitignore ํ์ผ์ ์ํ๋ฅผ ํ์ธํด๋ณด์ธ์:
ํ๋ก์ ํธ ๊ตฌ์กฐ๋ฅผ ๊ฒํ ํ๊ณ ๋ค์ ์ฌํญ์ ๊ณ ๋ คํด๋ณด์๊ธฐ ๋ฐ๋๋๋ค:
- ๋น๋ ์ฐ์ถ๋ฌผ์ด ์ ์ ํ ์ ๋ฆฌ๋๊ณ ์๋์ง
- ๋ถํ์ํ ํ์ผ์ด ํ๋ก์ ํธ์ ํฌํจ๋์ด ์์ง๋ ์์์ง
.gitignoreํจํด์ด ๋๋ฌด ๊ด๋ฒ์ํ์ง๋ ์์์ง
โ Verification successful
Git ๋ฌด์ ํ๋ ๊ฒฝ๊ณ ์ค์ ์ด ์ ์ ํฉ๋๋ค.
.gitignore ํ์ผ์ ๊ฒํ ํ ๊ฒฐ๊ณผ, ์ผ๋ฐ์ ์ธ Node.js/Next.js ํ๋ก์ ํธ์์ ์ฌ์ฉ๋๋ ํ์ค์ ์ธ ๋ฌด์ ํจํด๋ง์ ํฌํจํ๊ณ ์์ต๋๋ค. ํ์ฌ ๋ฌด์๋ ํ์ผ์ด 0๊ฐ๋ก ํ์ธ๋์ด git.ignoreLimitWarning ์ค์ ์ ๋จ์ํ ์๋ฐฉ ์ฐจ์์ ์ค์ ์ผ๋ก ๋ณด์
๋๋ค.
๋ฌด์ ํจํด ๋ชฉ๋ก์ด ๋ค์๊ณผ ๊ฐ์ด ์ ์ ํ๊ฒ ๊ตฌ์ฑ๋์ด ์์ต๋๋ค:
- ์์กด์ฑ ๊ด๋ จ:
/node_modules,.pnp,.yarn - ๋น๋ ์ฐ์ถ๋ฌผ:
/build,/.next,/out - ํ๊ฒฝ ์ค์ :
.env,.env*.local - ํ
์คํธ/๋๋ฒ๊ทธ ๊ด๋ จ:
/coverage,npm-debug.log* - Storybook ๊ด๋ จ:
/storybook-static
๐ Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check .gitignore patterns and ignored files count
# Show .gitignore patterns
echo "=== .gitignore ํจํด ==="
cat .gitignore
# Count ignored files
echo -e "\n=== ๋ฌด์๋ ํ์ผ ์ ==="
git status --ignored | grep -c "ignored"
Length of output: 603
| export default function ReviewableTab() { | ||
| return <ReviewableGatheringCardList />; | ||
| } |
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
์๋ฌ ์ฒ๋ฆฌ์ ๋ก๋ฉ ์ํ ๊ด๋ฆฌ๊ฐ ํ์ํฉ๋๋ค.
ํ์ฌ ๊ตฌํ์ ๋งค์ฐ ๋จ์ํ์ฌ ๋ค์๊ณผ ๊ฐ์ ๊ฐ์ ์ฌํญ์ ๊ณ ๋ คํด๋ณด์๊ธฐ ๋ฐ๋๋๋ค:
- ์๋ฌ ๋ฐ์ด๋๋ฆฌ ์ถ๊ฐ
- ๋ก๋ฉ ์ํ ์ฒ๋ฆฌ
- ํด๋ฐฑ UI ๊ตฌํ
๋ค์๊ณผ ๊ฐ์ด ๊ฐ์ ํ ์ ์์ต๋๋ค:
+import { Suspense, ErrorBoundary } from 'react';
+import LoadingSpinner from '@/src/components/common/loading-spinner';
+import ErrorFallback from '@/src/components/common/error-fallback';
export default function ReviewableTab() {
- return <ReviewableGatheringCardList />;
+ return (
+ <ErrorBoundary fallback={<ErrorFallback />}>
+ <Suspense fallback={<LoadingSpinner />}>
+ <ReviewableGatheringCardList />
+ </Suspense>
+ </ErrorBoundary>
+ );
}Committable suggestion skipped: line range outside the PR's diff.
| import { ReviewableGatheringCardInformResponse } from '@/src/types/reviewable-gathering-card'; | ||
|
|
||
| export async function getReviewableGatherings(pageable: PageableTypes) { | ||
| const { page, size, sort = ['string'] } = pageable; |
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
sort ๋งค๊ฐ๋ณ์์ ๊ธฐ๋ณธ๊ฐ ์ค์ ๊ฐ์ ํ์
sort ๋งค๊ฐ๋ณ์์ ๊ธฐ๋ณธ๊ฐ์ด ['string']์ผ๋ก ํ๋์ฝ๋ฉ๋์ด ์์ต๋๋ค. ์ด๋ ์ค์ ์ ๋ ฌ ๋ก์ง๊ณผ ๋ง์ง ์์ ์ ์์ต๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์์ ํ๋ ๊ฒ์ ์ ์๋๋ฆฝ๋๋ค:
- const { page, size, sort = ['string'] } = pageable;
+ const { page, size, sort = ['createdAt,desc'] } = pageable;๐ 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.
| const { page, size, sort = ['string'] } = pageable; | |
| const { page, size, sort = ['createdAt,desc'] } = pageable; |
| export async function getReviewableGatherings(pageable: PageableTypes) { | ||
| const { page, size, sort = ['string'] } = pageable; | ||
| const response: { data: ReviewableGatheringCardInformResponse } = await fetchApi( | ||
| `/api/gatherings/reviewable?page=${page}&size=${size}&sort=${sort}`, |
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.
URL ๋งค๊ฐ๋ณ์ ์ธ์ฝ๋ฉ ์ฒ๋ฆฌ ํ์
URL ๋งค๊ฐ๋ณ์๊ฐ ์ธ์ฝ๋ฉ๋์ง ์์ ํน์ ๋ฌธ์๊ฐ ํฌํจ๋ ๊ฒฝ์ฐ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
๋ค์๊ณผ ๊ฐ์ด encodeURIComponent๋ฅผ ์ฌ์ฉํ์ฌ ์์ ํ๋ ๊ฒ์ ์ ์๋๋ฆฝ๋๋ค:
- `/api/gatherings/reviewable?page=${page}&size=${size}&sort=${sort}`,
+ `/api/gatherings/reviewable?page=${encodeURIComponent(page)}&size=${encodeURIComponent(size)}&sort=${encodeURIComponent(sort)}`,๐ 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.
| `/api/gatherings/reviewable?page=${page}&size=${size}&sort=${sort}`, | |
| `/api/gatherings/reviewable?page=${encodeURIComponent(page)}&size=${encodeURIComponent(size)}&sort=${encodeURIComponent(sort)}`, |
| } | ||
|
|
||
| export default function ReviewingModal({ opened, close }: ReviewingModalProps) { | ||
| export default function ReviewingModal({ gatheringId, opened, close }: ReviewingModalProps) { |
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
ReviewForm์ gatheringId๋ฅผ ์ ๋ฌํด์ผ ํฉ๋๋ค.
๋ฆฌ๋ทฐ ์์ฑ ์ ์ด๋ค ๋ชจ์์ ๋ํ ๋ฆฌ๋ทฐ์ธ์ง ์๋ณํ๊ธฐ ์ํด gatheringId๊ฐ ํ์ํ ๊ฒ ๊ฐ์ต๋๋ค. ReviewForm ์ปดํฌ๋ํธ์ ์ด ๊ฐ์ ์ ๋ฌํ๋ ๊ฒ์ด ์ข๊ฒ ์ต๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์์ ํ๋ ๊ฒ์ ์ ์ํฉ๋๋ค:
- <ReviewForm onCancel={close} />
+ <ReviewForm gatheringId={gatheringId} onCancel={close} />Also applies to: 34-34
| import ReviewForm from './review-form'; | ||
|
|
||
| export interface ReviewingModalProps { | ||
| gatheringId: 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.
๐ก Codebase verification
gatheringId๋ฅผ ReviewForm ์ปดํฌ๋ํธ์ ์ ๋ฌํด์ผ ํฉ๋๋ค
ReviewForm ์ปดํฌ๋ํธ์์ ๋ฆฌ๋ทฐ๋ฅผ ์ ์ถํ๊ธฐ ์ํด gatheringId๊ฐ ํ์ํ ๊ฒ์ผ๋ก ๋ณด์
๋๋ค. ํ์ฌ๋ onCancel prop๋ง ์ ๋ฌ๋๊ณ ์์ต๋๋ค.
<ReviewForm onCancel={close} />โ<ReviewForm onCancel={close} gatheringId={gatheringId} />๋ก ์์ ์ด ํ์ํฉ๋๋ค.review-form.tsx์ReviewProps์ธํฐํ์ด์ค์๋gatheringId: numberํ์ ์ ์๋ฅผ ์ถ๊ฐํด์ผ ํฉ๋๋ค.
๐ Analysis chain
ํ์ ์ ์๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์ถ๊ฐ๋์์ต๋๋ค.
์ธํฐํ์ด์ค์ gatheringId ์์ฑ์ด ์ถ๊ฐ๋ ๊ฒ์ ์ข์ต๋๋ค. ํ์ง๋ง ํ์ฌ ์ปดํฌ๋ํธ์์ ์ด ์์ฑ์ด ์ฌ์ฉ๋์ง ์๊ณ ์์ต๋๋ค.
๐ Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: ReviewForm ์ปดํฌ๋ํธ์์ gatheringId prop์ด ํ์ํ์ง ํ์ธ
# ReviewForm ์ปดํฌ๋ํธ ๊ฒ์
ast-grep --pattern 'interface ReviewFormProps {
$$$
}'
Length of output: 58
Script:
#!/bin/bash
# Let's try to find ReviewForm component and its props usage
rg "ReviewForm" -A 5 -B 5
# Also search for any file containing ReviewForm in its name
fd ReviewForm
Length of output: 2460
| "next": "^14.2.15", | ||
| "react": "^18.3.1", | ||
| "react-dom": "^18.3.1", |
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.
๐ก Codebase verification
์์กด์ฑ ๋ฒ์ ๋ถ์ผ์น ๋ฐ ํธํ์ฑ ๋ฌธ์ ๋ฐ๊ฒฌ
Next.js์ React ๋ฒ์ ๊ฐ์ ํธํ์ฑ ๋ฌธ์ ๊ฐ ํ์ธ๋์์ต๋๋ค:
- Next.js 14.2.18์ React ^18.2.0์ peer dependency๋ก ์๊ตฌํ์ง๋ง, ํ์ฌ React ^18.3.1๋ก ์ค์ ๋์ด ์์ต๋๋ค
- package-lock.json์์ Next.js๋ 14.2.18 ๋ฒ์ ์ผ๋ก ๊ณ ์ ๋์ด ์์ผ๋, package.json์์๋ ^14.2.15๋ก ์ค์ ๋์ด ์์ด ์ผ๊ด์ฑ์ด ์์ต๋๋ค
๋ค์๊ณผ ๊ฐ์ด ์์ ์ ๊ถ์ฅ๋๋ฆฝ๋๋ค:
- React์ React DOM ๋ฒ์ ์ ^18.2.0์ผ๋ก ๋ค์ด๊ทธ๋ ์ด๋
- Next.js ๋ฒ์ ์ 14.2.18๋ก ๊ณ ์
๐ Analysis chain
์์กด์ฑ ๋ฒ์ ๊ด๋ฆฌ ์ ๋ต ๊ฒํ ํ์
๋ค์ ๋ณ๊ฒฝ ์ฌํญ๋ค์ ๋ํ ๊ฒํ ๊ฐ ํ์ํฉ๋๋ค:
- next.js: ๊ณ ์ ๋ฒ์ ์์ ์ ๋์ ๋ฒ์ ์ผ๋ก ๋ณ๊ฒฝ (14.2.15 โ ^14.2.15)
- react์ react-dom: ๋ ๊ตฌ์ฒด์ ์ธ ๋ฒ์ ์ผ๋ก ์ ๋ฐ์ดํธ (^18 โ ^18.3.1)
์ด๋ฌํ ๋ณ๊ฒฝ์ ์๊ธฐ์น ์์ ํธํ์ฑ ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ ์์ผ๋ฏ๋ก, ํ์ ๋ฒ์ ๊ด๋ฆฌ ์ ์ฑ ๊ณผ ์ผ์นํ๋์ง ํ์ธํด์ฃผ์ธ์.
๐ Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for peer dependency requirements
# Check next.js peer dependencies
curl -s https://registry.npmjs.org/next/14.2.15 | jq '.peerDependencies'
# Check if react versions are aligned in other package files
fd -e json -e yaml -e yml | xargs grep -l "react.*18.3.1"
Length of output: 301
Script:
#!/bin/bash
# Check package-lock.json for react dependencies and their resolved versions
cat package-lock.json | jq '.packages | .["node_modules/react"], .["node_modules/react-dom"], .["node_modules/next"]' 2>/dev/null
# Check for any direct usage of React 18.3 specific features
rg -l "experimental|concurrent|use client" --type js --type jsx --type ts --type tsx
# Check the current next.js version in package-lock.json
cat package-lock.json | jq '.packages["node_modules/next"].version' 2>/dev/null
Length of output: 2272
| const handleConfirmDelete = () => { | ||
| // TODO : ์ญ์ ๋ก์ง | ||
| closeConfirmCancel(); | ||
| }; | ||
|
|
||
| const handleConfirmLeaveCrew = () => { | ||
| // TODO : ํํด ๋ก์ง | ||
| closeLeaveCrewModal(); | ||
| }; |
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.
๋ฏธ๊ตฌํ๋ ์ญ์ /ํํด ๋ก์ง ๊ตฌํ ํ์
์ญ์ ์ ํํด ๊ธฐ๋ฅ์ด ์์ง ๊ตฌํ๋์ง ์์์ต๋๋ค. ์๋ฌ ์ฒ๋ฆฌ์ ์ฌ์ฉ์ ํผ๋๋ฐฑ๋ ๊ณ ๋ คํด์ผ ํฉ๋๋ค.
์ญ์ /ํํด ๋ก์ง ๊ตฌํ์ ๋์์ด ํ์ํ์ ๊ฐ์? GitHub ์ด์๋ฅผ ์์ฑํด๋๋ฆด ์ ์์ต๋๋ค.
| {/* eslint-disable-next-line no-nested-ternary */} | ||
| {/* //TODO: captin, crew์ธ ๊ฒฝ์ฐ ๋ก์ง ์์ */} | ||
| {/* {isCaptain ? ( | ||
| <Menu trigger="click" position="bottom-end" openDelay={100} closeDelay={400}> | ||
| <Menu.Target> | ||
| <div className="top-68 absolute right-6 top-[286px] cursor-pointer md:top-6 lg:top-6"> | ||
| <Image src={KebabIcon} alt="๋๋ณด๊ธฐ" width={20} height={20} /> | ||
| </div> | ||
| </Menu.Target> | ||
| <Menu.Dropdown> | ||
| <Menu.Item component="a" href={`/crew/detail/${id}/edit`} className="font-pretendard"> | ||
| ํฌ๋ฃจ ์์ ํ๊ธฐ | ||
| </Menu.Item> | ||
| <Menu.Item | ||
| type="button" | ||
| onClick={handleDelete} | ||
| className="font-pretendard text-red-600" | ||
| > | ||
| ํฌ๋ฃจ ์ญ์ ํ๊ธฐ | ||
| </Menu.Item> | ||
| </Menu.Dropdown> | ||
| </Menu> | ||
| ) : isCrew ? ( | ||
| <Menu trigger="click" position="bottom-end" openDelay={100} closeDelay={400}> | ||
| <Menu.Target> | ||
| <div className="top-68 absolute right-6 top-[286px] md:top-6 lg:top-6"> | ||
| <Image src={KebabIcon} alt="๋๋ณด๊ธฐ" width={20} height={20} /> | ||
| </div> | ||
| </Menu.Target> | ||
| <Menu.Dropdown> | ||
| <Menu.Item type="button" onClick={handleLeaveCrew} className="font-pretendard"> | ||
| ํฌ๋ฃจ ํํดํ๊ธฐ | ||
| </Menu.Item> | ||
| </Menu.Dropdown> | ||
| </Menu> | ||
| ) : null} */} |
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.
์ฃผ์ ์ฒ๋ฆฌ๋ ์ฝ๋ ์ ๋ฆฌ ํ์
์ฃผ์ ์ฒ๋ฆฌ๋ captain/crew ๊ด๋ จ ์ฝ๋๊ฐ ์์ต๋๋ค. ์ด๋ ์ฝ๋ ๊ฐ๋ ์ฑ์ ์ ํ์ํค๊ณ ์ ์ง๋ณด์๋ฅผ ์ด๋ ต๊ฒ ๋ง๋ญ๋๋ค.
๊ตฌํ์ด ํ์ํ ๊ฒฝ์ฐ TODO ์ฃผ์๋ง ๋จ๊ธฐ๊ณ ๋๋จธ์ง๋ ์ ๊ฑฐํ๊ฑฐ๋, ํ์์๋ ๊ฒฝ์ฐ ์ ์ฒด ์ฃผ์์ ์ ๊ฑฐํด์ฃผ์ธ์.
| <span className="text-sm font-medium text-gray-700">์ต์์ธ์ 2๋ช </span> | ||
| <span className="text-sm font-medium text-gray-700">์ต๋์ธ์ {totalCount}๋ช </span> |
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
ํ๋์ฝ๋ฉ๋ ๊ฐ๋ค์ ์์ํ ํ์
์ต์ ์ธ์์๊ฐ ํ๋์ฝ๋ฉ๋์ด ์์ต๋๋ค. ์ด๋ฐ ๊ฐ๋ค์ ์์๋ก ๋ถ๋ฆฌํ์ฌ ๊ด๋ฆฌํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์์๋ฅผ ์ถ๊ฐํด์ฃผ์ธ์:
const CREW_CONSTANTS = {
MIN_MEMBERS: 2,
// ๋ค๋ฅธ ์์๋ค๋ ์ถ๊ฐ
} as const;| <div className="relative h-[270px] w-full md:w-[385px] lg:w-[540px]"> | ||
| <Image fill style={{ objectFit: 'cover' }} alt={title} src={imageUrl} /> | ||
| </div> |
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
์ ๊ทผ์ฑ ๊ฐ์ ํ์
์ด๋ฏธ์ง์ ๋ํ ์๋ฏธ ์๋ ๋์ฒด ํ ์คํธ๊ฐ ๋ถ์กฑํฉ๋๋ค. ๋ํ ์ด๋ฏธ์ง๊ฐ ์ฅ์์ฉ์ธ ๊ฒฝ์ฐ์๋ ๋ช ์์ ์ผ๋ก ํ์ํด์ผ ํฉ๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์์ ํด์ฃผ์ธ์:
-<Image fill style={{ objectFit: 'cover' }} alt={title} src={imageUrl} />
+<Image
+ fill
+ style={{ objectFit: 'cover' }}
+ alt={`${title} ํฌ๋ฃจ์ ๋ํ ์ด๋ฏธ์ง`}
+ src={imageUrl}
+/>๐ 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.
| <div className="relative h-[270px] w-full md:w-[385px] lg:w-[540px]"> | |
| <Image fill style={{ objectFit: 'cover' }} alt={title} src={imageUrl} /> | |
| </div> | |
| <div className="relative h-[270px] w-full md:w-[385px] lg:w-[540px]"> | |
| <Image | |
| fill | |
| style={{ objectFit: 'cover' }} | |
| alt={`${title} ํฌ๋ฃจ์ ๋ํ ์ด๋ฏธ์ง`} | |
| src={imageUrl} | |
| /> | |
| </div> |
HaeJungg
left a comment
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.
์๊ณ ํ์ จ์ต๋๋ค๐
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.
์ ํ์ผ์ ์ง๊ธ ์๋ ํ์ผ์ธ๋ฐ ๋ค์ ์๊ฒผ๋ค์...! ์ต์ ํ๊ฐ ๋๋์๊น์...! ์๋๋ฉด ๋จธ์งํ๋ฉด์ ์ด์ ํ์ผ์ด ์ด์๋๊ฑฐ๊ฐ์์๐ฅฒ
|
๐storybook: https://67206cc6ff9d7a05a3528ff8-xssmkvshtx.chromatic.com/ |
|
๐storybook: https://67206cc6ff9d7a05a3528ff8-bbcqytlngk.chromatic.com/ |
yulrang
left a comment
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.
์๊ณ ํ์ จ์ต๋๋ค~~~~
๐ Issue Ticket
Ticket
โ๏ธ Description
๋ฆฌ๋ทฐ ๊ฐ๋ฅํ ๋ชจ์ ๋ชฉ๋ก์ ์กฐํํ๋ api ์์ฒญ ํจ์๋ฅผ ์์ฑํ๊ณ ,
๊ธฐ์กด์ ๋ชฉ๋ก ์ปดํฌ๋ํธ ์์ ํ์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ๊ธฐ์กด์ writable๋ก ์์ํ๋ ํ์ ์ด๋ ์ปดํฌ๋ํธ๋ฅผ reviewable๋ก ์์ ํ๋๋ฐ conflict ๋ ๊ฒ ๊ฐ์ ๋๋ ต์ด๋๋ค
โ Checklist
PR
Test
Summary by CodeRabbit
New Features
"git.ignoreLimitWarning": true๊ฐ ์ถ๊ฐ๋์์ต๋๋ค.ReviewableGatheringCardList์ปดํฌ๋ํธ๊ฐ ์ถ๊ฐ๋์ด ๋ฆฌ๋ทฐ ๊ฐ๋ฅํ ๋ชจ์์ ํ์ํฉ๋๋ค.DetailCrewCard์ปดํฌ๋ํธ๊ฐ ์ถ๊ฐ๋์ด ํฌ๋ฃจ์ ์์ธ ์ ๋ณด๋ฅผ ํ์ํฉ๋๋ค.useInfiniteScrollํ ์ด ์ถ๊ฐ๋์ด ๋ฌดํ ์คํฌ๋กค ๊ธฐ๋ฅ์ ์ง์ํฉ๋๋ค.Bug Fixes
Profile์ปดํฌ๋ํธ์priorityํ๋กํผํฐ๊ฐ ์ถ๊ฐ๋์ด ์ด๋ฏธ์ง ์ฐ์ ์์๋ฅผ ์ค์ ํ ์ ์์ต๋๋ค.Refactor
WritableGatheringCard๊ฐReviewableGatheringCard๋ก ์ด๋ฆ์ด ๋ณ๊ฒฝ๋์์ต๋๋ค.ReviewingModal์gatheringIdํ๋กํผํฐ๊ฐ ์ถ๊ฐ๋์์ต๋๋ค.Chores