Log currency 관련 API 호출 추가
components 정리에 따른 호출 위치 수정 excelExportButton에 functionName 추가 게임 로그조회 수정
This commit is contained in:
119
src/apis/Log.js
119
src/apis/Log.js
@@ -1,6 +1,6 @@
|
||||
//운영 정보 관리 - 로그 api 연결
|
||||
|
||||
import { Axios } from '../utils';
|
||||
import { Axios, responseFileDownload } from '../utils';
|
||||
|
||||
// 비즈니스 로그 조회
|
||||
export const BusinessLogList = async (token, params) => {
|
||||
@@ -25,67 +25,9 @@ export const BusinessLogExport = async (token, params) => {
|
||||
responseType: 'blob',
|
||||
timeout: 300000
|
||||
}).then(response => {
|
||||
if (!response.data) {
|
||||
console.log(response);
|
||||
throw new Error('No data received');
|
||||
}
|
||||
|
||||
const contentType = response.headers['content-type'] || response.headers['Content-Type'];
|
||||
const contentDisposition = response.headers['content-disposition'] || response.headers['Content-Disposition'];
|
||||
|
||||
// Excel이나 ZIP 파일이 아닌 경우
|
||||
if (!contentType.includes('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') &&
|
||||
!contentType.includes('application/zip')) {
|
||||
console.log(response);
|
||||
throw new Error(`잘못된 파일 형식입니다. Content-Type: ${contentType}`);
|
||||
}
|
||||
|
||||
let fileName = 'businessLog';
|
||||
let fileExtension = '.xlsx';
|
||||
let mimeType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
|
||||
|
||||
// ZIP 파일인지 확인
|
||||
if (contentType && contentType.includes('application/zip')) {
|
||||
fileExtension = '.zip';
|
||||
mimeType = 'application/zip';
|
||||
fileName = 'businessLog_multiple_files';
|
||||
}
|
||||
|
||||
// Content-Disposition에서 파일명 추출
|
||||
if (contentDisposition) {
|
||||
const fileNameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
|
||||
if (fileNameMatch && fileNameMatch[1]) {
|
||||
const extractedFileName = decodeURIComponent(fileNameMatch[1].replace(/['"]/g, ''));
|
||||
fileName = extractedFileName;
|
||||
}
|
||||
} else {
|
||||
// Content-Disposition이 없으면 기본 파일명 사용
|
||||
fileName = fileName + fileExtension;
|
||||
}
|
||||
|
||||
const blob = new Blob([response.data], { type: mimeType });
|
||||
|
||||
// 빈 파일 체크
|
||||
if (blob.size === 0) {
|
||||
throw new Error('다운로드된 파일이 비어있습니다.');
|
||||
}
|
||||
|
||||
// 너무 작은 파일 체크 (실제 Excel 파일은 최소 몇 KB 이상)
|
||||
if (blob.size < 1024) { // 1KB 미만
|
||||
throw new Error('파일 크기가 너무 작습니다. 올바른 Excel 파일이 아닐 수 있습니다.');
|
||||
}
|
||||
|
||||
const href = URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = href;
|
||||
link.download = fileName;
|
||||
link.style.display = 'none';
|
||||
link.rel = 'noopener noreferrer';
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
|
||||
link.remove();
|
||||
window.URL.revokeObjectURL(href);
|
||||
responseFileDownload(response, {
|
||||
defaultFileName: 'businessLog'
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
@@ -112,4 +54,57 @@ export const getExcelProgress = async (token, taskId) => {
|
||||
console.error('Progress API error:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const getCurrencyList = async (token, startDate, endDate, order, size, currentPage) => {
|
||||
try {
|
||||
const response = await Axios.get(`/api/v1/log/currency/list?start_dt=${startDate}&end_dt=${endDate}&orderby=${order}&page_no=${currentPage}
|
||||
&page_size=${size}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
return response.data.data;
|
||||
} catch (error) {
|
||||
console.error('getCurrencyList API error:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const getCurrencyDetailList = async (token, searchType, searchData, tranId, startDate, endDate, order, size, currentPage) => {
|
||||
try {
|
||||
const response = await Axios.get(`/api/v1/log/currency/detail/list?search_type=${searchType}&search_data=${searchData}&tran_id=${tranId}&start_dt=${startDate}&end_dt=${endDate}
|
||||
&orderby=${order}&page_no=${currentPage}&page_size=${size}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error('getCurrencyDetailList API error:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const GameCurrencyLogExport = async (token, params) => {
|
||||
try {
|
||||
await Axios.post(`/api/v1/log/currency/detail/excel-export`, params, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
responseType: 'blob',
|
||||
timeout: 300000
|
||||
}).then(response => {
|
||||
|
||||
responseFileDownload(response, {
|
||||
defaultFileName: 'gameCurrencyLog'
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
throw new Error('BusinessLogExport Error', e);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -17,6 +17,7 @@ export * from './Calium';
|
||||
export * from './Land';
|
||||
export * from './Menu';
|
||||
export * from './OpenAI';
|
||||
export * from './Log';
|
||||
|
||||
const apiModules = {};
|
||||
const allApis = {};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export {authType, ivenTabType, modalTypes, TabList, tattooSlot, commonStatus, ViewTitleCountType, landAuctionStatusType} from './types'
|
||||
export {authType, ivenTabType, modalTypes, TabUserList, tattooSlot, commonStatus, ViewTitleCountType, landAuctionStatusType} from './types'
|
||||
export {
|
||||
mailSendType,
|
||||
mailType,
|
||||
@@ -7,7 +7,7 @@ export {
|
||||
adminLevelType,
|
||||
logOption,
|
||||
eventStatus,
|
||||
currencyType,
|
||||
currencyItemCode,
|
||||
blockStatus,
|
||||
blockSanctions,
|
||||
blockPeriod,
|
||||
@@ -27,5 +27,6 @@ export {
|
||||
opYNType,
|
||||
opUserSessionType,
|
||||
opMailType,
|
||||
amountDeltaType
|
||||
} from './options'
|
||||
export {benItems, MinuteList, HourList, caliumRequestInitData, STATUS_STYLES, months, PAGE_SIZE_OPTIONS, ORDER_OPTIONS} from './data'
|
||||
@@ -4,6 +4,20 @@ export const languageType = [
|
||||
{ value: 'JA', name: '일본어' },
|
||||
];
|
||||
|
||||
export const TabGameLogList = [
|
||||
{ value: 'CURRENCY', name: '재화 로그' },
|
||||
{ value: 'ITEM', name: '아이템 로그' },
|
||||
// { value: 'TRADE', name: '거래 로그' },
|
||||
];
|
||||
|
||||
export const TabEconomicIndexList = [
|
||||
{ value: 'CURRENCY', name: '재화' },
|
||||
{ value: 'ITEM', name: '아이템' },
|
||||
// { value: 'VBP', name: 'VBP' },
|
||||
// { value: 'deco', name: '의상/타투' },
|
||||
// { value: 'instance', name: '인스턴스' },
|
||||
];
|
||||
|
||||
export const mailSendType = [
|
||||
{ value: 'ALL', name: '전체' },
|
||||
{ value: 'RESERVE_SEND', name: '예약 발송' },
|
||||
@@ -81,7 +95,7 @@ export const landAuctionStatus = [
|
||||
{ value: 'FAIL', name: '실패' },
|
||||
];
|
||||
|
||||
export const currencyType = [
|
||||
export const currencyItemCode = [
|
||||
{ value: '19010001', name: '골드' },
|
||||
{ value: '19010002', name: '사파이어' },
|
||||
{ value: '19010005', name: '루비' },
|
||||
@@ -205,6 +219,12 @@ export const CurrencyType = [
|
||||
{value: 'Ruby', name: '루비' }
|
||||
]
|
||||
|
||||
export const amountDeltaType = [
|
||||
{value: 'Acquire', name: '획득' },
|
||||
{value: 'Consume', name: '소모' },
|
||||
{value: 'None', name: '' },
|
||||
]
|
||||
|
||||
export const battleEventStatus = [
|
||||
{ value: 'ALL', name: '전체' },
|
||||
{ value: 'WAIT', name: '대기' },
|
||||
|
||||
@@ -75,7 +75,7 @@ export const adminAuthLevel = {
|
||||
DEVELOPER: "Developer",
|
||||
}
|
||||
|
||||
export const TabList = [
|
||||
export const TabUserList = [
|
||||
{ title: '기본정보' },
|
||||
{ title: '아바타' },
|
||||
{ title: '의상' },
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
TableDetailContainer,
|
||||
TableDetailFlex,
|
||||
TableDetailColumn,
|
||||
DetailTableInfo,
|
||||
DetailTableInfo, DownloadContainer, CircularProgressWrapper,
|
||||
} from '../../styles/Components';
|
||||
|
||||
import { withAuth } from '../../hooks/hook';
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
ViewTableInfo,
|
||||
} from '../../components/common';
|
||||
import { TableSkeleton } from '../../components/Skeleton/TableSkeleton';
|
||||
import BusinessLogSearchBar, { useBusinessLogSearch } from '../../components/ServiceManage/searchBar/BusinessLogSearchBar';
|
||||
import BusinessLogSearchBar, { useBusinessLogSearch } from '../../components/searchBar/BusinessLogSearchBar';
|
||||
import styled from 'styled-components';
|
||||
import CircularProgress from '../../components/common/CircularProgress';
|
||||
// import MessageInput from '../../components/common/input/MessageInput';
|
||||
@@ -34,7 +34,6 @@ import {
|
||||
} from '../../assets/data/adminConstants';
|
||||
import ExcelExportButton from '../../components/common/button/ExcelExportButton';
|
||||
import Pagination from '../../components/common/Pagination/Pagination';
|
||||
import useCommonSearchOld from '../../hooks/useCommonSearchOld';
|
||||
|
||||
const BusinessLogView = () => {
|
||||
const token = sessionStorage.getItem('token');
|
||||
@@ -186,6 +185,7 @@ const BusinessLogView = () => {
|
||||
<ViewTableInfo orderType="asc" pageType="B" total={dataList?.total} total_all={dataList?.total_all} handleOrderBy={handleOrderByChange} handlePageSize={handlePageSizeChange}>
|
||||
<DownloadContainer>
|
||||
<ExcelExportButton
|
||||
functionName="BusinessLogExport"
|
||||
params={searchParams}
|
||||
fileName={t('FILE_BUSINESS_LOG')}
|
||||
onLoadingChange={setDownloadState}
|
||||
@@ -268,16 +268,4 @@ const BusinessLogView = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default withAuth(authType.businessLogRead)(BusinessLogView);
|
||||
|
||||
const DownloadContainer = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
`;
|
||||
|
||||
const CircularProgressWrapper = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
`;
|
||||
export default withAuth(authType.businessLogRead)(BusinessLogView);
|
||||
@@ -4,7 +4,7 @@ import { Fragment, useState } from 'react';
|
||||
|
||||
import { Title, TableStyle, BtnWrapper, ButtonClose, ModalText } from '../../styles/Components';
|
||||
|
||||
import LandSearchBar from '../../components/DataManage/LandSearchBar';
|
||||
import LandSearchBar from '../../components/searchBar/LandSearchBar';
|
||||
import Button from '../../components/common/button/Button';
|
||||
import QuestDetailModal from '../../components/DataManage/QuestDetailModal';
|
||||
import LandDetailModal from '../../components/DataManage/LandDetailModal';
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Fragment, useState } from 'react';
|
||||
|
||||
import { Title, TableStyle, ButtonClose, ModalText, BtnWrapper } from '../../styles/Components';
|
||||
|
||||
import UserSearchBar from '../../components/DataManage/UserSearchBar';
|
||||
import UserSearchBar from '../../components/searchBar/UserSearchBar';
|
||||
import Modal from '../../components/common/modal/Modal';
|
||||
import Button from '../../components/common/button/Button';
|
||||
|
||||
|
||||
@@ -4,23 +4,33 @@ import { Link } from 'react-router-dom';
|
||||
import Button from '../../components/common/button/Button';
|
||||
import Pagination from '../../components/common/Pagination/Pagination';
|
||||
|
||||
import DatePicker, { registerLocale } from 'react-datepicker';
|
||||
import { registerLocale } from 'react-datepicker';
|
||||
import { ko } from 'date-fns/esm/locale';
|
||||
import 'react-datepicker/dist/react-datepicker.css';
|
||||
import { getMonth, getYear } from 'date-fns';
|
||||
import range from 'lodash/range';
|
||||
|
||||
import { Title, SelectInput, BtnWrapper, TableStyle, TableInfo, ListCount, ListOption, ButtonClose, ModalText } from '../../styles/Components';
|
||||
import {
|
||||
Title,
|
||||
SelectInput,
|
||||
BtnWrapper,
|
||||
TableStyle,
|
||||
TableInfo,
|
||||
ListCount,
|
||||
ListOption,
|
||||
ButtonClose,
|
||||
ModalText,
|
||||
TabScroll, TabItem, TabWrapper,
|
||||
} from '../../styles/Components';
|
||||
import { styled } from 'styled-components';
|
||||
|
||||
import ItemLogSearchBar from '../../components/DataManage/ItemLogSearchBar';
|
||||
import GoodsLogSearchBar from '../../components/DataManage/CreditLogSearchBar';
|
||||
import TradeLogSerchBar from '../../components/DataManage/TradeLogSearchBar';
|
||||
import Modal from '../../components/common/modal/Modal';
|
||||
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { authList } from '../../store/authList';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { withAuth } from '../../hooks/hook';
|
||||
import { authType, TabUserList } from '../../assets/data';
|
||||
import { TabGameLogList } from '../../assets/data/options';
|
||||
import CurrencyLogContent from '../../components/DataManage/CurrencyLogContent';
|
||||
|
||||
registerLocale('ko', ko);
|
||||
|
||||
@@ -41,7 +51,6 @@ const ItemLogContent = () => {
|
||||
];
|
||||
return (
|
||||
<>
|
||||
<ItemLogSearchBar />
|
||||
<TableInfo>
|
||||
<ListCount>총 : 117건 / 000 건</ListCount>
|
||||
<ListOption>
|
||||
@@ -98,193 +107,8 @@ const ItemLogContent = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const GoodsLogContent = () => {
|
||||
const mokupData = [
|
||||
{
|
||||
date: '2023-08-05 12:11:32',
|
||||
name: '홍길동',
|
||||
id: '16CD2ECD-4798-46CE-9B6B-F952CF11F196',
|
||||
gold: '99800',
|
||||
blue: '400',
|
||||
black: '500',
|
||||
red: '500',
|
||||
action: '소진',
|
||||
location: '유저 거래',
|
||||
goldchange: '-',
|
||||
bluechange: '-100',
|
||||
blackchange: '-',
|
||||
redchange: '-',
|
||||
key: 'User_trade_key',
|
||||
},
|
||||
];
|
||||
return (
|
||||
<>
|
||||
<GoodsLogSearchBar />
|
||||
<TableInfo>
|
||||
<ListCount>총 : 117건 / 000 건</ListCount>
|
||||
<ListOption>
|
||||
<SelectInput name="" id="" className="input-select">
|
||||
<option value="up">오름차순</option>
|
||||
<option value="down">내림차순</option>
|
||||
</SelectInput>
|
||||
<SelectInput name="" id="" className="input-select">
|
||||
<option value="up">50개</option>
|
||||
<option value="down">100개</option>
|
||||
</SelectInput>
|
||||
<Button theme="line" text="엑셀 다운로드" />
|
||||
</ListOption>
|
||||
</TableInfo>
|
||||
<TableWrapper>
|
||||
<TableStyle>
|
||||
<caption></caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="150">일자</th>
|
||||
<th width="200">아바타명</th>
|
||||
<th width="300">GUID</th>
|
||||
<th width="100">
|
||||
(Total)
|
||||
<br />
|
||||
골드
|
||||
</th>
|
||||
<th width="100">
|
||||
(Total)
|
||||
<br />
|
||||
사파이어
|
||||
</th>
|
||||
<th width="100">
|
||||
(Total)
|
||||
<br />
|
||||
칼리움
|
||||
</th>
|
||||
<th width="100">
|
||||
(Total)
|
||||
<br />
|
||||
오닉시움
|
||||
</th>
|
||||
<th width="80">액션</th>
|
||||
<th width="100">획득 / 소진처</th>
|
||||
<th width="100">
|
||||
(변화량)
|
||||
<br />
|
||||
골드
|
||||
</th>
|
||||
<th width="100">
|
||||
(변화량)
|
||||
<br />
|
||||
사파이어
|
||||
</th>
|
||||
<th width="100">
|
||||
(변화량)
|
||||
<br />
|
||||
칼리움
|
||||
</th>
|
||||
<th width="100">
|
||||
(변화량)
|
||||
<br />
|
||||
오닉시움
|
||||
</th>
|
||||
<th width="300">거래 Key</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{mokupData.map((data, index) => (
|
||||
<Fragment key={index}>
|
||||
<tr>
|
||||
<td>{new Date(data.date).toLocaleString()}</td>
|
||||
<td>{data.name}</td>
|
||||
<td>{data.id}</td>
|
||||
<td>{data.gold}</td>
|
||||
<td>{data.blue}</td>
|
||||
<td>{data.black}</td>
|
||||
<td>{data.red}</td>
|
||||
<td>{data.action}</td>
|
||||
<td>{data.location}</td>
|
||||
<td>{data.goldchange}</td>
|
||||
{/* 변화량 0보다 작을 경우 StateDecrease 적용 */}
|
||||
<td>
|
||||
<StateDecrease>{data.bluechange}</StateDecrease>
|
||||
</td>
|
||||
<td>{data.blackchange}</td>
|
||||
<td>{data.redchange}</td>
|
||||
<td>{data.key}</td>
|
||||
</tr>
|
||||
</Fragment>
|
||||
))}
|
||||
</tbody>
|
||||
</TableStyle>
|
||||
</TableWrapper>
|
||||
<Pagination />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const TradeLogContent = () => {
|
||||
const mokupData = [
|
||||
{
|
||||
date: '2023-08-05 12:11:32',
|
||||
name: '홍길동',
|
||||
trader: '칼리버스',
|
||||
id: '16CD2ECD-4798-46CE-9B6B-F952CF11F196',
|
||||
key: 'User_trade_key',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<TradeLogSerchBar />
|
||||
<TableInfo>
|
||||
<ListCount>
|
||||
총 : 117건 / <span>000</span> 건
|
||||
</ListCount>
|
||||
<ListOption>
|
||||
<SelectInput name="" id="" className="input-select">
|
||||
<option value="up">오름차순</option>
|
||||
<option value="down">내림차순</option>
|
||||
</SelectInput>
|
||||
<SelectInput name="" id="" className="input-select">
|
||||
<option value="up">50개</option>
|
||||
<option value="down">100개</option>
|
||||
</SelectInput>
|
||||
<Button theme="line" text="엑셀 다운로드" />
|
||||
</ListOption>
|
||||
</TableInfo>
|
||||
<TableWrapper>
|
||||
<TableStyle>
|
||||
<caption></caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="150">일자</th>
|
||||
<th width="150">조회 아바타명</th>
|
||||
<th width="150">거래 대상 아바타명</th>
|
||||
<th width="300">거래 대상 GUID</th>
|
||||
<th width="300">거래 Key</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{mokupData.map((data, index) => (
|
||||
<Fragment key={index}>
|
||||
<tr>
|
||||
<td>{new Date(data.date).toLocaleString()}</td>
|
||||
<td>{data.name}</td>
|
||||
<td>{data.trader}</td>
|
||||
<td>{data.id}</td>
|
||||
<td>{data.key}</td>
|
||||
</tr>
|
||||
</Fragment>
|
||||
))}
|
||||
</tbody>
|
||||
</TableStyle>
|
||||
</TableWrapper>
|
||||
<Pagination />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const GameLogView = () => {
|
||||
const navigate = useNavigate();
|
||||
const userInfo = useRecoilValue(authList);
|
||||
const [activeTab, setActiveTab] = useState('itemlog');
|
||||
const [activeTab, setActiveTab] = useState('CURRENCY');
|
||||
|
||||
const handleTab = (e, content) => {
|
||||
e.preventDefault();
|
||||
@@ -292,78 +116,28 @@ const GameLogView = () => {
|
||||
};
|
||||
return (
|
||||
<>
|
||||
{userInfo.auth_list && !userInfo.auth_list.some(auth => auth.id === 14) ? (
|
||||
<Modal min="440px" $padding="40px" $bgcolor="transparent" $view={'view'}>
|
||||
<BtnWrapper $justify="flex-end">
|
||||
<ButtonClose onClick={() => navigate(-1)} />
|
||||
</BtnWrapper>
|
||||
<ModalText $align="center">
|
||||
해당 메뉴에 대한 조회 권한이 없습니다.
|
||||
<br />
|
||||
권한 등급을 변경 후 다시 이용해주세요.
|
||||
</ModalText>
|
||||
<BtnWrapper $gap="10px">
|
||||
<Button text="확인" theme="primary" type="submit" size="large" width="100%" handleClick={() => navigate(-1)} />
|
||||
</BtnWrapper>
|
||||
</Modal>
|
||||
) : (
|
||||
<>
|
||||
<Title>게임로그조회</Title>
|
||||
<TabWrapper>
|
||||
<li>
|
||||
<TabItem $state={activeTab === 'itemlog' ? 'active' : 'none'} onClick={e => handleTab(e, 'itemlog')}>
|
||||
아이템 로그
|
||||
</TabItem>
|
||||
</li>
|
||||
<li>
|
||||
<TabItem $state={activeTab === 'goodslog' ? 'active' : 'none'} onClick={e => handleTab(e, 'goodslog')}>
|
||||
재화 로그
|
||||
</TabItem>
|
||||
</li>
|
||||
<li>
|
||||
<TabItem $state={activeTab === 'tradelog' ? 'active' : 'none'} onClick={e => handleTab(e, 'tradelog')}>
|
||||
거래 로그
|
||||
</TabItem>
|
||||
</li>
|
||||
</TabWrapper>
|
||||
{activeTab === 'itemlog' && <ItemLogContent />}
|
||||
{activeTab === 'goodslog' && <GoodsLogContent />}
|
||||
{activeTab === 'tradelog' && <TradeLogContent />}
|
||||
</>
|
||||
)}
|
||||
<Title>게임 로그 조회</Title>
|
||||
<TabScroll>
|
||||
<TabWrapper>
|
||||
{TabGameLogList.map((el, idx) => {
|
||||
return (
|
||||
<li>
|
||||
<TabItem key={idx} $state={activeTab === el.value ? 'active' : 'none'} onClick={e => handleTab(e, el.value)}>
|
||||
{el.name}
|
||||
</TabItem>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</TabWrapper>
|
||||
</TabScroll>
|
||||
{activeTab === 'ITEM' && <ItemLogContent />}
|
||||
{activeTab === 'CURRENCY' && <CurrencyLogContent />}
|
||||
{/*{activeTab === 'TRADE' && <TradeLogContent />}*/}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default GameLogView;
|
||||
|
||||
const TabItem = styled(Link)`
|
||||
display: inline-flex;
|
||||
width: 120px;
|
||||
height: 30px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: #f9f9f9;
|
||||
border-left: 1px solid #d9d9d9;
|
||||
&:hover {
|
||||
background: #888;
|
||||
color: #fff;
|
||||
}
|
||||
${props =>
|
||||
props.$state === 'active' &&
|
||||
`
|
||||
background: #888;
|
||||
color: #fff;`}
|
||||
`;
|
||||
|
||||
const TabWrapper = styled.ul`
|
||||
display: flex;
|
||||
li:first-child {
|
||||
${TabItem} {
|
||||
border-left: 0;
|
||||
}
|
||||
}
|
||||
`;
|
||||
export default withAuth(authType.gameLogRead)(GameLogView);
|
||||
|
||||
const TableWrapper = styled.div`
|
||||
width: 100%;
|
||||
@@ -383,7 +157,3 @@ const TableWrapper = styled.div`
|
||||
min-width: max-content;
|
||||
}
|
||||
`;
|
||||
|
||||
const StateDecrease = styled.span`
|
||||
color: #d60000;
|
||||
`;
|
||||
|
||||
@@ -25,9 +25,9 @@ import {
|
||||
import { INITIAL_PAGE_LIMIT, INITIAL_PAGE_SIZE, TYPE_MODIFY } from '../../assets/data/adminConstants';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { CheckBox, DynamicModal, ExcelDownButton, Pagination, ViewTableInfo } from '../../components/common';
|
||||
import LandInfoSearchBar, { useLandInfoSearch } from '../../components/ServiceManage/searchBar/LandInfoSearchBar';
|
||||
import LandInfoSearchBar, { useLandInfoSearch } from '../../components/searchBar/LandInfoSearchBar';
|
||||
import { TableSkeleton } from '../../components/Skeleton/TableSkeleton';
|
||||
import OwnerChangeModal from '../../components/ServiceManage/modal/OwnerChangeModal';
|
||||
import OwnerChangeModal from '../../components/modal/OwnerChangeModal';
|
||||
import { opLandInfoStatusType } from '../../assets/data/options';
|
||||
import { useAlert } from '../../context/AlertProvider';
|
||||
import { alertTypes } from '../../assets/data/types';
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { useState, Fragment } from 'react';
|
||||
|
||||
import { Title, BtnWrapper, ButtonClose, ModalText } from '../../styles/Components';
|
||||
import { TabScroll, Title } from '../../styles/Components';
|
||||
|
||||
import styled from 'styled-components';
|
||||
|
||||
import UserViewSearchBar from '../../components/DataManage/UserViewSearchBar';
|
||||
import UserViewSearchBar from '../../components/searchBar/UserViewSearchBar';
|
||||
import UserDefaultInfo from '../../components/DataManage/UserDefaultInfo';
|
||||
import UserAvatarInfo from '../../components/DataManage/UserAvatarInfo';
|
||||
import UserDressInfo from '../../components/DataManage/UserDressInfo';
|
||||
@@ -16,17 +16,14 @@ import UserFriendInfo from '../../components/DataManage/UserFriendInfo';
|
||||
import UserTatttooInfo from '../../components/DataManage/UserTattooInfo';
|
||||
import UserQuestInfo from '../../components/DataManage/UserQuestInfo';
|
||||
import UserClaimInfo from '../../components/DataManage/UserClaimInfo';
|
||||
import Modal from '../../components/common/modal/Modal';
|
||||
import Button from '../../components/common/button/Button';
|
||||
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { authList } from '../../store/authList';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import AuthModal from '../../components/common/modal/AuthModal';
|
||||
import { authType, TabList } from '../../assets/data';
|
||||
import { authType, TabUserList } from '../../assets/data';
|
||||
|
||||
const UserView = () => {
|
||||
const navigate = useNavigate();
|
||||
const userInfo = useRecoilValue(authList);
|
||||
|
||||
const [infoView, setInfoView] = useState('none');
|
||||
@@ -48,7 +45,7 @@ const UserView = () => {
|
||||
<UserWrapper display={infoView}>
|
||||
<TabScroll>
|
||||
<UserTabWrapper>
|
||||
{TabList.map((el, idx) => {
|
||||
{TabUserList.map((el, idx) => {
|
||||
return (
|
||||
<UserTab key={idx} $state={el.title === activeContent ? 'active' : 'unactive'} onClick={() => handleTab(el.title)}>
|
||||
{el.title}
|
||||
@@ -102,10 +99,7 @@ const UserTab = styled.li`
|
||||
color: #fff;
|
||||
background: #888;`}
|
||||
`;
|
||||
const TabScroll = styled.div`
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
`;
|
||||
|
||||
const UserTabWrapper = styled.ul`
|
||||
border-bottom: 1px solid #888888;
|
||||
display: flex;
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Link } from 'react-router-dom';
|
||||
|
||||
import Button from '../../components/common/button/Button';
|
||||
|
||||
import { Title, BtnWrapper, ButtonClose, ModalText } from '../../styles/Components';
|
||||
import { Title, BtnWrapper, ButtonClose, ModalText, TabItem, TabScroll, TabWrapper } from '../../styles/Components';
|
||||
import { styled } from 'styled-components';
|
||||
|
||||
import Modal from '../../components/common/modal/Modal';
|
||||
@@ -17,11 +17,14 @@ import VBPContent from '../../components/IndexManage/VBPContent';
|
||||
import ItemContent from '../../components/IndexManage/ItemContent';
|
||||
import InstanceContent from '../../components/IndexManage/InstanceContent';
|
||||
import DecoContent from '../../components/IndexManage/DecoContent';
|
||||
import { withAuth } from '../../hooks/hook';
|
||||
import { authType } from '../../assets/data';
|
||||
import { TabEconomicIndexList, TabGameLogList } from '../../assets/data/options';
|
||||
|
||||
const EconomicIndex = () => {
|
||||
const navigate = useNavigate();
|
||||
const userInfo = useRecoilValue(authList);
|
||||
const [activeTab, setActiveTab] = useState('credit');
|
||||
const [activeTab, setActiveTab] = useState('CURRENCY');
|
||||
|
||||
const handleTab = (e, content) => {
|
||||
e.preventDefault();
|
||||
@@ -29,86 +32,27 @@ const EconomicIndex = () => {
|
||||
};
|
||||
return (
|
||||
<>
|
||||
{userInfo.auth_list && !userInfo.auth_list.some(auth => auth.id === 10) ? (
|
||||
<Modal min="440px" $padding="40px" $bgcolor="transparent" $view={'view'}>
|
||||
<BtnWrapper $justify="flex-end">
|
||||
<ButtonClose onClick={() => navigate(-1)} />
|
||||
</BtnWrapper>
|
||||
<ModalText $align="center">
|
||||
해당 메뉴에 대한 조회 권한이 없습니다.
|
||||
<br />
|
||||
권한 등급을 변경 후 다시 이용해주세요.
|
||||
</ModalText>
|
||||
<BtnWrapper $gap="10px">
|
||||
<Button text="확인" theme="primary" type="submit" size="large" width="100%" handleClick={() => navigate(-1)} />
|
||||
</BtnWrapper>
|
||||
</Modal>
|
||||
) : (
|
||||
<>
|
||||
<Title>경제 지표</Title>
|
||||
<TabWrapper>
|
||||
<li>
|
||||
<TabItem $state={activeTab === 'credit' ? 'active' : 'none'} onClick={e => handleTab(e, 'credit')}>
|
||||
재화
|
||||
</TabItem>
|
||||
</li>
|
||||
<li>
|
||||
<TabItem $state={activeTab === 'vbp' ? 'active' : 'none'} onClick={e => handleTab(e, 'vbp')}>
|
||||
VBP
|
||||
</TabItem>
|
||||
</li>
|
||||
<li>
|
||||
<TabItem $state={activeTab === 'item' ? 'active' : 'none'} onClick={e => handleTab(e, 'item')}>
|
||||
아이템
|
||||
</TabItem>
|
||||
</li>
|
||||
<li>
|
||||
<TabItem $state={activeTab === 'instance' ? 'active' : 'none'} onClick={e => handleTab(e, 'instance')}>
|
||||
인스턴스
|
||||
</TabItem>
|
||||
</li>
|
||||
<li>
|
||||
<TabItem $state={activeTab === 'deco' ? 'active' : 'none'} onClick={e => handleTab(e, 'deco')}>
|
||||
의상 / 타투
|
||||
</TabItem>
|
||||
</li>
|
||||
</TabWrapper>
|
||||
{activeTab === 'credit' && <CreditContent />}
|
||||
{activeTab === 'vbp' && <VBPContent />}
|
||||
{activeTab === 'item' && <ItemContent />}
|
||||
{activeTab === 'instance' && <InstanceContent />}
|
||||
{activeTab === 'deco' && <DecoContent />}
|
||||
</>
|
||||
)}
|
||||
<Title>경제 지표</Title>
|
||||
<TabScroll>
|
||||
<TabWrapper>
|
||||
{TabEconomicIndexList.map((el, idx) => {
|
||||
return (
|
||||
<li>
|
||||
<TabItem key={idx} $state={activeTab === el.value ? 'active' : 'none'} onClick={e => handleTab(e, el.value)}>
|
||||
{el.name}
|
||||
</TabItem>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</TabWrapper>
|
||||
</TabScroll>
|
||||
{activeTab === 'CURRENCY' && <CreditContent />}
|
||||
{/*{activeTab === 'vbp' && <VBPContent />}*/}
|
||||
{/*{activeTab === 'item' && <ItemContent />}*/}
|
||||
{/*{activeTab === 'instance' && <InstanceContent />}*/}
|
||||
{/*{activeTab === 'deco' && <DecoContent />}*/}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default EconomicIndex;
|
||||
|
||||
const TabItem = styled(Link)`
|
||||
display: inline-flex;
|
||||
width: 120px;
|
||||
height: 30px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: #f9f9f9;
|
||||
border-left: 1px solid #d9d9d9;
|
||||
&:hover {
|
||||
background: #888;
|
||||
color: #fff;
|
||||
}
|
||||
${props =>
|
||||
props.$state === 'active' &&
|
||||
`background: #888;
|
||||
color: #fff;`}
|
||||
`;
|
||||
|
||||
const TabWrapper = styled.ul`
|
||||
display: flex;
|
||||
li:first-child {
|
||||
${TabItem} {
|
||||
border-left: 0;
|
||||
}
|
||||
}
|
||||
`;
|
||||
export default withAuth(authType.economicIndicatorsRead)(EconomicIndex);
|
||||
@@ -36,7 +36,7 @@ import { StatusWapper, StatusLabel } from '../../styles/ModuleComponents';
|
||||
import { battleEventStatus, battleRepeatType } from '../../assets/data/options';
|
||||
import BattleEventSearchBar, {
|
||||
useBattleEventSearch,
|
||||
} from '../../components/ServiceManage/searchBar/BattleEventSearchBar';
|
||||
} from '../../components/searchBar/BattleEventSearchBar';
|
||||
import { getDateOnly, getTimeOnly, secondToMinutes } from '../../utils/date';
|
||||
import { alertTypes, battleEventStatusType } from '../../assets/data/types';
|
||||
import { useAlert } from '../../context/AlertProvider';
|
||||
|
||||
@@ -13,7 +13,7 @@ import { authType, commonStatus, modalTypes, eventStatus } from '../../assets/da
|
||||
import { Title, FormWrapper, TableStyle, MailTitle, TableWrapper, TextInput, InputItem } from '../../styles/Components';
|
||||
import CheckBox from '../../components/common/input/CheckBox';
|
||||
import Button from '../../components/common/button/Button';
|
||||
import EventDetailModal from '../../components/ServiceManage/modal/EventDetailModal';
|
||||
import EventDetailModal from '../../components/modal/EventDetailModal';
|
||||
import Pagination from '../../components/common/Pagination/Pagination';
|
||||
import 'react-datepicker/dist/react-datepicker.css';
|
||||
import DynamicModal from '../../components/common/modal/DynamicModal';
|
||||
|
||||
@@ -27,7 +27,7 @@ import {
|
||||
RegistInputRow, RegistNotice, RegistTable,
|
||||
} from '../../styles/ModuleComponents';
|
||||
import AuthModal from '../../components/common/modal/AuthModal';
|
||||
import { authType, benItems, currencyType } from '../../assets/data';
|
||||
import { authType, benItems, currencyItemCode } from '../../assets/data';
|
||||
import DateTimeInput from '../../components/common/input/DateTimeInput';
|
||||
import { timeDiffMinute } from '../../utils';
|
||||
import { useAlert } from '../../context/AlertProvider';
|
||||
@@ -209,7 +209,7 @@ const EventRegist = () => {
|
||||
const item_cnt = resultData.item_list[itemIndex].item_cnt;
|
||||
resultData.item_list[itemIndex].item_cnt = Number(item_cnt) + Number(resourceCount);
|
||||
} else {
|
||||
const name = currencyType.find(well => well.value === resource).name;
|
||||
const name = currencyItemCode.find(well => well.value === resource).name;
|
||||
const newItem = { item: resource, item_cnt: resourceCount, item_name: name };
|
||||
resultData.item_list.push(newItem);
|
||||
}
|
||||
@@ -403,7 +403,7 @@ const EventRegist = () => {
|
||||
<td>
|
||||
<RegistInputItem>
|
||||
<SelectInput onChange={e => setResource(e.target.value)} value={resource}>
|
||||
{currencyType.filter(data => data.value !== currencyCodeTypes.calium).map((data, index) => (
|
||||
{currencyItemCode.filter(data => data.value !== currencyCodeTypes.calium).map((data, index) => (
|
||||
<option key={index} value={data.value}>
|
||||
{data.name}
|
||||
</option>
|
||||
|
||||
@@ -30,7 +30,7 @@ import { convertKTC, timeDiffMinute } from '../../utils';
|
||||
import { LandAuctionModal, LandAuctionSearchBar } from '../../components/ServiceManage';
|
||||
import { INITIAL_PAGE_SIZE, INITIAL_PAGE_LIMIT } from '../../assets/data/adminConstants';
|
||||
import { useDataFetch, useModal, useTable, withAuth } from '../../hooks/hook';
|
||||
import { useLandAuctionSearch } from '../../components/ServiceManage/searchBar/LandAuctionSearchBar';
|
||||
import { useLandAuctionSearch } from '../../components/searchBar/LandAuctionSearchBar';
|
||||
import { StatusWapper, ChargeBtn, StatusLabel } from '../../styles/ModuleComponents';
|
||||
import { alertTypes } from '../../assets/data/types';
|
||||
import { useAlert } from '../../context/AlertProvider';
|
||||
|
||||
@@ -10,7 +10,7 @@ import Button from '../../components/common/button/Button';
|
||||
|
||||
import 'react-datepicker/dist/react-datepicker.css';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import MailDetailModal from '../../components/ServiceManage/modal/MailDetailModal';
|
||||
import MailDetailModal from '../../components/modal/MailDetailModal';
|
||||
import Pagination from '../../components/common/Pagination/Pagination';
|
||||
|
||||
import { authList } from '../../store/authList';
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
import IconDelete from '../../assets/img/icon/icon-delete.png';
|
||||
import CloseIcon from '../../assets/img/icon/icon-close.png';
|
||||
|
||||
import { benItems, HourList, mailType, MinuteList, currencyType, userType } from '../../assets/data';
|
||||
import { benItems, HourList, mailType, MinuteList, currencyItemCode, userType } from '../../assets/data';
|
||||
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import MailRegistUploadBtn from '../../components/ServiceManage/MailRegistUploadBtn';
|
||||
@@ -243,7 +243,7 @@ const MailRegist = () => {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const name = currencyType.find(well => well.value === resource).name;
|
||||
const name = currencyItemCode.find(well => well.value === resource).name;
|
||||
const newItem = { item: resource, item_cnt: resourceCount, item_name: name };
|
||||
resultData.item_list.push(newItem);
|
||||
}
|
||||
@@ -578,7 +578,7 @@ const MailRegist = () => {
|
||||
<td>
|
||||
<InputItem>
|
||||
<SelectInput onChange={e => setResource(e.target.value)} value={resource}>
|
||||
{currencyType.map((data, index) => (
|
||||
{currencyItemCode.map((data, index) => (
|
||||
<option key={index} value={data.value}>
|
||||
{data.name}
|
||||
</option>
|
||||
|
||||
@@ -14,7 +14,7 @@ import { INITIAL_PAGE_LIMIT } from '../../assets/data/adminConstants';
|
||||
import { useModal, useTable, withAuth } from '../../hooks/hook';
|
||||
import { MenuBannerDelete, MenuBannerDetailView } from '../../apis';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import MenuBannerModal from '../../components/ServiceManage/modal/MenuBannerModal';
|
||||
import MenuBannerModal from '../../components/modal/MenuBannerModal';
|
||||
import tableInfo from '../../assets/data/pages/menuBannerTable.json'
|
||||
import { CommonSearchBar, useCommonSearch } from '../../components/ServiceManage';
|
||||
import { useAlert } from '../../context/AlertProvider';
|
||||
|
||||
@@ -22,10 +22,10 @@ import { INITIAL_PAGE_SIZE, INITIAL_PAGE_LIMIT } from '../../assets/data/adminCo
|
||||
import { useModal, useTable, withAuth } from '../../hooks/hook';
|
||||
import { StatusWapper, StatusLabel } from '../../styles/ModuleComponents';
|
||||
import { opMenuBannerStatus } from '../../assets/data/options';
|
||||
import MenuBannerSearchBar, { useMenuBannerSearch } from '../../components/ServiceManage/searchBar/MenuBannerSearchBar';
|
||||
import MenuBannerSearchBar, { useMenuBannerSearch } from '../../components/searchBar/MenuBannerSearchBar';
|
||||
import { MenuBannerDelete, MenuBannerDetailView } from '../../apis';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import MenuBannerModal from '../../components/ServiceManage/modal/MenuBannerModal';
|
||||
import MenuBannerModal from '../../components/modal/MenuBannerModal';
|
||||
import tableInfo from '../../assets/data/pages/menuBannerTable.json'
|
||||
|
||||
const MenuBanner = () => {
|
||||
|
||||
@@ -27,7 +27,7 @@ import { useModal, withAuth } from '../../hooks/hook';
|
||||
import { DynamicModal, TopButton } from '../../components/common';
|
||||
import { opInitDataType, opSuccessType } from '../../assets/data/options';
|
||||
import { InitData } from '../../apis/Data';
|
||||
import DataInitSearchBar, { useDataInitSearch } from '../../components/ServiceManage/searchBar/DataInitSearchBar';
|
||||
import DataInitSearchBar, { useDataInitSearch } from '../../components/searchBar/DataInitSearchBar';
|
||||
import { useAlert } from '../../context/AlertProvider';
|
||||
import { useLoading } from '../../context/LoadingProvider';
|
||||
import { alertTypes } from '../../assets/data/types';
|
||||
|
||||
Reference in New Issue
Block a user