Files
operationSystem-front/src/pages/ServiceManage/ReportList.js
2025-02-12 18:29:27 +09:00

345 lines
12 KiB
JavaScript

import { Fragment, useEffect, useState } from 'react';
import CheckBox from '../../components/common/input/CheckBox';
import styled from 'styled-components';
import { Title, FormWrapper, TableInfo, ListCount, ListOption, TableStyle, SelectInput, TableWrapper, ButtonClose, ModalText, BtnWrapper } from '../../styles/Components';
import Button from '../../components/common/button/Button';
import { ReportListDetailModal, ReportListAnswerModal, ReportListSearchBar, ReportListSummary } from '../../components/ServiceManage';
import Modal from '../../components/common/modal/Modal';
import { useNavigate } from 'react-router-dom';
import { authList } from '../../store/authList';
import { useRecoilValue } from 'recoil';
import { ReportListView, ReportListDetailView, ReportReplyDetail } from '../../apis/Report';
import Pagination from '../../components/common/Pagination/Pagination';
import { convertKTC } from '../../utils';
import AuthModal from '../../components/common/modal/AuthModal';
import { authType } from '../../assets/data';
import ViewTableInfo from '../../components/common/Table/ViewTableInfo';
const reportType = [
{ value: 'ALL', name: '전체' },
{ value: 'UNMANNERED_ACT', name: '비매너 행위' },
{ value: 'USE_UNHEALTHY_NAMES', name: '불건전 이름 사용' },
{ value: 'CASH_TRADING', name: '현금거래 행위' },
{ value: 'INTERFERENCE_GAME', name: '게임 진행 방해' },
{ value: 'INTERFERENCE_SERVICE', name: '운영서비스 방해' },
{ value: 'ACCOUNT_EXPLOITATION', name: '계정도용' },
{ value: 'BUG_ABUSING', name: '버그/어뷰징' },
{ value: 'USE_HACK', name: '불법프로그램 사용' },
{ value: 'LEAK_PERSONAL_INFO', name: '개인정보 유출' },
{ value: 'PRETENDING_GM', name: '운영자 사칭' },
];
const ReportList = () => {
const navigate = useNavigate();
const token = sessionStorage.getItem('token');
const userInfo = useRecoilValue(authList);
// 권한 설정용
let deleteAuth = userInfo.auth_list && userInfo.auth_list.some(auth => auth.id === 31); // 삭제 권한
let replyAuth = userInfo.auth_list && userInfo.auth_list.some(auth => auth.id === 31); // 답변 권한
let d = new Date();
const START_DATE = new Date(new Date(d.setDate(d.getDate() - 1)).setHours(0, 0, 0, 0));
const END_DATE = new Date();
// 페이징용
const [currentPage, setCurrentPage] = useState(1);
const [pageSize, setPageSize] = useState(50);
const [selectedRow, setSelectedRow] = useState([]);
const [searchData, setSearchData] = useState({
startDate: START_DATE,
endDate: END_DATE,
reportType: 'ALL',
status: 'ALL',
searchType: 'ALL',
searchKey: '',
});
const [orderBy, setOrderBy] = useState('DESC');
const [detailView, setDetailView] = useState('hidden');
const [answerView, setAnswerView] = useState('hidden');
const [dataList, setDataList] = useState([]);
// 신고내역 상세 조회용
const [detailData, setDetailData] = useState([]);
// 신고답변 상세 조회용
const [replyData, setReplyData] = useState([]);
const [pkId, setPkId] = useState('');
const [skId, setSkId] = useState('');
const [deleteModalClose, setDeleteModalClose] = useState('hidden');
const [confirmModalClose, setConfirmModalClose] = useState('hidden');
useEffect(() => {
fetchData(START_DATE, END_DATE, 'ALL', 'ALL', 'ALL', '');
}, [currentPage]);
const fetchData = async (startDate, endDate, reportType, status, searchType, searchKey, order, size) => {
await ReportListView(
token,
startDate && new Date(startDate).toISOString().split('.')[0],
endDate && new Date(endDate).toISOString().split('.')[0],
reportType && reportType,
status && status,
searchType && searchType,
searchKey && searchKey,
order ? order : orderBy,
size ? size : pageSize,
currentPage,
).then(data => {
setDataList(data);
})
};
const handlePageSize = e => {
const size = e.target.value;
setPageSize(size);
setCurrentPage(1);
fetchData(searchData.startDate, searchData.endDate, searchData.reportType, searchData.status, searchData.searchType, searchData.searchKey, orderBy, size, 1);
};
const handleDetail = async (e, pk, sk) => {
const pkData = encodeURIComponent(pk);
const skData = encodeURIComponent(sk);
e.preventDefault();
setPkId(pk);
setSkId(sk);
setDetailData(await ReportListDetailView(token, pkData, skData));
handleDetailView();
};
// 상세 정보 모달 띄우기
const handleDetailView = () => {
if (detailView === 'hidden') {
setDetailView('block');
} else {
setDetailView('hidden');
}
};
// 신고 답변 불러오기
const handleReply = async e => {
const pk = encodeURIComponent(pkId);
const sk = encodeURIComponent(skId);
setReplyData(await ReportReplyDetail(token, pk, sk));
handleReplyView();
};
// 답변 모달 띄우기
const handleReplyView = () => {
if (answerView === 'hidden') {
setDetailView('hidden');
setAnswerView('block');
} else {
setAnswerView('hidden');
setDetailView('block');
}
};
// 검색 함수
const handleSearch = (startDate, endDate, reportType, status, searchType, searchKey) => {
fetchData(startDate && new Date(startDate).toISOString(), endDate && new Date(endDate).toISOString(), reportType, status, searchType, searchKey, orderBy, pageSize);
};
// 오름차순 내림차순
const handleOrderBy = e => {
const order = e.target.value;
setOrderBy(order);
fetchData(
searchData.startDate && new Date(searchData.startDate).toISOString().split('.')[0],
searchData.endDate && new Date(searchData.endDate).toISOString().split('.')[0],
searchData.reportType,
searchData.status,
searchData.searchKey,
order,
pageSize,
);
};
// 선택 삭제 함수
const handleSelectedDelete = () => {
let list = [];
selectedRow.map(data =>
list.push({
id: data,
}),
);
// ReportDelete(token, list);
handleDeleteModalClose();
handleConfirmeModalClose();
};
// 선택 삭제 모달
const handleDeleteModalClose = () => {
if (selectedRow.length !== 0 && deleteModalClose === 'hidden') {
setDeleteModalClose('view');
} else {
setDeleteModalClose('hidden');
}
};
// 삭제, 승인, 저장 확인 모달창
const handleConfirmeModalClose = () => {
if (confirmModalClose === 'hidden') {
setConfirmModalClose('view');
} else {
setConfirmModalClose('hidden');
window.location.reload();
}
};
// 체크박스 선택 리스트
const handleSelectCheckBox = e => {
let list = [...selectedRow];
if (e.target.checked) {
list.push(e.target.id);
setSelectedRow(list);
} else {
const filterList = list.filter(data => e.target.id !== data);
setSelectedRow(filterList);
}
};
// 전체 선택 구현
const handleAllSelect = () => {
let list = [];
if (document.getElementById('check-all').checked === true) {
dataList.list &&
dataList.list.map((data, index) => {
document.getElementsByName('select')[index].checked = true;
list.push(String(data.id));
});
} else if (document.getElementById('check-all').checked === false) {
for (let i = 0; i < dataList.list.length; i++) {
dataList.list && dataList.list.map((data, index) => (document.getElementsByName('select')[index].checked = false));
list = [];
}
}
setSelectedRow(list);
};
const handleCountSelectedRow = () => {
return currentPage > (dataList && dataList.total) / pageSize ? selectedRow.length === dataList.total % pageSize : selectedRow.length === Number(pageSize);
};
return (
<>
{userInfo.auth_list && !userInfo.auth_list.some(auth => auth.id === authType.reportRead) ? (
<AuthModal/>
) : (
<>
<Title>신고내역 조회 답변</Title>
<ReportListSummary />
<FormWrapper>
<ReportListSearchBar handleSearch={handleSearch} setResultData={setSearchData} />
</FormWrapper>
<ViewTableInfo handlePageSize={handlePageSize} handleOrderBy={handleOrderBy} total={dataList.total} total_all={dataList.total_all}>
{deleteAuth && <Button theme={'disable'} text="선택 삭제" />}
</ViewTableInfo>
<TableWrapper>
<TableStyle>
<caption></caption>
<thead>
<tr>
<th width="40">
<CheckBox id="check-all" handleCheck={handleAllSelect} checked={handleCountSelectedRow()} />
</th>
<th width="80">번호</th>
<th width="180">신고일자</th>
<th width="200">신고자</th>
<th width="15%">신고 유형</th>
<th width="110">확인 / 답변</th>
<th width="90">상태</th>
<th width="180">해결 일자</th>
<th width="15%">담당자(이메일주소)</th>
{deleteAuth && <th width="80">삭제</th>}
</tr>
</thead>
<tbody>
{dataList.list &&
dataList.list.map((report, index) => (
<Fragment key={index}>
<tr>
<td>
<CheckBox name={'select'} id={report.row_num} setData={e => handleSelectCheckBox(e)} />
</td>
<td>{report.row_num}</td>
<td>{convertKTC(report.create_time, false)}</td>
<td>{report.reporter_nickname}</td>
<td>{reportType.map(data => data.value === report.report_type && data.name)}</td>
<td>
<Button theme="line" text="상세보기" handleClick={e => handleDetail(e, report.pk, report.sk)} />
</td>
<td>{report.state === 'UNRESOLVED' ? <ListState>미해결</ListState> : ''}</td>
<td>
{report.resolution_time && convertKTC(report.resolution_time, false)}
</td>
<td>{report.manager_email}</td>
{deleteAuth && (
<td>
<Button theme="line" text="삭제" />
</td>
)}
</tr>
</Fragment>
))}
</tbody>
</TableStyle>
</TableWrapper>
<Pagination postsPerPage={pageSize} totalPosts={dataList && dataList.total_all} setCurrentPage={setCurrentPage} currentPage={currentPage} pageLimit={10} />
<ReportListDetailModal detailView={detailView} handleReply={handleReply} handleDetailView={handleDetailView} detailData={detailData} replyData={replyData} replyAuth={replyAuth} />
<ReportListAnswerModal answerView={answerView} setAnswerView={setAnswerView} detailData={detailData} replyData={replyData} pkId={pkId} skId={skId} />
{/* 선택 삭제 모달 */}
<Modal min="440px" $padding="40px" $bgcolor="transparent" $view={deleteModalClose}>
<BtnWrapper $justify="flex-end">
<ButtonClose onClick={handleDeleteModalClose} />
</BtnWrapper>
<ModalText $align="center">
선택된 우편을 삭제하시겠습니까?
<br />
삭제 설정 정보가 제거됩니다.
</ModalText>
<BtnWrapper $gap="10px">
<Button text="취소" theme="line" size="large" width="100%" handleClick={handleDeleteModalClose} />
<Button text="확인" theme="primary" type="submit" size="large" width="100%" handleClick={handleSelectedDelete} />
</BtnWrapper>
</Modal>
{/* 확인 모달 */}
<Modal min="440px" $padding="40px" $bgcolor="transparent" $view={confirmModalClose}>
<BtnWrapper $justify="flex-end">
<ButtonClose onClick={handleConfirmeModalClose} />
</BtnWrapper>
<ModalText $align="center">삭제가 완료되었습니다.</ModalText>
<BtnWrapper $gap="10px">
<Button text="확인" theme="primary" type="submit" size="large" width="100%" handleClick={handleConfirmeModalClose} />
</BtnWrapper>
</Modal>
</>
)}
</>
);
};
export default ReportList;
const ListState = styled.span`
color: #d60000;
`;