Skip to content

Commit

Permalink
Feat: 인기여행지 리스트 스켈레톤 적용
Browse files Browse the repository at this point in the history
  • Loading branch information
suehub committed Jan 5, 2024
1 parent 293f0f9 commit 8e8f5ef
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 26 deletions.
16 changes: 16 additions & 0 deletions src/components/Tours/ToursItemSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const ToursItemSkeleton = () => {
return (
<div className="flex-col">
<div className="relative">
<div className="rounded-1 h-[134px] max-h-[134px] w-[178px] animate-pulse rounded-[16px] bg-gray-300"></div>
</div>
<p className="headline1 mt-2 h-6 animate-pulse rounded bg-gray-300"></p>
<div className="caption1 ml-[2px] mt-2 flex space-x-2">
<div className="h-4 w-1/3 animate-pulse rounded bg-gray-300"></div>
<div className="h-4 w-1/4 animate-pulse rounded bg-gray-300"></div>
</div>
</div>
);
};

export default ToursItemSkeleton;
75 changes: 49 additions & 26 deletions src/components/Tours/ToursList.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,40 @@
import { TourType, ToursListProps } from '@/@types/tours.types';
import ToursItem from './ToursItem';
import { getTours } from '@api/tours';
import { useInfiniteQuery } from '@tanstack/react-query';
import React, { useEffect, useState } from 'react';
import InfiniteScroll from 'react-infinite-scroller';
import React from 'react';
import { v4 as uuidv4 } from 'uuid';
import ToursItem from './ToursItem';
import ToursItemSkeleton from './ToursItemSkeleton';

const ToursList = ({ selectedRegion }: ToursListProps) => {
const { fetchNextPage, hasNextPage, data, error } = useInfiniteQuery({
queryKey: ['tours', selectedRegion],
queryFn: ({ pageParam = 0 }) => getTours(selectedRegion, pageParam, 10),
initialPageParam: 0,
getNextPageParam: (lastPage) => {
const currentPage = lastPage?.data.data.pageable.pageNumber;
const totalPages = lastPage?.data.data.totalPages;

if (currentPage < totalPages - 1) {
return currentPage + 1;
}

return undefined;
},
});
const { fetchNextPage, hasNextPage, data, isLoading, error } =
useInfiniteQuery({
queryKey: ['tours', selectedRegion],
queryFn: ({ pageParam = 0 }) => getTours(selectedRegion, pageParam, 10),
initialPageParam: 0,
getNextPageParam: (lastPage) => {
const currentPage = lastPage?.data.data.pageable.pageNumber;
const totalPages = lastPage?.data.data.totalPages;

if (currentPage < totalPages - 1) {
return currentPage + 1;
}

return undefined;
},
});

const [showSkeleton, setShowSkeleton] = useState(isLoading);

useEffect(() => {
if (isLoading) {
setShowSkeleton(true);
} else {
const timer = setTimeout(() => setShowSkeleton(false), 200);
return () => clearTimeout(timer);
}
}, [isLoading]);

if (error) {
return <div>데이터를 불러오는 중 오류가 발생했습니다.</div>;
Expand All @@ -32,18 +46,27 @@ const ToursList = ({ selectedRegion }: ToursListProps) => {
loadMore={() => fetchNextPage()}
hasMore={hasNextPage}
loader={
<div className="loader" key={0}>
Loading ...
<div key={uuidv4()} className="flex justify-center">
<div
className="z-[105] mx-auto mt-10 h-8 w-8 animate-spin rounded-full border-[3px] border-solid border-current border-t-transparent text-[blue-600] dark:text-[#28d8ff]"
role="status"
aria-label="loading">
<div className="sr-only">Loading...</div>
</div>
</div>
}>
<div className="no-scrollbar grid grid-cols-2 gap-[15px] overflow-y-scroll">
{data?.pages.map((group, index) => (
<React.Fragment key={index}>
{group?.data.data.content.map((tour: TourType) => (
<ToursItem key={tour.id} tour={tour} />
<div className="no-scrollbar grid min-h-[500px] grid-cols-2 gap-[15px] overflow-y-scroll">
{showSkeleton
? Array.from({ length: 10 }, (_, index) => (
<ToursItemSkeleton key={index} />
))
: data?.pages.map((group) => (
<React.Fragment key={uuidv4()}>
{group?.data.data.content.map((tour: TourType) => (
<ToursItem key={uuidv4()} tour={tour} />
))}
</React.Fragment>
))}
</React.Fragment>
))}
</div>
</InfiniteScroll>
);
Expand Down

0 comments on commit 8e8f5ef

Please sign in to comment.