Skip to content

Commit

Permalink
Merge pull request #99 from sprint-military-9team/feat#98-skeleton
Browse files Browse the repository at this point in the history
Feat#98 skeleton컴포넌트
  • Loading branch information
zoonyoung authored Apr 28, 2024
2 parents bc8bbce + 5cbb261 commit 3cca204
Show file tree
Hide file tree
Showing 8 changed files with 248 additions and 81 deletions.
5 changes: 5 additions & 0 deletions src/app/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import LoadingSpinner from '@/components/shopinfoPage/LoadingSpinner';

export default function Loading() {
return <LoadingSpinner />;
}
41 changes: 23 additions & 18 deletions src/components/announcelist/Announce/Announce.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Link from 'next/link';
import Pagination from './Pagination';
import styles from './announce.module.scss';
import { Data, MainData, SortButtonProps, SortListProps, FilterButtonProps, FilterInfo } from './type';
import CardListSkeleton from '../SuggestCard/skeleton/CardListSkeleton';

interface AnnounceProps {
headerData: string | null;
Expand Down Expand Up @@ -133,24 +134,28 @@ function Announce({ headerData }: AnnounceProps) {
)}
</div>
</div>
<div className={styles.cardWrapper}>
{cardData?.items.map((data: MainData) => (
<Card
key={data?.item.id}
image={data?.item.shop.item.imageUrl}
title={data?.item.shop.item.name}
startTime={data?.item.startsAt}
workHour={data?.item.workhour}
location={data?.item.shop.item.address1}
salary={`${data?.item.hourlyPay}`}
raise={data ? raisePercent(data.item.hourlyPay, data.item.shop.item.originalHourlyPay) : 0}
isRaised={data?.item.hourlyPay > data?.item.shop.item.originalHourlyPay}
completed={data?.item.closed ? '모집 완료' : today > new Date(data?.item.startsAt) ? '지난 공고' : ''}
shopId={data.item.shop.item.id}
noticeId={data.item.id}
/>
))}
</div>
{cardData ? (
<div className={styles.cardWrapper}>
{cardData?.items.map((data: MainData) => (
<Card
key={data?.item.id}
image={data?.item.shop.item.imageUrl}
title={data?.item.shop.item.name}
startTime={data?.item.startsAt}
workHour={data?.item.workhour}
location={data?.item.shop.item.address1}
salary={`${data?.item.hourlyPay}`}
raise={data ? raisePercent(data.item.hourlyPay, data.item.shop.item.originalHourlyPay) : 0}
isRaised={data?.item.hourlyPay > data?.item.shop.item.originalHourlyPay}
completed={data?.item.closed ? '모집 완료' : today > new Date(data?.item.startsAt) ? '지난 공고' : ''}
shopId={data.item.shop.item.id}
noticeId={data.item.id}
/>
))}
</div>
) : (
<CardListSkeleton title="" length={6} />
)}
</div>
<div className={styles.paginate}>
<Pagination
Expand Down
92 changes: 49 additions & 43 deletions src/components/announcelist/SuggestCard/SuggestCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,36 +13,40 @@ import 'slick-carousel/slick/slick.css';
import 'slick-carousel/slick/slick-theme.css';
import styles from './suggest.module.scss';
import { Data, MainData } from './type';
import CardListSkeleton from './skeleton/CardListSkeleton';

const SLICK_SETTINGS = {
dots: false,
infinite: true,
slidesToShow: 3,
slidesToScroll: 1,
autoplay: true,
arrows: false,
initialSlide: 0,
autoplaySpeed: 3000,
speed: 500,
responsive: [
{
breakpoint: 1024,
settings: {
slidesToShow: 2,
},
},
],
};

function SuggestCard() {
const [data, setData] = useState<Data | null>(null);
const [isLoading, setIsLoading] = useState(true);
const [userResidence, setUserResidence] = useState<string | null>();
const today = new Date();

const suggestData = data?.items
.filter((cardData) => !cardData.item.closed && today <= new Date(cardData.item.startsAt))
.slice(0, 30);

const len = suggestData?.length;

const settings = {
dots: false,
infinite: true,
slidesToShow: 3,
slidesToScroll: 1,
autoplay: true,
arrows: false,
initialSlide: 0,
autoplaySpeed: 3000,
speed: 500,
responsive: [
{
breakpoint: 1024,
settings: {
slidesToShow: 2,
},
},
],
};
const userId = Cookies.get('userId');
const token = Cookies.get('token');

Expand All @@ -61,6 +65,7 @@ function SuggestCard() {
}
}, [userId, token]);
useEffect(() => {
setIsLoading(true);
if (token && userResidence) {
const fetchData = async () => {
const response = await getAnnounceData(0, 100, CLOSELOCATIONLIST[userResidence], null, null, null, 'pay');
Expand All @@ -74,34 +79,35 @@ function SuggestCard() {
};
fetchData();
}
setIsLoading(false);
}, [userResidence]);

if (isLoading) return <CardListSkeleton title="맞춤 공고" length={3} />;

return (
<section className={styles.sectionWrapper}>
{len >= 3 ? (
<>
<p className={styles.title}>맞춤 공고</p>
<Slider {...settings} className={styles.cardWrapper}>
{suggestData?.map((cardData: MainData) => (
<Card
key={cardData?.item.id}
image={cardData?.item.shop.item.imageUrl}
title={cardData?.item.shop.item.name}
startTime={cardData?.item.startsAt}
workHour={cardData?.item.workhour}
location={cardData?.item.shop.item.address1}
salary={`${cardData?.item.hourlyPay}`}
raise={cardData ? raisePercent(cardData.item.hourlyPay, cardData.item.shop.item.originalHourlyPay) : 0}
isRaised={cardData?.item.hourlyPay > cardData?.item.shop.item.originalHourlyPay}
completed={
cardData?.item.closed ? '모집 완료' : today > new Date(cardData?.item.startsAt) ? '지난 공고' : ''
}
shopId={cardData.item.shop.item.id}
noticeId={cardData.item.id}
/>
))}
</Slider>
</>
<p className={styles.title}>맞춤 공고</p>
{suggestData?.length > 3 ? (
<Slider {...SLICK_SETTINGS} className={styles.cardWrapper}>
{suggestData?.map((cardData: MainData) => (
<Card
key={cardData?.item.id}
image={cardData?.item.shop.item.imageUrl}
title={cardData?.item.shop.item.name}
startTime={cardData?.item.startsAt}
workHour={cardData?.item.workhour}
location={cardData?.item.shop.item.address1}
salary={`${cardData?.item.hourlyPay}`}
raise={cardData ? raisePercent(cardData.item.hourlyPay, cardData.item.shop.item.originalHourlyPay) : 0}
isRaised={cardData?.item.hourlyPay > cardData?.item.shop.item.originalHourlyPay}
completed={
cardData?.item.closed ? '모집 완료' : today > new Date(cardData?.item.startsAt) ? '지난 공고' : ''
}
shopId={cardData.item.shop.item.id}
noticeId={cardData.item.id}
/>
))}
</Slider>
) : (
<div className={styles.alertWrapper}>
<span className={styles.title}>선호지역 근처 공고가 없습니다</span>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
@import '@/styles/_index';
@import '@/styles/_media';

.sectionWrapper {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 3.2rem;
}

.title {
color: $black;
font-family: 'Spoqa Han Sans Neo';
font-size: 2.8rem;
font-style: normal;
font-weight: 700;
line-height: normal;
letter-spacing: 0.056rem;
margin-left: 0.3rem;
}

.cardWrapper {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
width: 98rem;
position: relative;
gap: 1.4rem;
}

@include media(tablet) {
.cardWrapper {
width: 66.6rem;
}
}

@include media(mobile) {
.cardWrapper {
width: 37.1rem;
grid-template-columns: 1fr 1fr;
}

.cardWrapper>*:nth-child(n + 3) {
display: none;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Card from './CardSkeleton';
import styles from './CardListSkeleton.module.scss';

export default function CardListSkeleton({ title, length }: { title: string; length: number }) {
const dataList = [];
for (let i = 0; i < length; i += 1) {
dataList.push(i);
}
return (
<section className={styles.sectionWrapper}>
{title && <p className={styles.title}>{title}</p>}
<div className={styles.cardWrapper}>
{dataList.map((data) => (
<Card key={data} />
))}
</div>
</section>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
@use '@/styles/color' as c;
@use '@/styles/mixins' as m;
@use '@/styles/media' as r;

@mixin common {
display: flex;
flex-direction: column;
align-items: flex-start;
}

.cardWrapper {
padding: 1.6rem;
width: 31.2rem;
min-width: 31.2rem;
height: 34.8rem;
min-height: 34.8rem;
gap: 2.4rem;
border-radius: 1.2rem;
border: 0.1rem solid c.$gray-300;
background: c.$white;
cursor: pointer;

@include r.media('mobile') {
padding: 1.2rem;
width: 17.1rem;
height: 26rem;
min-width: 17.1rem;
min-height: 26rem;
gap: 1.2rem;
}
}

.imageWrapper {
position: relative;
width: 100%;
height: 16rem;
overflow: hidden;
border-radius: 1.2rem;
background: c.$gray-200;

@include r.media('mobile') {
max-height: 9.1rem;
}
}

.contentWrapper {
width: 100%;
height: 1.6rem;
}

.title {
margin-top: 2rem;
background: c.$gray-200;
width: 12rem;
height: 3rem;
@include m.rounded-lg;
}

.location {
margin-top: 1rem;
background: c.$gray-200;
width: 8rem;
height: 1.6rem;
@include m.rounded-lg;
}

.time {
margin-top: 1rem;
background: c.$gray-200;
width: 100%;
height: 1.6rem;
@include m.rounded-lg;
}

.salary {
margin-top: 1rem;
background: c.$gray-200;
width: 13rem;
height: 3rem;
@include m.rounded-lg;
}
16 changes: 16 additions & 0 deletions src/components/announcelist/SuggestCard/skeleton/CardSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import styles from './CardSkeleton.module.scss';

function Card() {
return (
<div className={styles.cardWrapper}>
<div className={styles.imageWrapper} />
<div className={styles.contentWrapper}>
<div className={styles.title} />
<div className={styles.time} />
<div className={styles.location} />
<div className={styles.salary} />
</div>
</div>
);
}
export default Card;
Loading

0 comments on commit 3cca204

Please sign in to comment.