diff --git a/components/Layout/Header.tsx b/components/Layout/Header.tsx index a8da8caa4..87d6e0308 100644 --- a/components/Layout/Header.tsx +++ b/components/Layout/Header.tsx @@ -1,7 +1,9 @@ import Link from 'next/link'; +import { useRouter } from 'next/router'; import { useEffect, useContext } from 'react'; import { useRecoilState, useSetRecoilState } from 'recoil'; import { BsMegaphone } from 'react-icons/bs'; +import { FaArrowLeft } from 'react-icons/fa'; import { FiMenu } from 'react-icons/fi'; import { IoStorefrontOutline } from 'react-icons/io5'; import { Modal } from 'types/modalTypes'; @@ -18,6 +20,7 @@ import useAxiosGet from 'hooks/useAxiosGet'; import styles from 'styles/Layout/Header.module.scss'; export default function Header() { + const router = useRouter(); const [live, setLive] = useRecoilState(liveState); const HeaderState = useContext(HeaderContext); const openMenuBarHandler = () => { @@ -54,11 +57,26 @@ export default function Header() { type: 'setError', }); + // 현재 경로가 뒤로 가기 버튼을 사용해야 하는 경로 패턴 중 하나와 일치하는지 확인 + const isBackButtonRoute = () => { + const path = router.asPath.split('?')[0]; // 쿼리 스트링 제거 + const patterns = [ + /^\/party\/create$/, // '/party/create' + /^\/party\/[0-9]+$/, // '/party/[roomId]' + ]; + + return patterns.some((pattern) => pattern.test(path)); + }; + return (
- + {isBackButtonRoute() ? ( + + ) : ( + + )}
42GG diff --git a/components/Layout/PlayButton.tsx b/components/Layout/PlayButton.tsx index 914729e20..0b87f853b 100644 --- a/components/Layout/PlayButton.tsx +++ b/components/Layout/PlayButton.tsx @@ -14,7 +14,8 @@ const PlayButton = () => { if ( presentPath === '/match' || presentPath === '/manual' || - presentPath === '/store' + presentPath === '/store' || + presentPath.startsWith('/party') ) return null; return ( diff --git a/components/admin/SideNav.tsx b/components/admin/SideNav.tsx index c2905b538..dc3574925 100644 --- a/components/admin/SideNav.tsx +++ b/components/admin/SideNav.tsx @@ -1,5 +1,7 @@ import { useRouter } from 'next/router'; +import { useState } from 'react'; import { BsShop } from 'react-icons/bs'; +import { FaAngleDown, FaAngleRight } from 'react-icons/fa'; import { GoSettings } from 'react-icons/go'; import { GrUserSettings, @@ -7,13 +9,22 @@ import { GrStatusWarning, GrAnnounce, } from 'react-icons/gr'; -import { IoGameControllerOutline, IoReceiptOutline } from 'react-icons/io5'; +import { + IoGameControllerOutline, + IoPeople, + IoReceiptOutline, +} from 'react-icons/io5'; import { MdOutlineMessage } from 'react-icons/md'; import { TbCalendarTime, TbCoin, TbPaperBag, TbTrophy, + TbNote, + TbFileReport, + TbMessageReport, + TbBuildingWarehouse, + TbPlaylistAdd, TbWallet, } from 'react-icons/tb'; import SideNavContent from 'components/admin/SideNavContent'; @@ -21,6 +32,7 @@ import styles from 'styles/admin/SideNav.module.scss'; export default function SideNav() { const currentPath = useRouter().asPath.replace('/admin', ''); + const [isPartyOpen, setPartyOpen] = useState(false); return (
@@ -135,6 +147,59 @@ export default function SideNav() { > + +
setPartyOpen(!isPartyOpen)} + > + + 파티 관리탭 + {isPartyOpen ? : } +
+ + {isPartyOpen && ( +
+ + + + + + + + + + + + + + + + + + + +
+ )}
); } diff --git a/components/admin/party/AdminCommentReport.tsx b/components/admin/party/AdminCommentReport.tsx new file mode 100644 index 000000000..45719564f --- /dev/null +++ b/components/admin/party/AdminCommentReport.tsx @@ -0,0 +1,108 @@ +import { useEffect, useState } from 'react'; +import { useSetRecoilState } from 'recoil'; +import { + Paper, + Table, + TableBody, + TableCell, + TableContainer, + TableRow, +} from '@mui/material'; +import { PartyCommentReport, PartyCommentReportTable } from 'types/partyTypes'; +import { instanceInPartyManage } from 'utils/axios'; +import { toastState } from 'utils/recoil/toast'; +import { tableFormat } from 'constants/admin/table'; +import { + AdminEmptyItem, + AdminTableHead, +} from 'components/admin/common/AdminTable'; +import PageNation from 'components/Pagination'; +import styles from 'styles/admin/party/AdminPartyCommon.module.scss'; + +const tableTitle: { [key: string]: string } = { + id: '번호', + reporterIntraId: '신고자 이름', + commentsId: '댓글 번호', + roomId: '방', + message: '메세지', + createdAt: '시간', +}; + +export default function AdminCommentReport() { + const [commentInfo, setCommentInfo] = useState({ + commentReportList: [], + totalPage: 0, + currentPage: 0, + }); + const [currentPage, setCurrentPage] = useState(1); + const setSnackBar = useSetRecoilState(toastState); + + useEffect(() => { + instanceInPartyManage + .get(`/reports/comments?page=${currentPage}&size=10`) + .then((res) => { + setCommentInfo({ + commentReportList: res.data.commentReportList, + totalPage: res.data.totalPage, + currentPage: currentPage, + }); + }) + .catch((error) => { + setSnackBar({ + toastName: 'GET request', + message: '댓글신고를 가져오는데 실패했습니다.', + severity: 'error', + clicked: true, + }); + }); + }, [currentPage]); + + return ( +
+
+ 댓글 신고리스트 +
+ + + + + {commentInfo.commentReportList && + commentInfo.commentReportList.length > 0 ? ( + commentInfo.commentReportList.map( + (report: PartyCommentReport, index: number) => ( + + {tableFormat['partyCommentReport'].columns.map( + (columnName) => { + return ( + + {report[ + columnName as keyof PartyCommentReport + ]?.toString()} + + ); + } + )} + + ) + ) + ) : ( + + )} + +
+
+
+ { + setCurrentPage(pageNumber); + }} + /> +
+
+ ); +} diff --git a/components/admin/party/AdminPartyNoShow.tsx b/components/admin/party/AdminPartyNoShow.tsx new file mode 100644 index 000000000..65d48bbb0 --- /dev/null +++ b/components/admin/party/AdminPartyNoShow.tsx @@ -0,0 +1,108 @@ +import { useEffect, useState } from 'react'; +import { useSetRecoilState } from 'recoil'; +import { + Paper, + Table, + TableBody, + TableCell, + TableContainer, + TableRow, +} from '@mui/material'; +import { PartyNoshowReport, PartyNoshowReportTable } from 'types/partyTypes'; +import { instanceInPartyManage } from 'utils/axios'; +import { toastState } from 'utils/recoil/toast'; +import { tableFormat } from 'constants/admin/table'; +import { + AdminEmptyItem, + AdminTableHead, +} from 'components/admin/common/AdminTable'; +import PageNation from 'components/Pagination'; +import styles from 'styles/admin/party/AdminPartyCommon.module.scss'; + +const tableTitle: { [key: string]: string } = { + id: '번호', + reporterIntraId: '신고자 이름', + reporteeIntraId: '피신고자 이름', + roomId: '방', + message: '메세지', + createdAt: '시간', +}; + +export default function AdminPartyNoShow() { + const [noShowInfo, setNoShowInfo] = useState({ + noShowReportList: [], + totalPages: 0, + currentPage: 0, + }); + const [currentPage, setCurrentPage] = useState(1); + const setSnackBar = useSetRecoilState(toastState); + + useEffect(() => { + instanceInPartyManage + .get(`/reports/users?page=${currentPage}&size=10`) + .then((res) => { + setNoShowInfo({ + noShowReportList: res.data.noShowReportList, + totalPages: res.data.totalPage, + currentPage: currentPage, + }); + }) + .catch((error) => { + setSnackBar({ + toastName: 'GET request', + message: '댓글신고를 가져오는데 실패했습니다.', + severity: 'error', + clicked: true, + }); + }); + }, [currentPage]); + + return ( +
+
+ 노쇼 신고리스트 +
+ + + + + {noShowInfo.noShowReportList && + noShowInfo.noShowReportList.length > 0 ? ( + noShowInfo.noShowReportList.map( + (report: PartyNoshowReport, index: number) => ( + + {tableFormat['partyNoshowReport'].columns.map( + (columnName) => { + return ( + + {report[ + columnName as keyof PartyNoshowReport + ]?.toString()} + + ); + } + )} + + ) + ) + ) : ( + + )} + +
+
+
+ { + setCurrentPage(pageNumber); + }} + /> +
+
+ ); +} diff --git a/components/admin/party/AdminPartyPenalty.tsx b/components/admin/party/AdminPartyPenalty.tsx new file mode 100644 index 000000000..269dac768 --- /dev/null +++ b/components/admin/party/AdminPartyPenalty.tsx @@ -0,0 +1,138 @@ +import { useEffect, useState } from 'react'; +import { useSetRecoilState } from 'recoil'; +import { + Paper, + Table, + TableBody, + TableCell, + TableContainer, + TableRow, +} from '@mui/material'; +import { PartyPenaltyAdmin, PartyPenaltyTable } from 'types/partyTypes'; +import { instanceInPartyManage } from 'utils/axios'; +import { dateToStringShort } from 'utils/handleTime'; +import { modalState } from 'utils/recoil/modal'; +import { toastState } from 'utils/recoil/toast'; +import { tableFormat } from 'constants/admin/table'; +import { + AdminEmptyItem, + AdminTableHead, +} from 'components/admin/common/AdminTable'; +import PageNation from 'components/Pagination'; +import styles from 'styles/admin/party/AdminPartyCommon.module.scss'; + +const tableTitle: { [key: string]: string } = { + id: '번호', + userIntraId: '유저', + penaltyType: '패널티 타입', + message: '내용', + startTime: '시작 시간', + penaltyTime: '패널티 시간', + edit: '수정', +}; + +export default function AdminCommentReport() { + const [penaltyInfo, setPenaltyInfo] = useState({ + penaltyList: [], + totalPage: 0, + currentPage: 0, + }); + const [currentPage, setCurrentPage] = useState(1); + const setModal = useSetRecoilState(modalState); + const setSnackBar = useSetRecoilState(toastState); + + useEffect(() => { + instanceInPartyManage + .get(`/penalties?page=${currentPage}&size=10`) + .then((res) => { + setPenaltyInfo({ + penaltyList: res.data.penaltyList, + totalPage: res.data.totalPage, + currentPage: currentPage, + }); + }) + .catch((error) => { + setSnackBar({ + toastName: 'GET request', + message: '댓글신고를 가져오는데 실패했습니다.', + severity: 'error', + clicked: true, + }); + }); + }, [currentPage]); + + const handleAddpenalty = () => { + setModal({ modalName: 'ADMIN-PARTY_PENALTY' }); + }; + + const handleEditpenalty = (partyPenalty?: PartyPenaltyAdmin) => { + setModal({ modalName: 'ADMIN-PARTY_PENALTY', partyPenalty }); + }; + + return ( +
+
+ 패널티 리스트 + +
+ + + + + {penaltyInfo.penaltyList && penaltyInfo.penaltyList.length > 0 ? ( + penaltyInfo.penaltyList.map( + (penalty: PartyPenaltyAdmin, index: number) => ( + + {tableFormat['partyPenaltyAdmin'].columns.map( + (columnName) => { + return ( + + {columnName === 'edit' ? ( + + ) : columnName === 'startTime' ? ( + + {dateToStringShort(new Date(penalty.startTime))} + + ) : ( + penalty[ + columnName as keyof PartyPenaltyAdmin + ]?.toString() + )} + + ); + } + )} + + ) + ) + ) : ( + + )} + +
+
+
+ { + setCurrentPage(pageNumber); + }} + /> +
+
+ ); +} diff --git a/components/admin/party/AdminPartyRoomReport.tsx b/components/admin/party/AdminPartyRoomReport.tsx new file mode 100644 index 000000000..0984c6662 --- /dev/null +++ b/components/admin/party/AdminPartyRoomReport.tsx @@ -0,0 +1,103 @@ +import { useEffect, useState } from 'react'; +import { useSetRecoilState } from 'recoil'; +import { + Paper, + Table, + TableBody, + TableCell, + TableContainer, + TableRow, +} from '@mui/material'; +import { PartyRoomReport, PartyRoomReportTable } from 'types/partyTypes'; +import { instanceInPartyManage } from 'utils/axios'; +import { toastState } from 'utils/recoil/toast'; +import { tableFormat } from 'constants/admin/table'; +import { + AdminEmptyItem, + AdminTableHead, +} from 'components/admin/common/AdminTable'; +import PageNation from 'components/Pagination'; +import styles from 'styles/admin/party/AdminPartyCommon.module.scss'; + +const tableTitle: { [key: string]: string } = { + id: '번호', + reporterIntraId: '신고자 이름', + reporteeIntraId: '피신고자 이름', + roomId: '방', + message: '메세지', + createdAt: '시간', +}; + +export default function AdminPartyRoomReport() { + const [roomInfo, setRoomInfo] = useState({ + roomReportList: [], + totalPages: 0, + currentPage: 0, + }); + const [currentPage, setCurrentPage] = useState(1); + + const setSnackBar = useSetRecoilState(toastState); + + useEffect(() => { + instanceInPartyManage + .get(`/reports/rooms?page=${currentPage}&size=10`) + .then((res) => { + setRoomInfo({ + roomReportList: res.data.roomReportList, + totalPages: res.data.totalPage, + currentPage: currentPage, + }); + }) + .catch((error) => { + setSnackBar({ + toastName: 'GET request', + message: '댓글신고를 가져오는데 실패했습니다.', + severity: 'error', + clicked: true, + }); + }); + }, [currentPage]); + + return ( +
+
+ 방 신고리스트 +
+ + + + + {roomInfo.roomReportList && roomInfo.roomReportList.length > 0 ? ( + roomInfo.roomReportList.map( + (report: PartyRoomReport, index: number) => ( + + {tableFormat['partyRoomReport'].columns.map( + (columnName) => ( + + {report[ + columnName as keyof PartyRoomReport + ]?.toString()} + + ) + )} + + ) + ) + ) : ( + + )} + +
+
+
+ { + setCurrentPage(pageNumber); + }} + /> +
+
+ ); +} diff --git a/components/admin/party/PartyCategory.tsx b/components/admin/party/PartyCategory.tsx new file mode 100644 index 000000000..c6db2fa4f --- /dev/null +++ b/components/admin/party/PartyCategory.tsx @@ -0,0 +1,83 @@ +import { useState } from 'react'; +import { + Paper, + Table, + TableBody, + TableCell, + TableContainer, + TableRow, +} from '@mui/material'; +import { PartyCategory } from 'types/partyTypes'; +import { tableFormat } from 'constants/admin/table'; +import { AdminTableHead } from 'components/admin/common/AdminTable'; +import usePartyCategory from 'hooks/party/usePartyCategory'; +import styles from 'styles/admin/party/AdminPartyCommon.module.scss'; + +const tableTitle: { [key: string]: string } = { + categoryId: '카테고리번호', + categoryName: '카테고리', + delete: '삭제', +}; + +export default function PartyCategories() { + const { categories, createCategory, deleteCategory } = usePartyCategory(); + const [newCategoryName, setNewCategoryName] = useState(''); + + const handleConfirm = () => { + if (newCategoryName.trim() !== '') { + createCategory(newCategoryName); + setNewCategoryName(''); + } + }; + + return ( +
+
+ 카테고리 관리 +
+ setNewCategoryName(e.target.value)} + /> + +
+
+ + + + + {categories.map((c) => ( + + {tableFormat['partyCategory'].columns.map((columnName) => { + return ( + + {columnName === 'delete' ? ( + + ) : ( + c[columnName as keyof PartyCategory]?.toString() + )} + + ); + })} + + ))} + +
+
+
+ ); +} diff --git a/components/admin/party/PartyReportNav.tsx b/components/admin/party/PartyReportNav.tsx new file mode 100644 index 000000000..de6392674 --- /dev/null +++ b/components/admin/party/PartyReportNav.tsx @@ -0,0 +1,29 @@ +import { useState } from 'react'; +import styles from 'styles/party/PartyNav.module.scss'; +import AdminCommentReport from './AdminCommentReport'; +import AdminPartyNoShowReport from './AdminPartyNoShow'; +import AdminPartyRoomReport from './AdminPartyRoomReport'; + +export default function PartyReportNav() { + const [navValue, setNavValue] = useState('noshow'); + return ( + <> +
+
    +
  • setNavValue('noshow')}> + 노쇼 관리 +
  • +
  • setNavValue('comment')}> + 댓글 관리 +
  • +
  • setNavValue('room')}> + 방 관리 +
  • +
+ {navValue === 'noshow' && } + {navValue === 'comment' && } + {navValue === 'room' && } +
+ + ); +} diff --git a/components/admin/party/PartyRoomTable.tsx b/components/admin/party/PartyRoomTable.tsx new file mode 100644 index 000000000..7c95d6ac0 --- /dev/null +++ b/components/admin/party/PartyRoomTable.tsx @@ -0,0 +1,104 @@ +import { useState } from 'react'; +import { useSetRecoilState } from 'recoil'; +import { + Paper, + Table, + TableBody, + TableCell, + TableContainer, + TableRow, +} from '@mui/material'; +import { PartyRoomColumn } from 'types/admin/adminPartyTypes'; +import { dateToStringShort } from 'utils/handleTime'; +import { modalState } from 'utils/recoil/modal'; +import { tableFormat } from 'constants/admin/table'; +import AdminSearchBar from 'components/admin/common/AdminSearchBar'; +import { AdminTableHead } from 'components/admin/common/AdminTable'; +import PageNation from 'components/Pagination'; +import useAdminPartyRoomList from 'hooks/party/useAdminPartyRoomList'; +import styles from 'styles/admin/party/AdminPartyCommon.module.scss'; + +const tableTitle: { [key: string]: string } = { + roomId: 'ID', + title: '제목', + categoryName: '카테고리', + createDate: '생성일', + dueDate: '마감일', + creatorIntraId: '작성자', + roomStatus: '상태', // 숨김 보이기 표시 + etc: '기타', +}; + +export default function PartyRoomTable() { + const setModal = useSetRecoilState(modalState); + const [currentPage, setCurrentPage] = useState(1); + const { partyRooms, totalPages } = useAdminPartyRoomList({ + page: currentPage, + }); + // const [searchKeyword, setSearchKeyword] = useState(''); + + const rooms: PartyRoomColumn[] = partyRooms.map((room) => ({ + roomId: room.roomId, + title: room.title, + categoryName: room.categoryName, + createDate: dateToStringShort(new Date(room.createDate)), + dueDate: dateToStringShort(new Date(room.dueDate)), + creatorIntraId: room.creatorIntraId ?? '', + roomStatus: room.status, + })); + + return ( +
+
+ 파티방 관리 + {/* { + setSearchKeyword(keyword ?? ''); + // updateRoomsByTitle(searchKeyword); + }} + /> */} +
+ + + + + {rooms.map((room) => ( + + {tableFormat['partyRoom'].columns.map((columnName) => ( + + {columnName !== 'etc' ? ( +
+ {room[columnName as keyof PartyRoomColumn] ?? '없음'} +
+ ) : ( + + )} +
+ ))} +
+ ))} +
+
+
+
+ { + setCurrentPage(pageNumber); + }} + /> +
+
+ ); +} diff --git a/components/admin/party/PartyTemplate.tsx b/components/admin/party/PartyTemplate.tsx new file mode 100644 index 000000000..0ddd656b9 --- /dev/null +++ b/components/admin/party/PartyTemplate.tsx @@ -0,0 +1,106 @@ +import React, { useEffect } from 'react'; +import { useSetRecoilState } from 'recoil'; +import { + Paper, + Table, + TableBody, + TableCell, + TableContainer, + TableRow, +} from '@mui/material'; +import { PartyGameTemplate } from 'types/partyTypes'; +import { modalState } from 'utils/recoil/modal'; +import { tableFormat } from 'constants/admin/table'; +import { AdminTableHead } from 'components/admin/common/AdminTable'; +import { usePartyTemplate } from 'hooks/party/usePartyTemplate'; +import styles from 'styles/admin/party/AdminPartyCommon.module.scss'; + +const tableTitle: { [key: string]: string } = { + gameTemplateId: '템플릿번호', + categoryId: '카테고리', + gameName: '템플릿이름', + maxGamePeople: '최대인원', + minGamePeople: '최소인원', + maxGameTime: '최대게임시간', + minGameTime: '최소게임시간', + genre: '장르', + difficulty: '난이도', + summary: '요약', + change: '수정', + delete: '삭제', +}; + +export default function PartyTemplate() { + const { templates, deleteTemplate } = usePartyTemplate(); + const setModal = useSetRecoilState(modalState); + + useEffect(() => { + console.log('Render'); + }, [templates]); + + const handleEditTemplate = (template?: PartyGameTemplate) => { + setModal({ modalName: 'ADMIN-PARTY_TEMPLATE', template }); + }; + + const handleAddTemplate = () => { + setModal({ modalName: 'ADMIN-PARTY_TEMPLATE' }); + }; + + const deleteHandler = (gameTemplateId: number) => { + deleteTemplate({ gameTemplateId }); + }; + + return ( +
+
+
+ 템플릿 관리 + +
+ + + + + {templates.map((t) => ( + + {tableFormat['partyTemplate'].columns.map((columnName) => { + return ( + + {columnName === 'change' && ( + + )} + {columnName === 'delete' ? ( + + ) : ( + t[columnName as keyof PartyGameTemplate]?.toString() + )} + + ); + })} + + ))} + +
+
+
+
+ ); +} diff --git a/components/main/PartyPreview.tsx b/components/main/PartyPreview.tsx new file mode 100644 index 000000000..766c00f9d --- /dev/null +++ b/components/main/PartyPreview.tsx @@ -0,0 +1,35 @@ +import { useRouter } from 'next/router'; +import usePartyRoomList from 'hooks/party/usePartyRoomList'; +import styles from 'styles/main/PartyPreview.module.scss'; +export default function PartyPreview() { + const { partyRooms } = usePartyRoomList(); + const openRooms = partyRooms.filter((room) => room.status === 'OPEN'); + const limitedRooms = openRooms.slice(0, 3); + const router = useRouter(); + + const movePartyRoom = (roomId: number) => { + router.push(`/party/${roomId}`); + }; + return ( +
+ {limitedRooms.length === 0 ? ( +
현재 활성화된 방이없습니다.
+ ) : ( +
    + {limitedRooms.map((room) => ( +
  • movePartyRoom(room.roomId)} + > +
    +
    {room.title}
    +
    {`${room.currentPeople}/${room.maxPeople}`}
    +
    +
  • + ))} +
+ )} +
+ ); +} diff --git a/components/main/Section.tsx b/components/main/Section.tsx index 1c4019eca..67e561f73 100644 --- a/components/main/Section.tsx +++ b/components/main/Section.tsx @@ -5,6 +5,7 @@ import GameResult from 'components/game/GameResult'; import TournamentPreview from 'components/main/TournamentPreview'; import RankListMain from 'components/rank/topRank/RankListMain'; import styles from 'styles/main/Section.module.scss'; +import PartyPreview from './PartyPreview'; type SectionProps = { sectionTitle: string; @@ -18,6 +19,7 @@ export default function Section({ sectionTitle, path }: SectionProps) { const pathCheck: pathType = { game: , rank: , + party: , tournament: , }; diff --git a/components/modal/ModalProvider.tsx b/components/modal/ModalProvider.tsx index abbf1aa7f..cd1f462ae 100644 --- a/components/modal/ModalProvider.tsx +++ b/components/modal/ModalProvider.tsx @@ -6,6 +6,7 @@ import AdminModal from 'components/modal/modalType/AdminModal'; import NormalModal from 'components/modal/modalType/NormalModal'; import StoreModal from 'components/modal/modalType/StoreModal'; import styles from 'styles/modal/Modal.module.scss'; +import PartyModal from './modalType/PartyModal'; import TournamentModal from './modalType/TournamentModal'; export default function ModalProvider() { @@ -46,6 +47,8 @@ export default function ModalProvider() { ) : modalType === 'TOURNAMENT' ? ( + ) : modalType === 'PARTY' ? ( + ) : null}
) diff --git a/components/modal/Party/PartyReportModal.tsx b/components/modal/Party/PartyReportModal.tsx new file mode 100644 index 000000000..7cbb04605 --- /dev/null +++ b/components/modal/Party/PartyReportModal.tsx @@ -0,0 +1,114 @@ +import { AxiosError } from 'axios'; +import { useState } from 'react'; +import { useSetRecoilState } from 'recoil'; +import { Modal, PartyReportModalData } from 'types/modalTypes'; +import { instance } from 'utils/axios'; +import { modalState } from 'utils/recoil/modal'; +import { toastState } from 'utils/recoil/toast'; +import styles from 'styles/modal/menu/ReportModal.module.scss'; +import { ModalButton, ModalButtonContainer } from '../ModalButton'; + +export function PartyReportModal({ report }: { report: PartyReportModalData }) { + const [isLoading, setIsLoading] = useState(false); + const [content, setContent] = useState(''); + const setModal = useSetRecoilState(modalState); + const setSnackbar = useSetRecoilState(toastState); + + const reportHandler = async () => { + const reportResponse: { [key: string]: string } = { + SUCCESS: '신고해주셔서 감사합니다 ❤️', + REJECT: '내용을 적어주세요 ❤️', + }; + + if (!content.replace(/^\s+|\s+$/g, '')) { + alert('칸을 입력하지 않았습니다.'); + throw new Error('REJECT'); + } + + try { + switch (report.name) { + case 'COMMENT': + await instance.post(`/party/reports/comments/${report.commentId}`, { + content: content, + }); + break; + case 'ROOM': + await instance.post(`/party/reports/rooms/${report.roomId}`, { + content: content, + }); + break; + case 'NOSHOW': + await instance.post( + `/party/reports/rooms/${report.roomId}/users/${report.userIntraId}`, + { content: content } + ); + break; + } + setModal({ modalName: null }); + setSnackbar({ + toastName: `report request`, + severity: 'success', + message: `${reportResponse.SUCCESS}`, + clicked: true, + }); + } catch (e) { + const error = e as AxiosError; + if (error.response && error.response.data) { + const message = (error.response.data as { message: string }).message; + setSnackbar({ + toastName: `bad request`, + severity: 'error', + message: `🔥 ${message} 🔥`, + clicked: true, + }); + } + throw new Error('REJECT'); + } + }; + + const handleReport = () => { + setIsLoading(true); + reportHandler().catch(() => setIsLoading(false)); + }; + + const reportName = + report.name === 'NOSHOW' + ? `${report.userIntraId} 노쇼 신고` + : report.name === 'COMMENT' + ? '댓글 신고' + : '방 신고'; + + return ( +
+
+
42GG
+
{reportName}
+
+
+
+
+