Skip to content

Commit

Permalink
Merge pull request #1238 from 42organization/main
Browse files Browse the repository at this point in the history
deploy
  • Loading branch information
greatSweetMango authored Jan 5, 2024
2 parents 8ca9a7a + 127ea32 commit 554e915
Show file tree
Hide file tree
Showing 16 changed files with 158 additions and 196 deletions.
5 changes: 5 additions & 0 deletions components/UI/LoadingSpinner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import styles from 'styles/UI/LoadingSpinner.module.scss';

export default function LoadingSpinner() {
return <div className={styles.loadingAnimation} />;
}
5 changes: 1 addition & 4 deletions components/modal/profile/EditProfileModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,7 @@ export default function EditProfileModal() {
<div className={styles.snsWrap}>
<div
className={`${styles.snsButton} ${slack ? styles.snsClicked : ''}`}
onClick={
() =>
alert('슬랙 알림은 현재 준비중입니다.') /* setSlack(!slack) */
}
onClick={() => setSlack(!slack)}
>
Slack
</div>
Expand Down
2 changes: 1 addition & 1 deletion components/rank/RankList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default function RankList({ season }: RankListProps) {
const makePath = (): string => {
const modeQuery = Mode === 'RANK' ? 'ranks/single' : 'exp';
const seasonQuery = Mode === 'RANK' ? `&season=${season}` : '';
return `pingpong/${modeQuery}?page=${page}&size=20${seasonQuery}`;
return `pingpong/v2/${modeQuery}?page=${page}&size=20${seasonQuery}`;
};

useRankList({
Expand Down
61 changes: 15 additions & 46 deletions components/tournament-record/WinnerSwiper.tsx
Original file line number Diff line number Diff line change
@@ -1,53 +1,32 @@
import React, {
useMemo,
useCallback,
SetStateAction,
forwardRef,
Ref,
} from 'react';
import React, { useMemo, SetStateAction, forwardRef, Ref } from 'react';
import { InfiniteData } from 'react-query';
import { EffectCoverflow } from 'swiper/modules';
import { Swiper, SwiperSlide, SwiperClass, SwiperRef } from 'swiper/react';
import { TournamentData, TournamentInfo } from 'types/tournamentTypes';
import { instance } from 'utils/axios';
import { InfiniteScroll } from 'utils/infinityScroll';
import { Swiper, SwiperSlide, SwiperRef, SwiperClass } from 'swiper/react';
import { TournamentInfo, TournamentData } from 'types/tournamentTypes';
import styles from 'styles/tournament-record/WinnerSwiper.module.scss';
import 'swiper/css';
import 'swiper/css/effect-coverflow';
import WinnerProfileImage from './WinnerProfileImage';

interface WinnerSwiperProps {
tournamentData: InfiniteData<TournamentData> | undefined;
type: string;
size: number;
setTournamentInfo: React.Dispatch<SetStateAction<TournamentInfo | undefined>>;
setIsEmpty: React.Dispatch<SetStateAction<boolean>>;
onIndexChange: (swiper: SwiperClass) => void;
}

const WinnerSwiper = forwardRef(
(
{ type, size, setTournamentInfo, setIsEmpty }: WinnerSwiperProps,
{
tournamentData,
type,
size,
setTournamentInfo,
onIndexChange,
}: WinnerSwiperProps,
ref: Ref<SwiperRef> | undefined
) => {
const fetchTournamentData = useCallback(
async (page: number) => {
const res = await instance.get(
`/pingpong/tournaments?page=${page}&type=${type}&size=${size}&status=END`
);
if (res.data.totalPage === 0) {
setIsEmpty(true);
} else {
setIsEmpty(false);
}
return res.data;
},
[type, size, setIsEmpty]
);

const { data, hasNextPage, fetchNextPage } = InfiniteScroll<TournamentData>(
['tournamentData', type],
fetchTournamentData,
'JC01'
);

const coverflowEffect = useMemo(
() => ({
rotate: 35,
Expand All @@ -58,16 +37,6 @@ const WinnerSwiper = forwardRef(
[]
);

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

return (
<Swiper
className={styles.swiper}
Expand All @@ -76,10 +45,10 @@ const WinnerSwiper = forwardRef(
centeredSlides={true}
coverflowEffect={coverflowEffect}
modules={[EffectCoverflow]}
onActiveIndexChange={indexChangeHandler}
onActiveIndexChange={onIndexChange}
ref={ref}
>
{data?.pages.map((page, pageIndex) => (
{tournamentData?.pages.map((page, pageIndex) => (
<React.Fragment key={pageIndex}>
{page.tournaments.length > 0 &&
page.tournaments.map((tournament, index) => (
Expand Down
2 changes: 1 addition & 1 deletion components/tournament-record/WinnerTournamentInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default function WinnerTournamentInfo({
return (
<div className={styles.winnerInfoContainer}>
<p className={styles.userId}>
{tournamentInfo?.winnerIntraId ?? '아이디 정보가 없습니다.'}
{tournamentInfo?.winnerIntraId ?? 'IntraId'}
</p>
<p className={styles.gameInfo}>
{tournamentInfo?.title}{' '}
Expand Down
16 changes: 9 additions & 7 deletions components/tournament/TournamentBraket.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import React from 'react';
import { useSetRecoilState } from 'recoil';
import { clickedTournamentState } from 'utils/recoil/tournament';
import TournamentMatch from 'components/tournament/TournamentMatch';
import LoadingSpinner from 'components/UI/LoadingSpinner';

if (typeof window !== 'undefined' && typeof window.navigator !== 'undefined') {
import('@g-loot/react-tournament-brackets');
Expand All @@ -19,7 +20,7 @@ if (typeof window !== 'undefined' && typeof window.navigator !== 'undefined') {
const SingleEliminationBracket = dynamic<
React.ComponentProps<typeof StaticSingleEliminationBracket>
>(
() => {
async () => {
return import('@g-loot/react-tournament-brackets').then(
(mod) => mod.SingleEliminationBracket
);
Expand All @@ -28,7 +29,7 @@ const SingleEliminationBracket = dynamic<
);

const SVGViewer = dynamic<React.ComponentProps<typeof StaticSVGViewer>>(
() => {
async () => {
return import('@g-loot/react-tournament-brackets').then(
(mod) => mod.SVGViewer
);
Expand All @@ -47,16 +48,17 @@ export default function TournamentBraket({
}: TournamentBraketProps) {
const setHighLightUser = useSetRecoilState(clickedTournamentState);

if (singleEliminationBracketMatchs.length === 0)
return <h1 style={{ color: 'white' }}>Loading...</h1>;
const finalWidth = containerSize?.width; //Math.max(width - 50, 500);
const finalHeight = containerSize?.height; //Math.max(height - 100, 500);
if (singleEliminationBracketMatchs.length === 0) {
return <LoadingSpinner />;
}

return (
<SingleEliminationBracket
matches={singleEliminationBracketMatchs}
onPartyClick={(party: Participant, won: boolean) => {
if (party.name !== '') setHighLightUser(party.name);
if (party.name !== '') {
setHighLightUser(party.name);
}
}}
matchComponent={TournamentMatch}
options={{
Expand Down
2 changes: 1 addition & 1 deletion components/tournament/TournamentCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default function TournamentCard({
.catch((error) => {
setError('JJH2');
});
}, []);
}, [tournamentId, setError]);

const start = dateToKRLocaleTimeString(new Date(startTime));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@ import { instance } from 'utils/axios';
import { convertTournamentGamesToBracketMatchs } from 'utils/handleTournamentGame';
import { errorState } from 'utils/recoil/error';
import TournamentBraket from 'components/tournament/TournamentBraket';
import LoadingSpinner from 'components/UI/LoadingSpinner';
import useComponentSize from 'hooks/util/useComponentSize';
import styles from 'styles/tournament-record/UserTournamentBracket.module.scss';
import styles from 'styles/tournament/UserTournamentBracket.module.scss';

interface UserTournamentBracketProps {
tournamentId: number | undefined;
queryStaleTime: number;
}

export default function UserTournamentBraket({
tournamentId,
queryStaleTime,
}: UserTournamentBracketProps) {
const setError = useSetRecoilState(errorState);
const [ref, size] = useComponentSize<HTMLDivElement>();
Expand All @@ -34,7 +37,7 @@ export default function UserTournamentBraket({
() => fetchTournamentGames(),
{
enabled: !!tournamentId, // tournamentId가 undefined가 아닐 때만 작동하도록
staleTime: 86400000, // 하루
staleTime: queryStaleTime,
}
);

Expand All @@ -45,7 +48,7 @@ export default function UserTournamentBraket({
return (
<div ref={ref} className={styles.bracketContainer}>
{isLoading ? (
<div className={styles.loadingAnimation} />
<LoadingSpinner />
) : (
<TournamentBraket
singleEliminationBracketMatchs={bracketMatches}
Expand Down
75 changes: 58 additions & 17 deletions pages/tournament-record.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,82 @@
import { useState, useRef, useEffect } from 'react';
import { SwiperRef } from 'swiper/react';
import { TournamentInfo } from 'types/tournamentTypes';
import { useState, useRef, useEffect, useCallback } from 'react';
import { SwiperClass, SwiperRef } from 'swiper/react';
import { TournamentInfo, TournamentData } from 'types/tournamentTypes';
import { instance } from 'utils/axios';
import { InfiniteScroll } from 'utils/infinityScroll';
import UserTournamentBracket from 'components/tournament/UserTournamentBracket';
import LeagueButtonGroup from 'components/tournament-record/LeagueButtonGroup';
import UserTournamentBracket from 'components/tournament-record/UserTournamentBracket';
import WinnerSwiper from 'components/tournament-record/WinnerSwiper';
import WinnerTournamentInfo from 'components/tournament-record/WinnerTournamentInfo';
import LoadingSpinner from 'components/UI/LoadingSpinner';
import styles from 'styles/tournament-record/TournamentRecord.module.scss';

export default function TournamentRecord() {
const [tournamentInfo, setTournamentInfo] = useState<TournamentInfo>();
const [selectedType, setSelectedType] = useState<string>('ROOKIE');
const [isEmpty, setIsEmpty] = useState<boolean>(false);
const swiperRef = useRef<SwiperRef>(null);

const fetchTournamentData = useCallback(
async (page: number) => {
const res = await instance.get(
`pingpong/tournaments?page=${page}&type=${selectedType}&size=5&status=END`
);
return res.data;
},
[selectedType]
);

const { data, hasNextPage, fetchNextPage, isLoading } =
InfiniteScroll<TournamentData>(
['tournamentData', selectedType],
fetchTournamentData,
'JC01'
);

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

useEffect(() => {
if (swiperRef.current?.swiper) {
swiperRef.current?.swiper.slideTo(0, 0); // index, speed
swiperRef.current?.swiper.slideTo(0, 0); // 이동할 슬라이드 인덱스, 이동 속도
}
}, [selectedType]);

return (
<div className={styles.pageWrap}>
<h1 className={styles.title}>Hall of Fame</h1>
<LeagueButtonGroup onSelect={setSelectedType} />
<WinnerSwiper
type={selectedType}
size={5}
setTournamentInfo={setTournamentInfo}
ref={swiperRef}
setIsEmpty={setIsEmpty}
/>
{isEmpty ? (
<p>종료된 토너먼트가 없습니다!</p>
{isLoading ? (
<div className={styles.spinnerWrapper}>
<LoadingSpinner />
</div>
) : (
<>
<WinnerTournamentInfo tournamentInfo={tournamentInfo} />
<UserTournamentBracket tournamentId={tournamentInfo?.tournamentId} />
<WinnerSwiper
tournamentData={data}
type={selectedType}
size={5}
setTournamentInfo={setTournamentInfo}
onIndexChange={indexChangeHandler}
ref={swiperRef}
/>
{data?.pages[0].totalPage === 0 ? (
<p>종료된 토너먼트가 없습니다!</p>
) : (
<>
<WinnerTournamentInfo tournamentInfo={tournamentInfo} />
<UserTournamentBracket
tournamentId={tournamentInfo?.tournamentId}
queryStaleTime={1000 * 60 * 60}
/>
</>
)}
</>
)}
</div>
Expand Down
Loading

0 comments on commit 554e915

Please sign in to comment.