Skip to content
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

Feat/유저 토너먼트 전적 페이지 우승자 스와이퍼 슬라이드 mock api #1088 #1099

Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 0 additions & 59 deletions components/tournament-record/WinnerSwipeView.tsx

This file was deleted.

87 changes: 87 additions & 0 deletions components/tournament-record/WinnerSwiper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import Image from 'next/image';
import React, { useMemo, useCallback } from 'react';
import { EffectCoverflow } from 'swiper/modules';
import { Swiper, SwiperSlide, SwiperClass } from 'swiper/react';
import { TournamentData } from 'types/tournamentTypes';
import { InfiniteScroll } from 'utils/infinityScroll';
import { mockInstance } from 'utils/mockAxios';
import styles from 'styles/tournament-record/WinnerSwiper.module.scss';
import 'swiper/css';
import 'swiper/css/effect-coverflow';

interface WinnerSwiperProps {
type: 'ROOKIE' | 'MASTER' | 'CUSTOM';
}

export default function WinnerSwiper(props: WinnerSwiperProps) {
const fetchTournamentData = useCallback(
async (page: number) => {
console.log('Fetching more data...');
const res = await mockInstance.get(
`/tournament?page=${page}&type=${props.type}&size=5`
);
return res.data;
},
[props.type]
);

// TODO: error, isLoading 시 return 컴포넌트
const { data, error, isLoading, hasNextPage, fetchNextPage } =
InfiniteScroll<TournamentData>(
'tournamentData',
fetchTournamentData,
'JC01'
);

const coverflowEffect = useMemo(
() => ({
rotate: 30,
stretch: 0,
depth: 500,
slideShadows: true,
}),
[]
);

const indexChangeHandler = useCallback(
(swiper: SwiperClass) => {
const slidesLength = swiper.slides.length;
console.log('slide length: ' + slidesLength);
if (hasNextPage && swiper.activeIndex >= slidesLength - 3) {
fetchNextPage();
}
},
[hasNextPage, fetchNextPage]
);

return (
<Swiper
className={styles.swiper}
slidesPerView={2.6}
effect={'coverflow'}
centeredSlides={true}
coverflowEffect={coverflowEffect}
modules={[EffectCoverflow]}
onActiveIndexChange={indexChangeHandler}
>
{data?.pages.map((page, pageIndex) => (
<React.Fragment key={pageIndex}>
{page.tournaments.length > 0 &&
page.tournaments.map((tournament) => (
<SwiperSlide key={tournament.tournamentId}>
<div className={styles.swiperSlide}>
<Image
src={tournament.winnerImageUrl}
fill={true}
style={{ objectFit: 'cover' }}
alt={tournament.winnerIntraId}
priority={true}
/>
</div>
</SwiperSlide>
))}
</React.Fragment>
))}
</Swiper>
);
}
7 changes: 6 additions & 1 deletion components/tournament/TournamentCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ export default function TournamentCard({
contents,
status,
type,
winnerUser,
startTime,
endTime,
winnerIntraId,
winnerImageUrl,
player_cnt,
}: TournamentInfo) {
const setModal = useSetRecoilState<Modal>(modalState);

Expand All @@ -27,6 +29,9 @@ export default function TournamentCard({
status: status,
type: type,
endTime: endTime,
winnerIntraId: winnerIntraId,
winnerImageUrl: winnerImageUrl,
player_cnt: player_cnt,
},
});
};
Expand Down
64 changes: 64 additions & 0 deletions pages/api/pingpong/tournament/dummyTournamentData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { TournamentInfo } from 'types/tournamentTypes';

const jincpark = {
intraId: 'jincpark',
imageUrl:
'https://42gg-public-image.s3.ap-northeast-2.amazonaws.com/images/jincpark.jpeg',
};

const jaehyuki = {
intraId: 'jaehyuki',
imageUrl:
'https://42gg-public-image.s3.ap-northeast-2.amazonaws.com/images/jaehyuki-7f6689c3-bf24-4e87-a04b-de9d61f1bef8.jpeg',
};

const junhjeon = {
intraId: 'junhjeon',
imageUrl:
'https://42gg-public-image.s3.ap-northeast-2.amazonaws.com/images/junhjeon.jpeg',
};

const users = [jincpark, jaehyuki, junhjeon];

const dummyTournaments: TournamentInfo[] = [];

for (let i = 28; i >= 1; i--) {
let status;
if (i === 28) {
status = '예정';
} else if (i === 27) {
status = '진행중';
} else {
status = '종료';
}

const rookieTournament: TournamentInfo = {
tournamentId: i * 2,
title: `${i}회 루키 토너먼트`,
contents: '블라블라',
startTime: new Date(),
endTime: new Date(),
status: status,
type: 'ROOKIE',
winnerIntraId: users[i % 3].intraId,
winnerImageUrl: users[i % 3].imageUrl,
player_cnt: 8,
};

const masterTournament: TournamentInfo = {
tournamentId: i * 2 - 1,
title: `${i}회 마스터 토너먼트`,
contents: '블라블라',
startTime: new Date(),
endTime: new Date(),
status: status,
type: 'MASTER',
winnerIntraId: users[i % 3].intraId,
winnerImageUrl: users[i % 3].imageUrl,
player_cnt: 8,
};

dummyTournaments.push(masterTournament, rookieTournament);
}

export default dummyTournaments;
51 changes: 51 additions & 0 deletions pages/api/pingpong/tournament/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { NextApiRequest, NextApiResponse } from 'next';
import dummyTournaments from './dummyTournamentData';

export default function handler(req: NextApiRequest, res: NextApiResponse) {
const { page, type, status, size } = req.query as {
page: string;
type: string;
status: string;
size: string;
};

if (!page) {
res.status(404).end('You must put page!!');
return;
}

let filteredTournaments = dummyTournaments;
if (type || status) {
filteredTournaments = dummyTournaments.filter((tournament) => {
return (
(!type || tournament.type === type) &&
(!status || tournament.status === status)
);
});
}

let sizeInt = 20;
if (size) {
sizeInt = parseInt(size);
}

// 소수점이 있을 경우 올림
const totalPage = Math.ceil(filteredTournaments.length / sizeInt);

if (parseInt(page) > totalPage) {
res.status(404).end('Page number exceeded');
return;
}

// page와 size에 맞게 slice
const startIndex = (parseInt(page) - 1) * sizeInt;
filteredTournaments = filteredTournaments.slice(
startIndex,
startIndex + sizeInt
);

res.status(200).json({
tournaments: filteredTournaments,
totalPage: totalPage,
});
}
Loading