Skip to content

Commit

Permalink
게스트 매치 리뷰 남기기 관련 변경사항 적용 (#437)
Browse files Browse the repository at this point in the history
* feat: 리뷰관련 api 명세 바뀐 것 적용

* feat: 매너스코어 뮤테이션에 관련 쿼리 무효화 로직 추가

* feat: 리뷰남기기 가능 기간인지 확인하는 도메인 유틸함수 작성

* feat: 리뷰남기기 관련 변경사항 ui에 적용

* feat: 리뷰남기기 관련 api 변경사항 mock 데이터에 적용
  • Loading branch information
dlwl98 authored Dec 1, 2023
1 parent 7b7fe91 commit 781f2fe
Show file tree
Hide file tree
Showing 12 changed files with 136 additions and 20 deletions.
4 changes: 2 additions & 2 deletions src/api/member/getGameRegistrationStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import { axiosInstance } from '@api/axiosInstance';

import {
GetGameRegistrationStatusRequest,
GetRegistrationStatusResponse,
GetGameRegistrationStatusResponse,
} from '@type/api/member';

export const getGameRegistrationStatus = async ({
memberId,
gameId,
}: GetGameRegistrationStatusRequest) => {
const { data } = await axiosInstance.get<GetRegistrationStatusResponse>(
const { data } = await axiosInstance.get<GetGameRegistrationStatusResponse>(
`/members/${memberId}/games/${gameId}/registration-status`
);

Expand Down
19 changes: 18 additions & 1 deletion src/hooks/mutations/useMannerScoreReviewPatchMutation.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { useMutation } from '@tanstack/react-query';
import { useMutation, useQueryClient } from '@tanstack/react-query';

import { patchMannerScoreReview } from '@api/games/patchMannerScoreReview';

import { useLoginInfoStore } from '@stores/loginInfo.store';

import { PatchGameMannerScoreReviewRequest } from '@type/api/games';
import { Game } from '@type/models';

Expand All @@ -12,8 +14,23 @@ export const useMannerScoreReviewPatchMutation = ({
payload: PatchGameMannerScoreReviewRequest;
gameId: Game['id'];
}) => {
const queryClient = useQueryClient();
const loginInfo = useLoginInfoStore((state) => state.loginInfo);

return useMutation({
mutationKey: ['patch-manner-score-review', gameId, JSON.stringify(payload)],
mutationFn: () => patchMannerScoreReview({ payload, gameId }),
onSuccess: () => {
console.log(['game-registration', loginInfo?.id, gameId]);
queryClient.invalidateQueries({
queryKey: ['created-games', loginInfo?.id],
});
queryClient.invalidateQueries({
queryKey: ['confirmed-games', loginInfo?.id],
});
queryClient.invalidateQueries({
queryKey: ['game-registration', loginInfo?.id, gameId],
});
},
});
};
13 changes: 10 additions & 3 deletions src/mocks/data/member.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import {
PostRefreshAccessTokenResponse,
PostRegistrationResponse,
} from '@type/api/member';
import { Authenticated, CrewProfile, Game, Registration } from '@type/models';
import {
Authenticated,
CrewProfile,
MemberGame,
Registration,
} from '@type/models';

export const AUTH_LOGIN_MEMBER: Authenticated = {
accessToken:
Expand Down Expand Up @@ -129,7 +134,7 @@ export const MEMBERS_MEMBERID: GetMemberProfileResponse = {
],
};

export const MEMBERS_MEMBERID_CONFIRMED_GAMES: Game[] = [
export const MEMBERS_MEMBERID_CONFIRMED_GAMES: MemberGame[] = [
{
id: 1,
content: '같이 즐거운 게임 해요~',
Expand All @@ -146,6 +151,7 @@ export const MEMBERS_MEMBERID_CONFIRMED_GAMES: Game[] = [
cost: 0,
memberCount: 3,
maxMemberCount: 5,
isReviewDone: false,
host: {
id: 1,
email: '[email protected]',
Expand Down Expand Up @@ -190,7 +196,7 @@ export const MEMBERS_MEMBERID_CONFIRMED_GAMES: Game[] = [
},
];

export const MEMBERS_MEMBERID_CREATED_GAMES: Game[] = [
export const MEMBERS_MEMBERID_CREATED_GAMES: MemberGame[] = [
{
id: 1,
content: '같이 즐거운 게임 해요~',
Expand All @@ -207,6 +213,7 @@ export const MEMBERS_MEMBERID_CREATED_GAMES: Game[] = [
cost: 0,
memberCount: 3,
maxMemberCount: 5,
isReviewDone: false,
host: {
id: 1,
email: '[email protected]',
Expand Down
15 changes: 14 additions & 1 deletion src/pages/GamesDetailPage/GamesDetailPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ import { useLoginInfoStore } from '@stores/loginInfo.store';
import { PATH_NAME } from '@consts/pathName';
import { WEEKDAY } from '@consts/weekday';

import { getGameStartDate, isGameEnded, isGameStarted } from '@utils/domain';
import {
getGameStartDate,
isGameEnded,
isGameStarted,
isReviewPeriod,
} from '@utils/domain';

import Ball from '@assets/ball.svg';
import GameMember from '@assets/gameMember.svg';
Expand Down Expand Up @@ -65,6 +70,11 @@ export const GamesDetailPage = () => {
(member) => member.id === loginInfo?.id
);
const vacancy = match.maxMemberCount - match.memberCount > 0;
const canReview = isReviewPeriod(
match.playDate,
match.playStartTime,
match.playTimeMinutes
);

const [year, month, day] = match.playDate.split('-');
const [hour, min] = match.playStartTime.split(':');
Expand Down Expand Up @@ -260,9 +270,11 @@ export const GamesDetailPage = () => {
<ErrorBoundary fallback={<></>}>
{loginInfo?.id && isMyMatch && (
<HostButton
loginId={loginInfo.id}
gameId={gameId}
isStarted={isStarted}
isEnded={isEnded}
isReviewPeriod={canReview}
/>
)}
{loginInfo?.id && !isMyMatch && (
Expand All @@ -272,6 +284,7 @@ export const GamesDetailPage = () => {
isStarted={isStarted}
isEnded={isEnded}
vacancy={vacancy}
isReviewPeriod={canReview}
/>
)}
</ErrorBoundary>
Expand Down
10 changes: 8 additions & 2 deletions src/pages/GamesDetailPage/components/GuestButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type GuestButtonProps = {
isStarted: boolean;
isEnded: boolean;
vacancy: boolean;
isReviewPeriod: boolean;
};

export const GuestButton = ({
Expand All @@ -26,12 +27,13 @@ export const GuestButton = ({
isStarted,
isEnded,
vacancy,
isReviewPeriod,
}: GuestButtonProps) => {
const isContinue = isStarted && !isEnded;
const navigate = useNavigate();

const {
data: { memberRegistrationStatus },
data: { memberRegistrationStatus, isReviewDone },
} = useGameRegistrationStatusQuery({ memberId: loginId, gameId });
const { mutate: participateMutate } = useGameParticipateCreateMutation();

Expand All @@ -53,7 +55,11 @@ export const GuestButton = ({
}

if (isEnded) {
if (memberRegistrationStatus === '확정') {
if (
isReviewPeriod &&
memberRegistrationStatus === '확정' &&
!isReviewDone
) {
return (
<BottomButton onClick={navigateReviewPage}>리뷰 남기기</BottomButton>
);
Expand Down
17 changes: 15 additions & 2 deletions src/pages/GamesDetailPage/components/HostButton.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
import { useNavigate } from 'react-router-dom';

import { useGameRegistrationStatusQuery } from '@hooks/queries/useGameRegistrationStatusQuery';

import { PATH_NAME } from '@consts/pathName';

import { BottomButton } from './BottomButton';

type HostButtonProps = {
loginId: number;
gameId: number;
isStarted: boolean;
isEnded: boolean;
isReviewPeriod: boolean;
};

export const HostButton = ({ gameId, isStarted, isEnded }: HostButtonProps) => {
export const HostButton = ({
loginId,
gameId,
isStarted,
isEnded,
isReviewPeriod,
}: HostButtonProps) => {
const navigate = useNavigate();
const {
data: { isReviewDone },
} = useGameRegistrationStatusQuery({ memberId: loginId, gameId });

const navigateManagePage = () =>
navigate(PATH_NAME.GET_GAMES_MANAGE_PATH(String(gameId)));
Expand All @@ -23,7 +36,7 @@ export const HostButton = ({ gameId, isStarted, isEnded }: HostButtonProps) => {
return <BottomButton onClick={navigateManagePage}>매치 관리</BottomButton>;
}

if (isEnded) {
if (isReviewPeriod && isEnded && !isReviewDone) {
return (
<BottomButton onClick={navigateReviewPage}>리뷰 남기기</BottomButton>
);
Expand Down
17 changes: 15 additions & 2 deletions src/pages/GamesHostPage/GamesHostPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ import { useLoginInfoStore } from '@stores/loginInfo.store';

import { PATH_NAME } from '@consts/pathName';

import { getGameStartDate, isGameEnded, isGameStarted } from '@utils/domain';
import {
getGameStartDate,
isGameEnded,
isGameStarted,
isReviewPeriod,
} from '@utils/domain';

import { PageContent, PageWrapper } from './GamesHostPage.styles';

Expand Down Expand Up @@ -44,6 +49,14 @@ export const GamesHostPage = () => {
(member) => member.profileImageUrl
);
const startTime = getGameStartDate(game.playDate, game.playStartTime);
const canReview =
isReviewPeriod(
game.playDate,
game.playStartTime,
game.playTimeMinutes
) &&
isGameEnded(startTime, game.playTimeMinutes) &&
!game.isReviewDone;

return (
<MatchItem
Expand All @@ -65,7 +78,7 @@ export const GamesHostPage = () => {
매치 관리
</MatchItem.BottomButton>
)}
{isGameEnded(startTime, game.playTimeMinutes) && (
{canReview && (
<MatchItem.BottomButton
onClick={() =>
navigate(PATH_NAME.GET_GAMES_REVIEW_PATH(String(game.id)))
Expand Down
12 changes: 10 additions & 2 deletions src/pages/GamesParticipatePage/GamesParticipatePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { useLoginInfoStore } from '@stores/loginInfo.store';

import { PATH_NAME } from '@consts/pathName';

import { getGameStartDate } from '@utils/domain';
import { getGameStartDate, isReviewPeriod } from '@utils/domain';

import { PageContent, PageWrapper } from './GamesParticipatePage.styles';

Expand Down Expand Up @@ -47,6 +47,14 @@ export const GamesParticipatePage = () => {
const endTimeNumber =
startTime.getTime() + game.playTimeMinutes * 60000;
const isMatchEnd = endTimeNumber <= new Date().getTime();
const canReview =
isReviewPeriod(
game.playDate,
game.playStartTime,
game.playTimeMinutes
) &&
isMatchEnd &&
!game.isReviewDone;

return (
<MatchItem
Expand All @@ -59,7 +67,7 @@ export const GamesParticipatePage = () => {
maxMemberCount={game.maxMemberCount}
membersProfileImageUrls={membersProfileImageUrls}
>
{isMatchEnd && (
{canReview && (
<MatchItem.BottomButton
onClick={() =>
navigate(PATH_NAME.GET_GAMES_REVIEW_PATH(String(game.id)))
Expand Down
26 changes: 23 additions & 3 deletions src/pages/MannerScoreReviewPage/MannerScoreReviewPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { useNavigate } from 'react-router-dom';
import { ProfileSkeleton } from '@pages/ProfilePage';
import { Profile } from '@pages/ProfilePage';

import { LoginRequireError } from '@routes/LoginRequireBoundary';

import { Avatar } from '@components/Avatar';
import { Header } from '@components/Header';
import { Modal } from '@components/Modal';
Expand All @@ -13,13 +15,16 @@ import { Text } from '@components/shared/Text';

import { useMannerScoreReviewPatchMutation } from '@hooks/mutations/useMannerScoreReviewPatchMutation';
import { useGameDetailQuery } from '@hooks/queries/useGameDetailQuery';
import { useGameRegistrationStatusQuery } from '@hooks/queries/useGameRegistrationStatusQuery';

import { theme } from '@styles/theme';

import { useLoginInfoStore } from '@stores/loginInfo.store';

import { PATH_NAME } from '@consts/pathName';

import { isReviewPeriod } from '@utils/domain';

import leftArrowIcon from '@assets/leftArrow.svg';
import rightArrowIcon from '@assets/rightArrow.svg';

Expand All @@ -37,16 +42,31 @@ import { ToggleButton } from './ToggleButton';
export const MannerScoreReviewPage = () => {
const navigate = useNavigate();
const gameId = Number(location.pathname.split('/')[2]);
const { data: gameData } = useGameDetailQuery(gameId);
const loginInfo = useLoginInfoStore((state) => state.loginInfo);
if (!loginInfo?.id) {
throw new LoginRequireError();
}

const { data: gameData } = useGameDetailQuery(gameId);
const {
data: { isReviewDone },
} = useGameRegistrationStatusQuery({ memberId: loginInfo.id, gameId });
const teammateListInfo = gameData.members.filter(({ id }) => {
return loginInfo?.id !== id;
});

const nowDate = new Date();
const gameDate = new Date(`${gameData.playDate}T${gameData.playEndTime}`);

const canReview = isReviewPeriod(
gameData.playDate,
gameData.playStartTime,
gameData.playTimeMinutes
);
const exitCode =
nowDate <= gameDate || !loginInfo || teammateListInfo.length === 0;
!canReview ||
isReviewDone ||
nowDate <= gameDate ||
teammateListInfo.length === 0;

const [currentSelectedMemberIndex, setCurrentSelectedMemberIndex] =
useState(0);
Expand Down
8 changes: 6 additions & 2 deletions src/type/api/member.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
CrewProfile,
Game,
Member,
MemberGame,
MemberProfile,
Registration,
} from '@type/models';
Expand Down Expand Up @@ -37,12 +38,12 @@ export type GetConfirmedGamesRequest = {
memberId: Member['id'];
};

export type GetConfirmedGamesResponse = Game[];
export type GetConfirmedGamesResponse = MemberGame[];

export type GetCreatedGamesRequest = {
memberId: Member['id'];
};
export type GetCreatedGamesResponse = Game[];
export type GetCreatedGamesResponse = MemberGame[];

export type GetJoinedCrewsResponse = CrewProfile[];

Expand All @@ -63,3 +64,6 @@ export type GetGameRegistrationStatusRequest = {
export type GetRegistrationStatusResponse = {
memberRegistrationStatus: '없음' | '대기' | '확정';
};

export type GetGameRegistrationStatusResponse =
GetRegistrationStatusResponse & { isReviewDone: boolean };
2 changes: 2 additions & 0 deletions src/type/models/Game.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ export type Game = {
positions: Position[];
members: Member[];
};

export type MemberGame = Game & { isReviewDone: boolean };
Loading

0 comments on commit 781f2fe

Please sign in to comment.