Skip to content

Commit

Permalink
feat: #309 스켈레톤 UI 개발 및 적용
Browse files Browse the repository at this point in the history
스켈레톤 UI 개발 및 적용
  • Loading branch information
bomi8489 authored Jul 14, 2024
2 parents 7c60506 + 480762a commit 2424a7f
Show file tree
Hide file tree
Showing 7 changed files with 197 additions and 82 deletions.
43 changes: 23 additions & 20 deletions src/app/(routes)/space/[spaceId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Button from '@/components/common/Button/Button'
import DeferredComponent from '@/components/common/DeferedComponent/DeferedComponent'
import useViewLink from '@/components/common/LinkList/hooks/useViewLink'
import Space from '@/components/common/Space/Space'
import SpaceSkeleton from '@/components/common/Space/SpaceSkeleton'
import useGetSpace from '@/components/common/Space/hooks/useGetSpace'
import useGetTags from '@/components/common/Space/hooks/useGetTags'
import Tab from '@/components/common/Tab/Tab'
Expand Down Expand Up @@ -36,27 +37,29 @@ const SpacePage = ({ params }: { params: { spaceId: number } }) => {
})
const { tag, tagIndex, handleTagChange } = useTagParam({ tags })

return isSpaceLoading || isTagsLoading ? (
<DeferredComponent>
<Spinner />
</DeferredComponent>
) : (
return (
<>
{space && (
<Space
type="Header"
userName={space.memberDetailInfos[0].nickname}
spaceId={space.spaceId}
spaceName={space.spaceName}
spaceImage={space.spaceImagePath}
description={space.description}
category={CATEGORIES_RENDER[space.category]}
scrap={space.scrapCount}
favorite={space.favoriteCount}
hasFavorite={space.hasFavorite}
hasScrap={space.hasScrap}
isVisible={space.isVisible}
/>
{isSpaceLoading ? (
<DeferredComponent>
<SpaceSkeleton />
</DeferredComponent>
) : (
space && (
<Space
type="Header"
userName={space.memberDetailInfos[0].nickname}
spaceId={space.spaceId}
spaceName={space.spaceName}
spaceImage={space.spaceImagePath}
description={space.description}
category={CATEGORIES_RENDER[space.category]}
scrap={space.scrapCount}
favorite={space.favoriteCount}
hasFavorite={space.hasFavorite}
hasScrap={space.hasScrap}
isVisible={space.isVisible}
/>
)
)}
{tabList.length > MIN_TAB_NUMBER && (
<Tab>
Expand Down
119 changes: 59 additions & 60 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { CategoryList, Dropdown, LinkItem, Spinner } from '@/components'
import FloatingButton from '@/components/FloatingButton/FloatingButton'
import { ChipColors } from '@/components/common/Chip/Chip'
import DeferredComponent from '@/components/common/DeferedComponent/DeferedComponent'
import LinkItemSkeleton from '@/components/common/LinkItem/LinkItemSkeleton'
import MainSpaceList from '@/components/common/MainSpaceList/MainSpaceList'
import { useCategoryParam, useSortParam } from '@/hooks'
import useGetPopularLinks from '@/hooks/useGetPopularLinks'
Expand All @@ -23,67 +24,65 @@ export default function Home() {

return (
<>
{isPopularLinksLoading ? (
<DeferredComponent>
<Spinner />
</DeferredComponent>
) : (
<>
<section className="px-4 pb-8">
<h2 className="py-4 font-bold text-gray9">인기있는 링크</h2>
{links && (
<Swiper
slidesPerView={2.1}
spaceBetween={16}
freeMode={true}
pagination={{
clickable: true,
}}
modules={[FreeMode]}
className="mySwiper">
{links.map((link: PopularLinkResBody) => (
<SwiperSlide key={link.linkId}>
<LinkItem
linkId={link.linkId}
title={link.title}
url={link.url}
tagName={link.tagName}
tagColor={link.tagColor as ChipColors}
isInitLiked={link.isLiked}
likeInitCount={link.likeCount}
type="card"
/>
</SwiperSlide>
))}
</Swiper>
)}
</section>
<section>
<div className="sticky top-[53px] z-40 bg-bgColor">
<div className="flex items-center justify-between px-4 pt-2">
<h2 className="font-bold text-gray9">스페이스 모음</h2>
<Dropdown
type="space"
placement="right"
defaultIndex={sortIndex}
onChange={handleSortChange}
/>
</div>
<CategoryList
type="all"
defaultIndex={categoryIndex}
onChange={handleCategoryChange}
/>
</div>
<MainSpaceList
queryKey="main"
sort={sort ?? ''}
category={category ?? ''}
fetchFn={fetchGetSpaces}
<section className="px-4 pb-8">
<h2 className="py-4 font-bold text-gray9">인기있는 링크</h2>
{isPopularLinksLoading ? (
<DeferredComponent>
<LinkItemSkeleton type="card" />
</DeferredComponent>
) : (
links && (
<Swiper
slidesPerView={2.1}
spaceBetween={16}
freeMode={true}
pagination={{
clickable: true,
}}
modules={[FreeMode]}
className="mySwiper">
{links.map((link: PopularLinkResBody) => (
<SwiperSlide key={link.linkId}>
<LinkItem
linkId={link.linkId}
title={link.title}
url={link.url}
tagName={link.tagName}
tagColor={link.tagColor as ChipColors}
isInitLiked={link.isLiked}
likeInitCount={link.likeCount}
type="card"
/>
</SwiperSlide>
))}
</Swiper>
)
)}
</section>
<section>
<div className="sticky top-[53px] z-40 bg-bgColor">
<div className="flex items-center justify-between px-4 pt-2">
<h2 className="font-bold text-gray9">스페이스 모음</h2>
<Dropdown
type="space"
placement="right"
defaultIndex={sortIndex}
onChange={handleSortChange}
/>
</section>
</>
)}
</div>
<CategoryList
type="all"
defaultIndex={categoryIndex}
onChange={handleCategoryChange}
/>
</div>
<MainSpaceList
queryKey="main"
sort={sort ?? ''}
category={category ?? ''}
fetchFn={fetchGetSpaces}
/>
</section>
<FloatingButton />
</>
)
Expand Down
36 changes: 36 additions & 0 deletions src/components/common/LinkItem/LinkItemSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Skeleton from '../Skeleton/Skeleton'

export interface LinkItemSkeletonProps {
type?: 'list' | 'card'
}

const LinkItemSkeleton = ({ type }: LinkItemSkeletonProps) => {
return (
<>
{type === 'list' ? (
<div className="flex items-center justify-between gap-2 border-t border-slate3 px-3 py-2 last:border-b">
<Skeleton className="h-5 w-3/4" />
</div>
) : (
<div className="flex">
<div className="mr-4 flex min-h-[101.5px] w-[214.47px] flex-col justify-between gap-1 rounded-md border border-slate3 px-3 py-2.5">
<Skeleton className="h-5 w-4/5" />
<Skeleton className="h-5 w-10" />
<div className="flex items-center justify-end">
<Skeleton className="h-5 w-10" />
</div>
</div>
<div className="mr-4 flex min-h-[101.5px] w-[214.47px] flex-col justify-between gap-1 rounded-md border border-slate3 px-3 py-2.5">
<Skeleton className="h-5 w-4/5" />
<Skeleton className="h-5 w-10" />
<div className="flex items-center justify-end">
<Skeleton className="h-5 w-10" />
</div>
</div>
</div>
)}
</>
)
}

export default LinkItemSkeleton
4 changes: 2 additions & 2 deletions src/components/common/MainSpaceList/MainSpaceList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import useMainSpacesQuery from '@/components/SpaceList/hooks/useMainSpacesQuery'
import { CATEGORIES_RENDER } from '@/constants'
import useInfiniteScroll from '@/hooks/useInfiniteScroll'
import { SearchSpaceReqBody, SpaceResBody } from '@/types'
import { Spinner } from '../..'
import DeferredComponent from '../DeferedComponent/DeferedComponent'
import Space from '../Space/Space'
import MainSpaceSkeleton from './MainSpaceSkeleton'

export interface SpaceListProps {
memberId?: number
Expand Down Expand Up @@ -50,7 +50,7 @@ const MainSpaceList = ({

return isSpacesLoading ? (
<DeferredComponent>
<Spinner />
<MainSpaceSkeleton />
</DeferredComponent>
) : (
<>
Expand Down
25 changes: 25 additions & 0 deletions src/components/common/MainSpaceList/MainSpaceSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import SpaceSkeleton from '../Space/SpaceSkeleton'

const MainSpaceSkeleton = () => {
return (
<ul className="flex flex-col gap-y-2 px-4 pt-2">
<li>
<SpaceSkeleton type="Card" />
</li>
<li>
<SpaceSkeleton type="Card" />
</li>
<li>
<SpaceSkeleton type="Card" />
</li>
<li>
<SpaceSkeleton type="Card" />
</li>
<li>
<SpaceSkeleton type="Card" />
</li>
</ul>
)
}

export default MainSpaceSkeleton
14 changes: 14 additions & 0 deletions src/components/common/Skeleton/Skeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
interface SkeletonProps {
className?: string
}

const Skeleton = ({ className }: SkeletonProps) => {
return (
<div
className={
className + ' rounded-xl bg-slate-100 dark:bg-slate-800 '
}></div>
)
}

export default Skeleton
38 changes: 38 additions & 0 deletions src/components/common/Space/SpaceSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import Skeleton from '../Skeleton/Skeleton'

interface SpaceSkeletonProps {
type?: 'Card' | 'Header'
}

const SpaceSkeleton = ({ type }: SpaceSkeletonProps) => {
return (
<>
{type === 'Card' ? (
<div className="relative flex gap-3 rounded-md border border-slate3 p-2">
<div className="flex grow flex-col justify-center gap-1 rounded-md bg-white bg-opacity-60 px-3 py-1.5 dark:bg-gray-900 dark:bg-opacity-60">
<Skeleton className="h-5 w-1/2" />
<Skeleton className="h-5 w-1/2" />
<div className="flex justify-between">
<Skeleton className="h-5 w-20" />
<Skeleton className="h-5 w-20" />
</div>
</div>
</div>
) : (
<div className="relative flex flex-col gap-10 rounded-md border border-slate3 p-4">
<div className="flex justify-end gap-2">
<Skeleton className="h-5 w-20" />
<Skeleton className="h-5 w-20" />
</div>
<div className="flex flex-col gap-1.5 rounded-md border border-slate3 bg-white bg-opacity-60 px-3 py-1.5 dark:bg-gray-900 dark:bg-opacity-60">
<Skeleton className="h-5 w-1/2" />
<Skeleton className="h-4 w-1/3" />
<Skeleton className="h-5 w-20" />
</div>
</div>
)}
</>
)
}

export default SpaceSkeleton

0 comments on commit 2424a7f

Please sign in to comment.