Skip to content
5 changes: 2 additions & 3 deletions src/app/(crew)/my-crew/hosted/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Loader } from '@mantine/core';
import { useGetMyCrewHostedQuery } from '@/src/_queries/crew/my-crew-hosted-list-query';
import { useInfiniteScroll } from '@/src/hooks/use-infinite-scroll';
import CrewCardList from '@/src/components/common/crew-list/crew-card-list';
import CrewSkeletonList from '@/src/components/common/skeleton/crew-skeleton-list';

export default function MyCrewHostedPage() {
const { data, isLoading, error, ref, isFetchingNextPage } = useInfiniteScroll(
Expand All @@ -15,9 +16,7 @@ export default function MyCrewHostedPage() {
<div>
<CrewCardList inWhere="my-crew" data={data ?? { pages: [], pageParams: [] }} />
{isLoading || isFetchingNextPage ? (
<div className="flex justify-center py-10">
<Loader size="sm" />
</div>
<CrewSkeletonList num={6} column={1} />
) : (
<div ref={ref} className="h-[1px]" />
)}
Expand Down
5 changes: 2 additions & 3 deletions src/app/(crew)/my-crew/joined/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Loader } from '@mantine/core';
import { useGetMyCrewJoinedQuery } from '@/src/_queries/crew/my-crew-joined-list-query';
import { useInfiniteScroll } from '@/src/hooks/use-infinite-scroll';
import CrewCardList from '@/src/components/common/crew-list/crew-card-list';
import CrewSkeletonList from '@/src/components/common/skeleton/crew-skeleton-list';

export default function MyCrewJoinedPage() {
const { data, isLoading, error, ref, isFetchingNextPage } = useInfiniteScroll(
Expand All @@ -15,9 +16,7 @@ export default function MyCrewJoinedPage() {
<div>
<CrewCardList inWhere="my-crew" data={data ?? { pages: [], pageParams: [] }} />
{isLoading || isFetchingNextPage ? (
<div className="flex justify-center py-10">
<Loader size="sm" />
</div>
<CrewSkeletonList num={6} column={1} />
) : (
<div ref={ref} className="h-[1px]" />
)}
Expand Down
4 changes: 3 additions & 1 deletion src/app/(crew)/my-gathering/hosted/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import { useGetHostedGatheringListQuery } from '@/src/_queries/my-gathering/host
import { formatDateToRequest } from '@/src/utils/format-date';
import GatheringListWithDate from '@/src/app/(crew)/my-gathering/_component/gathering-list-with-date';
import PopOverCalendar from '@/src/components/common/input/pop-over-calendar';
import MyGatheringSkeletonList from '@/src/components/common/skeleton/my-gathering-skeleton-list';
import { GatheringCardProps } from '@/src/types/gathering-data';

export default function MyGatheringHostedPage() {
const [selectedDate, setSelectedDate] = useState(new Date());
const [hostedGatheringList, setHostedGatheringList] = useState<GatheringCardProps[]>();

const { data, refetch } = useQuery(
const { data, isLoading, refetch } = useQuery(
useGetHostedGatheringListQuery(formatDateToRequest(selectedDate)),
);

Expand All @@ -29,6 +30,7 @@ export default function MyGatheringHostedPage() {
<div className="py-4 md:py-6">
<PopOverCalendar value={selectedDate} onChange={(d) => setSelectedDate(d)} />
</div>
{isLoading && <MyGatheringSkeletonList num={6} />}
{hostedGatheringList && <GatheringListWithDate gatheringList={hostedGatheringList} />}
</div>
);
Expand Down
4 changes: 3 additions & 1 deletion src/app/(crew)/my-gathering/joined/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import { useGetJoinedGatheringListQuery } from '@/src/_queries/my-gathering/join
import { formatDateToRequest } from '@/src/utils/format-date';
import GatheringListWithDate from '@/src/app/(crew)/my-gathering/_component/gathering-list-with-date';
import PopOverCalendar from '@/src/components/common/input/pop-over-calendar';
import MyGatheringSkeletonList from '@/src/components/common/skeleton/my-gathering-skeleton-list';
import { GatheringCardProps } from '@/src/types/gathering-data';

export default function MyGatheringJoinedPage() {
const [selectedDate, setSelectedDate] = useState(new Date());
const [joinedGatheringList, setJoinedGatheringList] = useState<GatheringCardProps[]>();

const { data, refetch } = useQuery(
const { data, isLoading, refetch } = useQuery(
useGetJoinedGatheringListQuery(formatDateToRequest(selectedDate)),
);

Expand All @@ -29,6 +30,7 @@ export default function MyGatheringJoinedPage() {
<div className="py-4 md:py-6">
<PopOverCalendar value={selectedDate} onChange={(d) => setSelectedDate(d)} />
</div>
{isLoading && <MyGatheringSkeletonList num={6} />}
{joinedGatheringList && <GatheringListWithDate gatheringList={joinedGatheringList} />}
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from '@/src/_apis/auth/user-apis';
import { useUser } from '@/src/_queries/auth/user-queries';
import { useAuth } from '@/src/hooks/use-auth';
import ProfileSkeleton from '@/src/components/common/skeleton/profile-skeleton';
import ProfileCardPresenter from './presenter';

export default function ProfileCard() {
Expand Down Expand Up @@ -38,7 +39,7 @@ export default function ProfileCard() {
}
}, [user]);

if (userLoading || !isAuthChecked) return <div>로딩 중...</div>;
if (userLoading || !isAuthChecked) return <ProfileSkeleton />;
if (!user) return null;

const handleEdit = () => {
Expand Down
7 changes: 3 additions & 4 deletions src/app/(crew)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { useRef, useState } from 'react';
import Image from 'next/image';
import { Divider, Loader, TextInput } from '@mantine/core';
import { Divider, Loader, Skeleton, TextInput } from '@mantine/core';
import { useGetCrewListQuery } from '@/src/_queries/crew/crew-list-queries';
import regionData from '@/src/data/region.json';
import { useInfiniteScroll } from '@/src/hooks/use-infinite-scroll';
Expand All @@ -11,6 +11,7 @@ import HeroCrew from '@/src/app/(crew)/_components/hero/hero-crew';
import CrewCardList from '@/src/components/common/crew-list/crew-card-list';
import Button from '@/src/components/common/input/button';
import DropDown from '@/src/components/common/input/drop-down';
import CrewSkeletonList from '@/src/components/common/skeleton/crew-skeleton-list';
import IcoSearch from '@/public/assets/icons/ic-search.svg';

export default function HomePage() {
Expand Down Expand Up @@ -133,9 +134,7 @@ export default function HomePage() {
<div className="mt-8 px-3 md:px-8 lg:px-11.5">
{data && <CrewCardList data={data} />}
{isLoading || isFetchingNextPage ? (
<div className="flex justify-center py-10">
<Loader size="sm" />
</div>
<CrewSkeletonList num={6} column={2} />
) : (
<div ref={ref} className="h-[1px]" />
)}
Expand Down
2 changes: 1 addition & 1 deletion src/components/common/crew-list/crew-card-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default function CrewCardList({ data, inWhere }: CrewCardListProps) {
);

return (
<ul className={`mx-auto grid w-full grid-cols-1 gap-x-2 gap-y-2 ${gridColsStyle}`}>
<ul className={`mx-auto grid w-full grid-cols-1 gap-x-4 gap-y-6 ${gridColsStyle}`}>
{crewDataList.map((inform) => (
<li key={inform?.id} className="w-full">
<CrewCard
Expand Down
6 changes: 3 additions & 3 deletions src/components/common/crew-list/crew-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ export default function CrewCard({
<div
role="presentation"
onClick={() => router.push(CREWPAGE)}
className="relative mx-auto flex h-[430px] w-full animate-fade cursor-pointer flex-col overflow-hidden rounded-[14px] bg-white shadow-bg md:h-[203px] md:flex-row"
className="relative mx-auto flex w-full animate-fade cursor-pointer flex-col overflow-hidden rounded-[14px] bg-white transition-shadow hover:shadow-card md:h-[203px] md:flex-row"
>
{/* 썸네일 */}
<div className="relative h-[203px] w-full flex-shrink-0 md:w-[230px]">
<Image fill objectFit="cover" alt={title} src={imageUrl} />
</div>

<div className="flex w-full flex-col justify-between p-6 sm:h-[238px] sm:px-4 sm:pt-4 md:h-[203px]">
<div className="flex min-h-[203px] w-full flex-col justify-between p-6 sm:px-4 sm:pt-4">
<div>
<div className="flex flex-col gap-1">
<span className="max-w-[200px] overflow-hidden text-ellipsis whitespace-nowrap pr-4 text-lg font-semibold">
Expand All @@ -66,7 +66,7 @@ export default function CrewCard({
{`현재 ${totalGatheringCount}개의 약속이 개설되어 있습니다.`}
</span>
</div>
<div className="flex w-full gap-8 pt-[31px]">
<div className="flex w-full gap-8 md:pt-[31px]">
<div className="flex flex-grow flex-col items-start gap-2">
<div className="flex w-full items-center justify-between">
<div className="flex items-center space-x-2">
Expand Down
12 changes: 10 additions & 2 deletions src/components/common/input/date-time-picker/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,18 @@ export default function DateTimePicker({ fullDate, onChange }: DateTimePickerPro
const [minute, setMinute] = useState<string | null>('분');

const handleSelect = (date: Date) => {
const newDate = new Date(selected);
const isSelected = selected;

newDate.setFullYear(Number(date.getFullYear()));
newDate.setMonth(Number(date.getMonth()));
newDate.setDate(Number(date.getDate()));

const kstDate = new Date(newDate.getTime() - newDate.getTimezoneOffset() * 60000).toISOString();

if (isSelected) {
setSelected(date);
setSelected(newDate);
onChange(kstDate);
Comment on lines +21 to +32
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

날짜 선택 로직 개선이 필요합니다

다음과 같은 개선사항을 제안드립니다:

  1. 불필요한 isSelected 체크를 제거하고 로직을 단순화
  2. DST(일광절약시간제) 변경 시 발생할 수 있는 문제를 방지하기 위해 date-fns 라이브러리 사용 고려

다음과 같이 수정하는 것을 추천드립니다:

- const newDate = new Date(selected);
- const isSelected = selected;
+ const newDate = new Date(
+   date.getFullYear(),
+   date.getMonth(),
+   date.getDate(),
+   selected.getHours(),
+   selected.getMinutes()
+ );

- newDate.setFullYear(Number(date.getFullYear()));
- newDate.setMonth(Number(date.getMonth()));
- newDate.setDate(Number(date.getDate()));

const kstDate = new Date(newDate.getTime() - newDate.getTimezoneOffset() * 60000).toISOString();

- if (isSelected) {
-   setSelected(newDate);
-   onChange(kstDate);
- }
+ setSelected(newDate);
+ onChange(kstDate);
📝 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.

Suggested change
const newDate = new Date(selected);
const isSelected = selected;
newDate.setFullYear(Number(date.getFullYear()));
newDate.setMonth(Number(date.getMonth()));
newDate.setDate(Number(date.getDate()));
const kstDate = new Date(newDate.getTime() - newDate.getTimezoneOffset() * 60000).toISOString();
if (isSelected) {
setSelected(date);
setSelected(newDate);
onChange(kstDate);
const newDate = new Date(
date.getFullYear(),
date.getMonth(),
date.getDate(),
selected.getHours(),
selected.getMinutes()
);
const kstDate = new Date(newDate.getTime() - newDate.getTimezoneOffset() * 60000).toISOString();
setSelected(newDate);
onChange(kstDate);

}
};

Expand Down Expand Up @@ -53,7 +61,7 @@ export default function DateTimePicker({ fullDate, onChange }: DateTimePickerPro
})}
firstDayOfWeek={0}
classNames={{
day: 'w-full aspect-square text-gray-800 data-[selected=true]:text-white flex',
day: 'w-full aspect-square text-gray-800 data-[selected=true]:text-white data-[selected=true]:rounded-xl flex',
monthCell: 'w-[calc(14.285vw-5.714px)] aspect-square md:w-[85px]',
monthsListCell:
'w-[calc(33.333vw-13.333px)] h-[10vw] md:w-[200px] md:h-[80px] text-gray-800',
Expand Down
18 changes: 18 additions & 0 deletions src/components/common/skeleton/crew-skeleton-list/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import CrewSkeleton from '../crew-skeleton';

interface CrewSkeletonListProps {
num: number;
column?: number;
}

export default function CrewSkeletonList({ num, column }: CrewSkeletonListProps) {
const columnStyle = column === 2 ? 'lg:grid-cols-2' : 'lg:grid-cols-1';
return (
<div className={`grid grid-cols-1 gap-x-4 gap-y-6 ${columnStyle}`} aria-label="콘텐츠 로딩 중">
{[...Array(num)].map((_, index) => (
// eslint-disable-next-line react/no-array-index-key
<CrewSkeleton key={index} />
))}
</div>
);
}
15 changes: 15 additions & 0 deletions src/components/common/skeleton/crew-skeleton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Skeleton } from '@mantine/core';

export default function CrewSkeleton() {
return (
<div className="flex flex-col overflow-hidden rounded-xl md:flex-row">
<Skeleton className="h-[203px] md:w-[230px]" />
<div className="md:min-h-auto relative flex min-h-[203px] flex-1 flex-col gap-2 p-6">
<Skeleton className="h-4 w-2/3" />
<Skeleton className="h-4 w-32" />
<Skeleton className="h-4 w-40" />
<Skeleton className="absolute bottom-6 left-6 right-6 h-2 w-auto" />
</div>
</div>
);
}
19 changes: 19 additions & 0 deletions src/components/common/skeleton/gathering-skeleton-list/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import GatheringSkeleton from '../gathering-skeleton';

interface GatheringSkeletonListProps {
num: number;
}

export default function GatheringSkeletonList({ num }: GatheringSkeletonListProps) {
return (
<div
className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3"
aria-label="콘텐츠 로딩 중"
>
{[...Array(num)].map((_, index) => (
// eslint-disable-next-line react/no-array-index-key
<GatheringSkeleton key={index} />
))}
Comment on lines +13 to +16
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

배열 인덱스를 key로 사용하는 것은 피해야 합니다.

현재 구현에서는 배열 인덱스를 key로 사용하고 있는데, 이는 React의 재조정(reconciliation) 과정에서 문제를 일으킬 수 있습니다. 스켈레톤 아이템의 경우 정적이므로 큰 문제가 되지 않을 수 있으나, 더 안전한 방법을 사용하는 것이 좋습니다.

- {[...Array(num)].map((_, index) => (
-   // eslint-disable-next-line react/no-array-index-key
-   <GatheringSkeleton key={index} />
- ))}
+ {Array.from({ length: num }, (_, index) => (
+   <GatheringSkeleton key={`skeleton-${index}`} />
+ ))}

또한, Array.from()을 사용하면 스프레드 연산자를 사용하는 것보다 더 명확하고 효율적입니다.

📝 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.

Suggested change
{[...Array(num)].map((_, index) => (
// eslint-disable-next-line react/no-array-index-key
<GatheringSkeleton key={index} />
))}
{Array.from({ length: num }, (_, index) => (
<GatheringSkeleton key={`skeleton-${index}`} />
))}

</div>
);
}
16 changes: 16 additions & 0 deletions src/components/common/skeleton/gathering-skeleton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Skeleton } from '@mantine/core';

export default function GatheringSkeleton() {
return (
<div className="flex flex-col overflow-hidden rounded-xl">
<Skeleton className="h-[160px] w-full" />
<div className="relative flex min-h-[184px] flex-col gap-2 p-4">
<Skeleton className="h-4 w-40" />
<Skeleton className="h-4 w-32" />
<Skeleton className="h-4 w-24" />
<Skeleton circle className="absolute right-4 top-4 h-8 w-8" />
<Skeleton className="absolute bottom-4 left-4 right-4 h-10 w-auto" />
</div>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Skeleton } from '@mantine/core';
import MyGatheringSkeleton from '../my-gathering-skeleton';

interface MyGatheringSkeletonListProps {
num: number;
}

export default function MyGatheringSkeletonList({ num }: MyGatheringSkeletonListProps) {
return (
<div>
{[...Array(num)].map((_, index) => (
// eslint-disable-next-line react/no-array-index-key
<div key={index} className="md:flex">
Comment on lines +11 to +13
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

배열 생성 및 키 처리 방식 개선 필요

현재 구현에서 발견된 몇 가지 개선이 필요한 부분입니다:

  1. Array spread 대신 더 효율적인 방법을 사용할 수 있습니다.
  2. 인덱스를 키로 사용하는 것은 재정렬이나 필터링이 발생할 경우 문제가 될 수 있습니다.
-      {[...Array(num)].map((_, index) => (
-        // eslint-disable-next-line react/no-array-index-key
-        <div key={index} className="md:flex">
+      {Array.from({ length: num }, (_, index) => (
+        <div key={`skeleton-${index}`} className="md:flex">
📝 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.

Suggested change
{[...Array(num)].map((_, index) => (
// eslint-disable-next-line react/no-array-index-key
<div key={index} className="md:flex">
{Array.from({ length: num }, (_, index) => (
<div key={`skeleton-${index}`} className="md:flex">

<div className="w-1/6">
<div className="flex flex-col gap-2">
<Skeleton className="h-4 w-36" />
<Skeleton className="h-4 w-20" />
</div>
</div>
<div className="relative -mb-3.5 w-0.5 bg-gray-200">
<div className="md:corner-dot" />
</div>
<div className="flex-1 pb-6 md:pl-8">
<MyGatheringSkeleton />
</div>
</div>
))}
</div>
);
}
17 changes: 17 additions & 0 deletions src/components/common/skeleton/my-gathering-skeleton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Skeleton } from '@mantine/core';

export default function MyGatheringSkeleton() {
return (
<div className="flex gap-6 p-6">
<Skeleton className="h-28 w-28 rounded-xl md:h-32 md:w-32" />
<div className="relative flex flex-col gap-3">
<Skeleton className="h-4 w-40" />
<div className="flex gap-2">
<Skeleton className="h-4 w-32" />
<Skeleton className="h-4 w-24" />
</div>
<Skeleton className="absolute bottom-0 h-4 w-24" />
</div>
</div>
);
}
Comment on lines +1 to +17
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

스켈레톤 컴포넌트가 현재 미사용 상태입니다

검증 결과, MyGatheringSkeleton 컴포넌트는 정의된 파일(src/components/common/skeleton/my-gathering-skeleton/index.tsx) 외에 다른 곳에서 사용되지 않고 있습니다. 이는 다음 두 가지 가능성을 시사합니다:

  • 새로 추가된 컴포넌트로 아직 사용되지 않은 상태
  • 더 이상 필요하지 않은 미사용 컴포넌트

개발자의 의도에 따라 다음 조치가 필요합니다:

  • 새로운 기능을 위한 컴포넌트라면 사용 계획 확인
  • 불필요한 컴포넌트라면 제거 고려
🔗 Analysis chain

컴포넌트 사용 패턴 확인 필요

이 스켈레톤 컴포넌트가 다른 페이지들과 일관되게 사용되고 있는지 확인이 필요합니다.


Let me try different commands to gather the necessary information.


Let me try one more search with different commands to find the component usage.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 스켈레톤 컴포넌트의 사용 패턴 확인

# MyGatheringSkeleton 컴포넌트의 사용처 확인
echo "MyGatheringSkeleton 사용 현황:"
rg "MyGatheringSkeleton" --type tsx

# 다른 스켈레톤 컴포넌트들과의 일관성 확인
echo "\n다른 스켈레톤 컴포넌트 현황:"
fd --type f ".*skeleton.*\.tsx$" src/components

Length of output: 223


Script:

#!/bin/bash
# MyGatheringSkeleton 컴포넌트 사용처 확인
echo "MyGatheringSkeleton 사용 현황:"
rg "MyGatheringSkeleton" -t ts -t tsx

# 다른 스켈레톤 컴포넌트 검색
echo -e "\n스켈레톤 컴포넌트 파일 목록:"
find src/components -type f -name "*skeleton*.tsx"

# 스켈레톤 컴포넌트 임포트 패턴 확인
echo -e "\n스켈레톤 컴포넌트 임포트 패턴:"
rg "import.*Skeleton" -t ts -t tsx

# MyGatheringSkeleton 구현 확인
echo -e "\nMyGatheringSkeleton 구현 확인:"
ast-grep --pattern 'export default function MyGatheringSkeleton() { $$$ }'

Length of output: 1965


Script:

#!/bin/bash
# 전체 코드베이스에서 MyGatheringSkeleton 문자열 검색
echo "MyGatheringSkeleton 사용 현황:"
find . -type f -exec grep -l "MyGatheringSkeleton" {} \;

# 스켈레톤 관련 파일 검색 (대소문자 구분 없이)
echo -e "\n스켈레톤 관련 파일:"
find . -type f -iname "*skeleton*.tsx" -o -iname "*skeleton*.ts"

# Mantine Skeleton 임포트 검색
echo -e "\nMantine Skeleton 임포트:"
find . -type f -exec grep -l "@mantine/core.*Skeleton" {} \;

Length of output: 187

16 changes: 16 additions & 0 deletions src/components/common/skeleton/my-review-skeleton-list/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import MyReviewSkeleton from '../my-review-skeleton';

interface MyReviewSkeletonListProps {
num: number;
}

export default function MyReviewSkeletonList({ num }: MyReviewSkeletonListProps) {
return (
<div className="grid grid-cols-1 gap-6" aria-label="콘텐츠 로딩 중">
{[...Array(num)].map((_, index) => (
// eslint-disable-next-line react/no-array-index-key
<MyReviewSkeleton key={index} />
))}
</div>
);
}
Comment on lines +7 to +16
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

컴포넌트 구현에 대한 개선 제안

현재 구현에서 몇 가지 개선할 점이 있습니다:

  1. 배열 인덱스를 key로 사용하는 것은 React의 성능 최적화에 좋지 않을 수 있습니다.
  2. num prop에 대한 유효성 검사가 필요합니다.
  3. 배열 생성 로직을 더 명확하게 표현할 수 있습니다.

다음과 같이 개선해보세요:

 interface MyReviewSkeletonListProps {
   num: number;
 }

 export default function MyReviewSkeletonList({ num }: MyReviewSkeletonListProps) {
+  const skeletonCount = Math.max(0, Math.floor(num));
   return (
     <div className="grid grid-cols-1 gap-6" aria-label="콘텐츠 로딩 중">
-      {[...Array(num)].map((_, index) => (
-        // eslint-disable-next-line react/no-array-index-key
-        <MyReviewSkeleton key={index} />
+      {Array.from({ length: skeletonCount }, (_, index) => (
+        <MyReviewSkeleton key={`skeleton-${index}`} />
       ))}
     </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.

Suggested change
export default function MyReviewSkeletonList({ num }: MyReviewSkeletonListProps) {
return (
<div className="grid grid-cols-1 gap-6" aria-label="콘텐츠 로딩 중">
{[...Array(num)].map((_, index) => (
// eslint-disable-next-line react/no-array-index-key
<MyReviewSkeleton key={index} />
))}
</div>
);
}
interface MyReviewSkeletonListProps {
num: number;
}
export default function MyReviewSkeletonList({ num }: MyReviewSkeletonListProps) {
const skeletonCount = Math.max(0, Math.floor(num));
return (
<div className="grid grid-cols-1 gap-6" aria-label="콘텐츠 로딩 중">
{Array.from({ length: skeletonCount }, (_, index) => (
<MyReviewSkeleton key={`skeleton-${index}`} />
))}
</div>
);
}

16 changes: 16 additions & 0 deletions src/components/common/skeleton/my-review-skeleton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Skeleton } from '@mantine/core';

export default function MyReviewSkeleton() {
return (
<div className="flex flex-col">
<Skeleton className="h-6 w-32" />
<div className="relative flex flex-col gap-2 p-6">
<Skeleton className="mb-4 h-4 w-40" />
<Skeleton className="h-6 w-32" />
<Skeleton className="h-4 w-60" />
<Skeleton className="absolute bottom-6 h-4 w-20" />
<Skeleton className="absolute bottom-6 right-6 h-9 w-30" />
</div>
</div>
);
}
13 changes: 13 additions & 0 deletions src/components/common/skeleton/profile-skeleton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Skeleton } from '@mantine/core';

export default function ProfileSkeleton() {
return (
<div className="flex items-center gap-6.5" aria-label="콘텐츠 로딩 중">
<Skeleton circle className="h-28 w-28" />
<div className="flex flex-col gap-3">
<Skeleton className="h-6 w-40" />
<Skeleton className="h-4 w-36" />
</div>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import ReviewableReviewSkeleton from '../reviewable-review-skeleton';

interface ReviewableReviewSkeletonListProps {
num: number;
}

export default function ReviewableReviewSkeletonList({ num }: ReviewableReviewSkeletonListProps) {
return (
<div className="grid grid-cols-1 gap-12" aria-label="콘텐츠 로딩 중">
{[...Array(num)].map((_, index) => (
// eslint-disable-next-line react/no-array-index-key
<ReviewableReviewSkeleton key={index} />
))}
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Skeleton } from '@mantine/core';

export default function ReviewableReviewSkeleton() {
return (
<div className="flex gap-5">
<Skeleton className="h-[166px] w-[230px] rounded-xl" />
<div className="relative flex flex-1 flex-col gap-4">
<Skeleton className="h-4 w-40" />
<Skeleton className="h-4 w-20" />
<Skeleton className="absolute bottom-0 h-4 w-28" />
<Skeleton className="absolute bottom-0 right-0 h-10 w-28 rounded-xl" />
</div>
</div>
);
}
Loading
Loading