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/#170 관리자 알림 확인 기능 및 해당 그룹 바로가기 #181

Merged
merged 6 commits into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
514 changes: 59 additions & 455 deletions __mocks__/constants/matchRoundMock.ts

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions src/@types/admin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface CallAdmin {
matchRound: number;
matchName: string;
callName: string;
}
5 changes: 3 additions & 2 deletions src/@types/bracket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ interface PlayerInfo {
}
interface MatchInfo {
matchName: string;
matchStatus: string;
matchId: number;
matchStatus: 'READY' | 'PROGRESS' | 'END';
matchRound: number;
matchCurrentSet: number;
matchSetCurrent: number;
matchPlayerInfoList: PlayerInfo[];
matchId: number;
alarm: boolean;
}

export interface BracketContents {
Expand Down
3 changes: 2 additions & 1 deletion src/@types/icon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ export type IconKind =
| 'sendEmail'
| 'modify'
| 'setting'
| 'cancel';
| 'cancel'
| 'shortcut';
2 changes: 2 additions & 0 deletions src/components/Icon/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
MdModeEdit,
MdSettings,
MdCancel,
MdOutlineShortcut,
} from 'react-icons/md';
import { MouseEventHandler } from 'react';

Expand All @@ -33,6 +34,7 @@ const ICON: { [key in IconKind]: IconType } = {
modify: MdModeEdit,
setting: MdSettings,
cancel: MdCancel,
shortcut: MdOutlineShortcut,
};

interface IconProps {
Expand Down
91 changes: 91 additions & 0 deletions src/components/RoundAlarm/RoundAlarmBody.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import authAPI from '@apis/authAPI';
import Icon from '@components/Icon';
import styled from '@emotion/styled';
import { BracketContents } from '@type/bracket';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';

interface Props {
curRound: number;
havingAlarm: boolean;
}

const RoundAlarmBody = ({ curRound, havingAlarm }: Props) => {
const router = useRouter();

console.log(havingAlarm);

const [roundInfo, setRoundInfo] = useState<BracketContents>();

useEffect(() => {
const getRoundInfo = async () => {
try {
const res = await authAPI({
method: 'get',
url: `/api/match/${router.query.channelLink as string}/${curRound}`,
});

setRoundInfo(res.data);
} catch (error) {}
};

getRoundInfo();
}, []);

const moveToCheckIn = (matchId: number) => {
authAPI({
method: 'post',
url: `/api/match/${router.query.channelLink as string}/${matchId}/call-off`,
});

router.push(`/contents/${router.query.channelLink as string}/checkIn/${matchId}`);
};

return (
<Ground>
{roundInfo?.matchInfoDtoList.map((match) => {
return (
<GroupContainer key={match.matchId} onClick={() => moveToCheckIn(match.matchId)}>
<GroupTitle>{match.matchName}</GroupTitle>
<Icon kind='shortcut' size={25} />

{(match.alarm || havingAlarm) && <AlarmCircle />}
</GroupContainer>
);
})}
</Ground>
);
};

const Ground = styled.div`
margin: 2rem 0;
`;

const GroupContainer = styled.div`
width: 15rem;
height: 4rem;
display: flex;
align-items: center;
border: 0.2rem solid #132043;

justify-content: space-around;

position: relative;

cursor: pointer;
`;

const GroupTitle = styled.div`
font-size: 2rem;
`;

const AlarmCircle = styled.div`
position: absolute;
width: 0.8rem;
height: 0.8rem;
right: 0.4rem;
background-color: #c70039;
border-radius: 0.4rem;
`;

export default RoundAlarmBody;
52 changes: 52 additions & 0 deletions src/components/RoundAlarm/RoundAlarmHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import styled from '@emotion/styled';

interface Props {
liveRound: number;
curRound: number;
}

type bracketStatus = 'PAST' | 'PRESENT' | 'FUTURE';

const RoundAlarmHeader = ({ liveRound, curRound }: Props) => {
return (
<>
{liveRound > curRound && <Button status='PAST'>Round {curRound}</Button>}
{liveRound === curRound && <Button status='PRESENT'>Round {curRound}</Button>}
{liveRound < curRound && <Button status='FUTURE'>Round {curRound}</Button>}
</>
);
};

const Button = styled.button<{ status: bracketStatus }>`
width: 12rem;
height: 4rem;
border: none;
padding: 0;
margin: 0;

font-size: 1.6rem;
color: white;

${(prop) =>
prop.status === 'PAST' &&
`
background-color : #7C81AD;
cursor: pointer;
`}

${(prop) =>
prop.status === 'PRESENT' &&
`
background-color : #4B527E;
cursor: pointer;
`}

${(prop) =>
prop.status === 'FUTURE' &&
`
background-color : #2E4374;
cursor: not-allowed
`}
`;

export default RoundAlarmHeader;
110 changes: 92 additions & 18 deletions src/pages/contents/[channelLink]/admin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,75 @@ import useModals from '@hooks/useModals';

import { SERVER_URL } from '@config/index';
import { parse } from 'cookie';
import { useEffect, useState } from 'react';
import { connectToStomp } from '@config/stomp';
import { Client, StompSubscription } from '@stomp/stompjs';
import { useQuery } from '@tanstack/react-query';
import authAPI from '@apis/authAPI';
import { BracketHeader } from '@type/bracket';
import RoundAlarmHeader from '@components/RoundAlarm/RoundAlarmHeader';
import RoundAlarmBody from '@components/RoundAlarm/RoundAlarmBody';
import { CallAdmin } from '@type/admin';
interface Props {
role: string;
}

const fetchRoundInfo = async (channelLink: string): Promise<BracketHeader> => {
const res = await authAPI<BracketHeader>({ method: 'get', url: `/api/match/${channelLink}` });
return res.data;
};

const Admin = ({ role }: Props) => {
const router = useRouter();
const [client, setClient] = useState<Client>();

const [curRound, setCurRound] = useState<number>();

const [alramInfo, setAlramInfo] = useState<CallAdmin>();

const { openModal, closeModal } = useModals();

const { data, isSuccess } = useQuery({
queryKey: ['roundInfos'],
queryFn: () => {
setCurRound(1);
return fetchRoundInfo(router.query.channelLink as string);
},
});

if (!role) {
router.push('/');
}

const isMySelfAlarm = () => {
return curRound === alramInfo?.matchRound;
};

useEffect(() => {
const tmpClient = connectToStomp();
tmpClient.activate();

let checkInSubscription: StompSubscription;

tmpClient.onConnect = () => {
setClient(tmpClient);
checkInSubscription = tmpClient.subscribe(
`/match/${router.query.channelLink as string}`,
(data) => {
setAlramInfo(JSON.parse(data.body));
},
);
};
return () => {
if (!client) return;
if (checkInSubscription) checkInSubscription.unsubscribe();
client.deactivate();
};
}, []);

if (isSuccess) {
}

return (
<Container>
<Header>대회 설정</Header>
Expand All @@ -41,25 +97,37 @@ const Admin = ({ role }: Props) => {
>
대회 관리하기
</Button>
<Button
width={20}
height={6}
onClick={() =>
openModal(Modal, {
onClose: () => closeModal(Modal),
children: (
<ModifyChannel
channelLink={router.query.channelLink as string}
onClose={() => closeModal(Modal)}
/>
),
})
}
>
채널 정보 수정하기
</Button>
</BracketContainer>
<Header>대회 알림</Header>
<BracketContainer>
<RoundList>
{data?.roundList.map((ele) => {
return <RoundAlarmHeader liveRound={data.liveRound} curRound={ele} key={ele} />;
})}
</RoundList>
</BracketContainer>
<Header>채널 정보 설정</Header>
<Button
width={20}
height={6}
onClick={() =>
openModal(Modal, {
onClose: () => closeModal(Modal),
children: (
<ModifyChannel
channelLink={router.query.channelLink as string}
onClose={() => closeModal(Modal)}
/>
),
})
}
>
채널 정보 수정하기
</Button>
{curRound && (
<div>
<RoundAlarmBody curRound={curRound} havingAlarm={isMySelfAlarm()} />
</div>
)}
</Container>
);
};
Expand All @@ -82,6 +150,12 @@ const BracketContainer = styled.div`
column-gap: 3rem;
`;

const RoundList = styled.div`
display: flex;
align-items: center;
column-gap: 2rem;
`;

export const getServerSideProps: GetServerSideProps = async (context) => {
try {
const cookies = parse(context.req.headers.cookie || 'no-cookie');
Expand Down