Compare commits
2 Commits
64bf449de7
...
9d06246aba
| Author | SHA1 | Date | |
|---|---|---|---|
| 9d06246aba | |||
| 1532793cc1 |
@@ -1,5 +1,4 @@
|
||||
//사용자 관리 - 로그조회 api 연결
|
||||
|
||||
import { Axios } from '../utils';
|
||||
|
||||
export const LogViewList = async (token, searchType, searchKey, historyType, startDt, endDt, orderBy, size, currentPage) => {
|
||||
@@ -34,3 +33,21 @@ export const LogviewDetail = async (token, id) => {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const LogHistory = async (token, params) => {
|
||||
try {
|
||||
const res = await Axios.post(`/api/v1/history/change-list`, params, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
});
|
||||
|
||||
if(res.data.result === 'ERROR'){
|
||||
throw new Error('LogHistory Error', res.data.data.message);
|
||||
}
|
||||
|
||||
return res.data.data.list;
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
throw new Error('LogHistory Error', e);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -8,5 +8,8 @@ export const ONE_MINUTE_MS = 60000;
|
||||
export const ONE_MINUTE_SECOND = 60;
|
||||
export const AUCTION_MIN_MINUTE_TIME = 15; // 15분
|
||||
export const IMAGE_MAX_SIZE = 5242880;
|
||||
export const STORAGE_MAIL_COPY = 'copyMailData';
|
||||
export const STORAGE_BUSINESS_LOG_SEARCH = 'businessLogSearchParam';
|
||||
export const LOG_ACTION_FAIL_CALIUM_ECHO = 'FailCaliumEchoSystem';
|
||||
|
||||
export { INITIAL_PAGE_SIZE, INITIAL_CURRENT_PAGE, INITIAL_PAGE_LIMIT };
|
||||
|
||||
18
src/assets/data/apis/historyAPI.json
Normal file
18
src/assets/data/apis/historyAPI.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"baseUrl": "/api/v1/history",
|
||||
"endpoints": {
|
||||
"LogViewList": {
|
||||
"method": "GET",
|
||||
"url": "/list",
|
||||
"dataPath": "data.data",
|
||||
"paramFormat": "query"
|
||||
},
|
||||
"LogviewDetail": {
|
||||
"method": "GET",
|
||||
"url": "/detail/:id",
|
||||
"dataPath": "data.data",
|
||||
"paramFormat": "query",
|
||||
"paramMapping": ["id"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
import itemAPI from './itemAPI.json';
|
||||
import menuBannerAPI from './menuBannerAPI.json';
|
||||
import historyAPI from './historyAPI.json';
|
||||
|
||||
export {
|
||||
itemAPI,
|
||||
menuBannerAPI
|
||||
menuBannerAPI,
|
||||
historyAPI
|
||||
};
|
||||
@@ -5,6 +5,14 @@ export const benItems = [
|
||||
"19010005"
|
||||
];
|
||||
|
||||
export const historyBenField = [
|
||||
"create_by",
|
||||
"create_dt",
|
||||
"update_by",
|
||||
"update_dt",
|
||||
"id"
|
||||
]
|
||||
|
||||
export const HourList = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23'];
|
||||
|
||||
export const MinuteList = [
|
||||
@@ -113,4 +121,75 @@ export const STATUS_STYLES = {
|
||||
background: '#4287f5',
|
||||
color: 'white'
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const logFieldLabels = {
|
||||
// DynamoDB 필드
|
||||
'attribFieldName': '속성 명',
|
||||
'pk': '파티션 키',
|
||||
'sk': '정렬 키',
|
||||
'DocType': '문서 타입',
|
||||
'CreatedDateTime': '생성 일시',
|
||||
'UpdatedDateTime': '수정 일시',
|
||||
'DeletedDateTime': '삭제 일시',
|
||||
'RestoredDateTime': '복원 일시',
|
||||
'INSERT': '등록',
|
||||
'UPDATE': '수정',
|
||||
'DELETE': '삭제',
|
||||
|
||||
//기본
|
||||
'id': 'ID',
|
||||
'userId': '사용자 ID',
|
||||
'userIP': '사용자 IP',
|
||||
'timestamp': '타임스탬프',
|
||||
'message': '메시지',
|
||||
'tranId': '트랜잭션 ID',
|
||||
'group_id': '그룹 ID',
|
||||
'update_dt': '수정 일시',
|
||||
'updateDt': '수정 일시',
|
||||
'update_by': '수정자',
|
||||
'create_dt': '생성 일시',
|
||||
'createDt': '생성 일시',
|
||||
'create_by': '생성자',
|
||||
'status': '상태',
|
||||
'deleted': '삭제 여부',
|
||||
|
||||
// 이벤트 필드 관련
|
||||
'eventId': '이벤트 ID',
|
||||
'eventName': '이벤트 명',
|
||||
'repeatType': '반복 타입',
|
||||
'eventOperationTime': '운영 시간(초)',
|
||||
'eventStartDt': '시작 시간',
|
||||
'eventEndDt': '종료 시간',
|
||||
'roundTime': '라운드 시간(초)',
|
||||
'roundCount': '라운드 수',
|
||||
'hotTime': '핫타임',
|
||||
'configId': '설정 ID',
|
||||
'rewardGroupId': '보상 그룹 ID',
|
||||
'attrib_type': '속성 타입',
|
||||
'event_id': '이벤트 ID',
|
||||
'is_active': '활성화 여부',
|
||||
'start_day': '시작일',
|
||||
'start_hour': '시작 시간',
|
||||
'start_min': '시작 분',
|
||||
'end_date': '종료 일시',
|
||||
'instance_id': '인스턴스 ID',
|
||||
'once_period_type': '주기 타입',
|
||||
'day_of_week_type': '요일 타입',
|
||||
'ffa_config_data_id': 'FFA 설정 ID',
|
||||
'ffa_reward_group_id': 'FFA 보상 그룹 ID',
|
||||
'ffa_hot_time': 'FFA 핫타임',
|
||||
'round_count': '라운드 수',
|
||||
|
||||
};
|
||||
|
||||
export const historyTables = {
|
||||
userBlock: 'black_list',
|
||||
landAuction: 'land_auction',
|
||||
landOwnerChange: 'land_ownership_changes',
|
||||
event: 'event',
|
||||
mail: 'mail',
|
||||
notice: 'notice',
|
||||
battleEvent: 'battle_event',
|
||||
caliumRequest: 'calium_request',
|
||||
}
|
||||
@@ -100,7 +100,7 @@ export const menuConfig = {
|
||||
permissions: {
|
||||
read: authType.gameLogRead
|
||||
},
|
||||
view: true,
|
||||
view: false,
|
||||
authLevel: adminAuthLevel.NONE
|
||||
},
|
||||
cryptview: {
|
||||
@@ -108,7 +108,7 @@ export const menuConfig = {
|
||||
permissions: {
|
||||
read: authType.cryptoRead
|
||||
},
|
||||
view: true,
|
||||
view: false,
|
||||
authLevel: adminAuthLevel.NONE
|
||||
},
|
||||
businesslogview: {
|
||||
|
||||
@@ -167,6 +167,11 @@ export const userType2 = [
|
||||
{ value: 'NICKNAME', name: '닉네임' },
|
||||
];
|
||||
|
||||
export const adminUserType = [
|
||||
{ value: 'ID', name: 'ID(이메일)' },
|
||||
{ value: 'NAME', name: '이름' },
|
||||
];
|
||||
|
||||
export const userSearchType2 = [
|
||||
{ value: 'GUID', name: 'GUID' },
|
||||
{ value: 'NICKNAME', name: '닉네임' },
|
||||
@@ -336,6 +341,75 @@ export const opItemType = [
|
||||
{ value: 'BEAUTY', name: '뷰티' },
|
||||
]
|
||||
|
||||
export const opHistoryType = [
|
||||
{ value: '', name: '전체' },
|
||||
{ value: 'LOGIN_PERMITTED', name: '로그인 승인' },
|
||||
{ value: 'ADMIN_INFO_UPDATE', name: '운영자 정보 수정' },
|
||||
{ value: 'ADMIN_INFO_DELETE', name: '운영자 정보 삭제' },
|
||||
{ value: 'PASSWORD_INIT', name: '비밀번호 초기화' },
|
||||
{ value: 'USER_INFO_UPDATE', name: '유저 정보 변경' },
|
||||
{ value: 'GROUP_AUTH_UPDATE', name: '그룹 권한 수정' },
|
||||
{ value: 'GROUP_DELETE', name: '그룹 삭제' },
|
||||
{ value: 'NOTICE_DELETE', name: '공지사항 삭제' },
|
||||
{ value: 'NOTICE_ADD', name: '공지사항 등록' },
|
||||
{ value: 'NOTICE_UPDATE', name: '공지사항 수정' },
|
||||
{ value: 'NOTICE_SEND_FAIL', name: '공지사항 전송 실패' },
|
||||
{ value: 'MAIL_DELETE', name: '우편 삭제' },
|
||||
{ value: 'MAIL_ADD', name: '우편 등록' },
|
||||
{ value: 'MAIL_UPDATE', name: '우편 수정' },
|
||||
{ value: 'MAIL_SEND', name: '우편 전송' },
|
||||
{ value: 'MAIL_SEND_FAIL', name: '우편 전송 실패' },
|
||||
{ value: 'MAIL_ITEM_DELETE', name: '우편 아이템 삭제' },
|
||||
{ value: 'MAIL_ITEM_UPDATE', name: '우편 아이템 수정' },
|
||||
{ value: 'BLACKLIST_ADD', name: '유저 제재 등록' },
|
||||
{ value: 'BLACKLIST_UPDATE', name: '유저 제재 수정' },
|
||||
{ value: 'BLACKLIST_DELETE', name: '유저 제재 삭제' },
|
||||
{ value: 'REPORT_DELETE', name: '신고내역 삭제' },
|
||||
{ value: 'USER_ITEM_DELETE', name: '유저 아이템 삭제' },
|
||||
{ value: 'SCHEDULE_MAIL_FAIL', name: '메일 스케줄 실패' },
|
||||
{ value: 'SCHEDULE_NOTICE_FAIL', name: '공지 스케줄 실패' },
|
||||
{ value: 'SCHEDULE_EVENT_FAIL', name: '이벤트 스케줄 실패' },
|
||||
{ value: 'USER_MAIL_DELETE', name: '유저 메일 삭제' },
|
||||
{ value: 'INVENTORY_ITEM_DELETE', name: '인벤토리 아이템 삭제' },
|
||||
{ value: 'INVENTORY_ITEM_UPDATE', name: '인벤토리 아이템 수정' },
|
||||
{ value: 'EVENT_ADD', name: '이벤트 등록' },
|
||||
{ value: 'EVENT_UPDATE', name: '이벤트 수정' },
|
||||
{ value: 'EVENT_DELETE', name: '이벤트 삭제' },
|
||||
{ value: 'CALIUM_ADD', name: '칼리움 요청 등록' },
|
||||
{ value: 'CALIUM_SAVE', name: '칼리움 저장' },
|
||||
{ value: 'CALIUM_TRANSFER', name: '칼리움 전송' },
|
||||
{ value: 'CALIUM_TOTAL_UPDATE', name: '칼리움 충전' },
|
||||
{ value: 'LAND_AUCTION_ADD', name: '랜드경매 등록' },
|
||||
{ value: 'LAND_AUCTION_UPDATE', name: '랜드경매 수정' },
|
||||
{ value: 'LAND_AUCTION_DELETE', name: '랜드경매 삭제' },
|
||||
{ value: 'BATTLE_EVENT_ADD', name: '전투시스템 이벤트 등록' },
|
||||
{ value: 'BATTLE_EVENT_UPDATE', name: '전투시스템 이벤트 수정' },
|
||||
{ value: 'BATTLE_EVENT_DELETE', name: '전투시스템 이벤트 삭제' },
|
||||
{ value: 'LAND_OWNER_CHANGE_ADD', name: '랜드 소유권 변경 등록' },
|
||||
{ value: 'LAND_OWNER_CHANGE_UPDATE', name: '랜드 소유권 변경 수정' },
|
||||
{ value: 'LAND_OWNER_CHANGE_DELETE', name: '랜드 소유권 변경 예약 취소' },
|
||||
{ value: 'LAND_OWNER_CHANGE_MAIL', name: '랜드 소유권 변경 우편' },
|
||||
{ value: 'LAND_OWNED_INITIALIZE', name: '랜드 소유권 정보 초기화' },
|
||||
{ value: 'LAND_DESC_INITIALIZE', name: '랜드 정보 초기화' },
|
||||
{ value: 'LAND_AUCTION_INITIALIZE', name: '랜드 경매 초기화' },
|
||||
{ value: 'MENU_BANNER_ADD', name: '메뉴 배너 등록' },
|
||||
{ value: 'MENU_BANNER_UPDATE', name: '메뉴 배너 수정' },
|
||||
{ value: 'MENU_BANNER_DELETE', name: '메뉴 배너 삭제' },
|
||||
{ value: 'ITEM_UPDATE', name: '아이템 수정' },
|
||||
{ value: 'ITEM_DELETE', name: '아이템 삭제' },
|
||||
{ value: 'USER_ADMIN_AUTH_UPDATE', name: '유저 관리자 권한 수정' },
|
||||
{ value: 'NICKNAME_REGISTRY_DELETE', name: '닉네임 레지스트리 삭제' },
|
||||
{ value: 'NICKNAME_REGISTRY_ADD', name: '닉네임 레지스트리 등록' },
|
||||
{ value: 'NICKNAME_UPDATE', name: '닉네임 수정' },
|
||||
{ value: 'DATA_INIT_ADD', name: '데이터 초기화 등록' },
|
||||
];
|
||||
|
||||
export const opDBType = [
|
||||
{ value: '', name: '전체'},
|
||||
{ value: 'dynamoDB', name: 'dynamoDB'},
|
||||
{ value: 'MySql', name: 'MySql'},
|
||||
]
|
||||
|
||||
// export const logAction = [
|
||||
// { value: "None", name: "ALL" },
|
||||
// { value: "AIChatDeleteCharacter", name: "NPC 삭제" },
|
||||
@@ -658,6 +732,14 @@ export const logAction = [
|
||||
{ value: "BeaconCreate", name: "BeaconCreate" },
|
||||
{ value: "BeaconEdit", name: "BeaconEdit" },
|
||||
{ value: "BeaconSell", name: "BeaconSell" },
|
||||
{ value: "BeaconShopRegisterItem", name: "BeaconShopRegisterItem" },
|
||||
{ value: "BeaconShopReturnItem", name: "BeaconShopReturnItem" },
|
||||
{ value: "BeaconShopPurchaseItem", name: "BeaconShopPurchaseItem" },
|
||||
{ value: "BeaconShopReceivePaymentForSales", name: "BeaconShopReceivePaymentForSales" },
|
||||
{ value: "BeaconShopSearchItem", name: "BeaconShopSearchItem" },
|
||||
{ value: "BeaconShopUpdateDailyCount", name: "BeaconShopUpdateDailyCount" },
|
||||
{ value: "BeaconShopDeleteRecord", name: "BeaconShopDeleteRecord" },
|
||||
{ value: "BeaconShopDeactiveItems", name: "BeaconShopDeactiveItems" },
|
||||
{ value: "BrokerApiAdmin", name: "BrokerApiAdmin" },
|
||||
{ value: "BrokerApiPlanetAuth", name: "BrokerApiPlanetAuth" },
|
||||
{ value: "BrokerApiUserExchangeOrderCompleted", name: "BrokerApiUserExchangeOrderCompleted" },
|
||||
@@ -708,6 +790,8 @@ export const logAction = [
|
||||
{ value: "CheatCommandSendMail", name: "CheatCommandSendMail" },
|
||||
{ value: "CheatCommandShopProductInit", name: "CheatCommandShopProductInit" },
|
||||
{ value: "CheatCommandShopProductRenewal", name: "CheatCommandShopProductRenewal" },
|
||||
{ value: "CheatCommandBeaconShopItemTimeChange", name: "CheatCommandBeaconShopItemTimeChange" },
|
||||
{ value: "CheatCommandDailyLimitInit", name: "CheatCommandDailyLimitInit" },
|
||||
{ value: "ClaimReward", name: "ClaimReward" },
|
||||
{ value: "ConvertCalium", name: "ConvertCalium" },
|
||||
{ value: "ConvertExchangeCalium", name: "ConvertExchangeCalium" },
|
||||
@@ -744,6 +828,8 @@ export const logAction = [
|
||||
{ value: "ItemTattooChangeAttribute", name: "ItemTattooChangeAttribute" },
|
||||
{ value: "ItemTattooLevelUp", name: "ItemTattooLevelUp" },
|
||||
{ value: "ItemUse", name: "ItemUse" },
|
||||
{ value: "ItemDestroyByUser", name: "ItemDestroyByUser" },
|
||||
{ value: "ItemDestoryByExpiration", name: "ItemDestoryByExpiration" },
|
||||
{ value: "JoinInstance", name: "JoinInstance" },
|
||||
{ value: "JoinParty", name: "JoinParty" },
|
||||
{ value: "JoinPartyInstance", name: "JoinPartyInstance" },
|
||||
@@ -770,7 +856,7 @@ export const logAction = [
|
||||
{ value: "ProductGive", name: "ProductGive" },
|
||||
{ value: "ProductOpenFailed", name: "ProductOpenFailed" },
|
||||
{ value: "ProductOpenSuccess", name: "ProductOpenSuccess" },
|
||||
{ value: "QuestMailSend", name: "QuestMailSend" },
|
||||
{ value: "QuestMainAssign", name: "QuestMainAssign" },
|
||||
{ value: "QuestMainAbort", name: "QuestMainAbort" },
|
||||
{ value: "QuestMainAssignByDialogue", name: "QuestMainAssignByDialogue" },
|
||||
{ value: "QuestMainAssignForce", name: "QuestMainAssignForce" },
|
||||
@@ -778,6 +864,7 @@ export const logAction = [
|
||||
{ value: "QuestMainRepeatTimeInit", name: "QuestMainRepeatTimeInit" },
|
||||
{ value: "QuestMainRepeatTimeRefresh", name: "QuestMainRepeatTimeRefresh" },
|
||||
{ value: "QuestMainReward", name: "QuestMainReward" },
|
||||
{ value: "QuestMailSend", name: "QuestMailSend" },
|
||||
{ value: "QuestMainTask", name: "QuestMainTask" },
|
||||
{ value: "QuestTaskUpdate", name: "QuestTaskUpdate" },
|
||||
{ value: "RefuseFriendRequest", name: "RefuseFriendRequest" },
|
||||
@@ -865,6 +952,9 @@ export const logDomain = [
|
||||
{ value: "BattleSnapshot", name: "BattleSnapshot" },
|
||||
{ value: "BeaconCreate", name: "BeaconCreate" },
|
||||
{ value: "Beacon", name: "Beacon" },
|
||||
{ value: "BeaconShop", name: "BeaconShop" },
|
||||
{ value: "BeaconShopSoldRecord", name: "BeaconShopSoldRecord" },
|
||||
{ value: "BeaconShopSoldPrice", name: "BeaconShopSoldPrice" },
|
||||
{ value: "BrokerApi", name: "BrokerApi" },
|
||||
{ value: "Buff", name: "Buff" },
|
||||
{ value: "Building", name: "Building" },
|
||||
@@ -888,6 +978,7 @@ export const logDomain = [
|
||||
{ value: "FarmingReward", name: "FarmingReward" },
|
||||
{ value: "GameLogInOut", name: "GameLogInOut" },
|
||||
{ value: "Item", name: "Item" },
|
||||
{ value: "IgmApi", name: "IgmApi" },
|
||||
{ value: "MyHome", name: "MyHome" },
|
||||
{ value: "Land", name: "Land" },
|
||||
{ value: "LandAuction", name: "LandAuction" },
|
||||
@@ -905,6 +996,9 @@ export const logDomain = [
|
||||
{ value: "PackageLastOrderRecode", name: "PackageLastOrderRecode" },
|
||||
{ value: "PackageRepeat", name: "PackageRepeat" },
|
||||
{ value: "PackageState", name: "PackageState" },
|
||||
{ value: "PlanetProviderAuth", name: "PlanetProviderAuth" },
|
||||
{ value: "PlanetUserAuth", name: "PlanetUserAuth" },
|
||||
{ value: "PlanetItemExchange", name: "PlanetItemExchange" },
|
||||
{ value: "QuestMain", name: "QuestMain" },
|
||||
{ value: "QuestUgq", name: "QuestUgq" },
|
||||
{ value: "QuestMail", name: "QuestMail" },
|
||||
|
||||
56
src/assets/data/pages/historySearch.json
Normal file
56
src/assets/data/pages/historySearch.json
Normal file
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"initialSearchParams": {
|
||||
"searchType": "ID",
|
||||
"searchData": "",
|
||||
"historyType": "",
|
||||
"startDate": "",
|
||||
"endDate": "",
|
||||
"orderBy": "DESC",
|
||||
"pageSize": 50,
|
||||
"currentPage": 1
|
||||
},
|
||||
|
||||
"searchFields": [
|
||||
{
|
||||
"type": "select",
|
||||
"id": "searchType",
|
||||
"label": "대상",
|
||||
"optionsRef": "adminUserType",
|
||||
"col": 1
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"id": "searchData",
|
||||
"placeholder": "대상 입력",
|
||||
"width": "300px",
|
||||
"col": 1
|
||||
},
|
||||
{
|
||||
"type": "select",
|
||||
"id": "historyType",
|
||||
"label": "이력종류",
|
||||
"optionsRef": "opHistoryType",
|
||||
"col": 1
|
||||
},
|
||||
{
|
||||
"type": "period",
|
||||
"startDateId": "startDate",
|
||||
"endDateId": "endDate",
|
||||
"label": "기간",
|
||||
"col": 2
|
||||
}
|
||||
],
|
||||
|
||||
"apiInfo": {
|
||||
"endpointName": "LogViewList",
|
||||
"loadOnMount": true,
|
||||
"paramTransforms": [
|
||||
{"param": "startDate", "transform": "toISOString"},
|
||||
{"param": "endDate", "transform": "toISOString"}
|
||||
],
|
||||
"pageField": "page_no",
|
||||
"pageSizeField": "page_size",
|
||||
"orderField": "orderBy"
|
||||
},
|
||||
"paginationType": "front"
|
||||
}
|
||||
56
src/assets/data/pages/historyTable.json
Normal file
56
src/assets/data/pages/historyTable.json
Normal file
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"id": "historyTable",
|
||||
"selection": {
|
||||
"type": "single",
|
||||
"idField": "id"
|
||||
},
|
||||
"header": {
|
||||
"countType": "total",
|
||||
"orderType": "desc",
|
||||
"pageType": "default",
|
||||
"buttons": []
|
||||
},
|
||||
"columns": [
|
||||
{
|
||||
"id": "timestamp",
|
||||
"type": "date",
|
||||
"width": "200px",
|
||||
"title": "일시(KST)",
|
||||
"format": {
|
||||
"type": "function",
|
||||
"name": "convertKTC"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "dbType",
|
||||
"type": "option",
|
||||
"width": "100px",
|
||||
"title": "DB타입",
|
||||
"option_name": "opDBType"
|
||||
},
|
||||
{
|
||||
"id": "historyType",
|
||||
"type": "option",
|
||||
"width": "150px",
|
||||
"title": "이력종류",
|
||||
"option_name": "opHistoryType"
|
||||
},
|
||||
{
|
||||
"id": "userId",
|
||||
"type": "text",
|
||||
"width": "100px",
|
||||
"title": "작업자"
|
||||
},
|
||||
{
|
||||
"id": "detail",
|
||||
"type": "button",
|
||||
"width": "120px",
|
||||
"title": "상세보기",
|
||||
"text": "상세보기"
|
||||
}
|
||||
],
|
||||
"sort": {
|
||||
"defaultColumn": "timestamp",
|
||||
"defaultDirection": "desc"
|
||||
}
|
||||
}
|
||||
@@ -73,12 +73,6 @@
|
||||
"title": "제재 사유",
|
||||
"option_name": "blockSanctions"
|
||||
},
|
||||
{
|
||||
"id": "create_by",
|
||||
"type": "text",
|
||||
"width": "150px",
|
||||
"title": "등록자"
|
||||
},
|
||||
{
|
||||
"id": "detail",
|
||||
"type": "button",
|
||||
@@ -92,6 +86,13 @@
|
||||
"id": "id"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "history",
|
||||
"type": "button",
|
||||
"width": "120px",
|
||||
"title": "히스토리",
|
||||
"text": "히스토리"
|
||||
}
|
||||
],
|
||||
"sort": {
|
||||
|
||||
@@ -268,8 +268,6 @@ const BattleEventModal = ({ modalType, detailView, handleDetailView, content, se
|
||||
}
|
||||
}
|
||||
|
||||
console.log(configData)
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal min="760px" $view={detailView}>
|
||||
|
||||
@@ -31,6 +31,7 @@ import { useAlert } from '../../../context/AlertProvider';
|
||||
import { useLoading } from '../../../context/LoadingProvider';
|
||||
import { alertTypes, currencyCodeTypes } from '../../../assets/data/types';
|
||||
import { userType2 } from '../../../assets/data/options';
|
||||
import { STORAGE_MAIL_COPY } from '../../../assets/data/adminConstants';
|
||||
|
||||
const MailDetailModal = ({ detailView, handleDetailView, content }) => {
|
||||
const userInfo = useRecoilValue(authList);
|
||||
@@ -151,14 +152,14 @@ const MailDetailModal = ({ detailView, handleDetailView, content }) => {
|
||||
if (data.result === 'ERROR') {
|
||||
showToast(data.data.message, { type: alertTypes.warning });
|
||||
}else{
|
||||
const itemIndex = resultData.item_list.findIndex(
|
||||
data => data.item === item
|
||||
);
|
||||
|
||||
if (itemIndex !== -1) {
|
||||
showToast('MAIL_ITEM_ADD_DUPL', { type: alertTypes.warning });
|
||||
return;
|
||||
}
|
||||
// const itemIndex = resultData.item_list.findIndex(
|
||||
// data => data.item === item
|
||||
// );
|
||||
//
|
||||
// if (itemIndex !== -1) {
|
||||
// showToast('MAIL_ITEM_ADD_DUPL', { type: alertTypes.warning });
|
||||
// return;
|
||||
// }
|
||||
const newItem = { item: item, item_cnt: itemCount, item_name: data.data.item_info.item_name };
|
||||
|
||||
resultData.item_list.push(newItem);
|
||||
@@ -285,7 +286,7 @@ const MailDetailModal = ({ detailView, handleDetailView, content }) => {
|
||||
};
|
||||
|
||||
// 복사한 데이터를 세션 스토리지에 저장
|
||||
sessionStorage.setItem('copyMailData', JSON.stringify(mailData));
|
||||
sessionStorage.setItem(STORAGE_MAIL_COPY, JSON.stringify(mailData));
|
||||
|
||||
navigate('/servicemanage/mail/mailregist');
|
||||
};
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { TextInput, BtnWrapper, InputLabel, SelectInput, InputGroup } from '../../../styles/Components';
|
||||
import { TextInput, InputLabel, SelectInput, InputGroup } from '../../../styles/Components';
|
||||
import { SearchBarLayout, SearchPeriod } from '../../common/SearchBar';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { logAction, logDomain, userSearchType2 } from '../../../assets/data/options';
|
||||
import { BusinessLogList } from '../../../apis/Log';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {SearchFilter} from '../';
|
||||
import { useAlert } from '../../../context/AlertProvider';
|
||||
import { alertTypes } from '../../../assets/data/types';
|
||||
|
||||
export const useBusinessLogSearch = (token, initialPageSize, setAlertMsg) => {
|
||||
const { t } = useTranslation();
|
||||
export const useBusinessLogSearch = (token, initialPageSize) => {
|
||||
const {showToast} = useAlert();
|
||||
|
||||
const [searchParams, setSearchParams] = useState({
|
||||
search_type: 'GUID',
|
||||
@@ -53,14 +54,16 @@ export const useBusinessLogSearch = (token, initialPageSize, setAlertMsg) => {
|
||||
params
|
||||
);
|
||||
if(result.result === "ERROR_LOG_MEMORY_LIMIT"){
|
||||
setAlertMsg(t('LOG_MEMORY_LIMIT_WARNING'))
|
||||
showToast('LOG_MEMORY_LIMIT_WARNING', {type: alertTypes.error});
|
||||
}else if(result.result === "ERROR_MONGODB_QUERY"){
|
||||
setAlertMsg(t('LOG_MONGGDB_QUERY_WARNING'))
|
||||
showToast('LOG_MONGGDB_QUERY_WARNING', {type: alertTypes.error});
|
||||
}else if(result.result === "ERROR"){
|
||||
showToast(result.result, {type: alertTypes.error});
|
||||
}
|
||||
setData(result.data);
|
||||
return result.data;
|
||||
} catch (error) {
|
||||
console.error('Error fetching auction data:', error);
|
||||
showToast('error', {type: alertTypes.error});
|
||||
throw error;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { BtnWrapper, InputLabel, TextInput } from '../../../styles/Components';
|
||||
import Button from '../../common/button/Button';
|
||||
import { InputLabel, TextInput } from '../../../styles/Components';
|
||||
import { SearchBarLayout, SearchPeriod } from '../../common/SearchBar';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { InitHistoryList } from '../../../apis/Data';
|
||||
import { useAlert } from '../../../context/AlertProvider';
|
||||
import { alertTypes } from '../../../assets/data/types';
|
||||
|
||||
export const useDataInitSearch = (token, setAlertMsg) => {
|
||||
const { t } = useTranslation();
|
||||
export const useDataInitSearch = (token) => {
|
||||
const {showToast} = useAlert();
|
||||
|
||||
const [searchParams, setSearchParams] = useState({
|
||||
tran_id: '',
|
||||
@@ -39,9 +39,9 @@ export const useDataInitSearch = (token, setAlertMsg) => {
|
||||
params
|
||||
);
|
||||
if(result.result === "ERROR_LOG_MEMORY_LIMIT"){
|
||||
setAlertMsg(t('LOG_MEMORY_LIMIT_WARNING'))
|
||||
showToast('LOG_MEMORY_LIMIT_WARNING',{type: alertTypes.error});
|
||||
}else if(result.result === "ERROR_MONGODB_QUERY"){
|
||||
setAlertMsg(t('LOG_MONGGDB_QUERY_WARNING'))
|
||||
showToast('LOG_MONGGDB_QUERY_WARNING',{type: alertTypes.error});
|
||||
}
|
||||
setData(result.data);
|
||||
return result.data;
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useState } from 'react';
|
||||
import { TextInput, InputLabel, SelectInput, BtnWrapper } from '../../../styles/Components';
|
||||
import Button from '../../common/button/Button';
|
||||
import { SearchBarLayout, SearchPeriod } from '../../common/SearchBar';
|
||||
import { opHistoryType } from '../../../assets/data/options';
|
||||
|
||||
const LogViewSearchBar = ({ handleSearch, resultData }) => {
|
||||
const [searchData, setSearchData] = useState({
|
||||
@@ -19,21 +20,7 @@ const LogViewSearchBar = ({ handleSearch, resultData }) => {
|
||||
{ value: 'id', name: 'ID(이메일)' },
|
||||
];
|
||||
|
||||
const logOption = [
|
||||
{ value: '', name: '이력 선택' },
|
||||
{ value: 'LOGIN_PERMITTED', name: '로그인 승인' },
|
||||
{ value: 'ADMIN_INFO_UPDATE', name: '운영자 정보 수정' },
|
||||
{ value: 'ADMIN_INFO_DELETE', name: '운영자 정보 삭제' },
|
||||
{ value: 'PASSWORD_INIT', name: '비밀번호 초기화' },
|
||||
{ value: 'USER_INFO_UPDATE', name: '유저 정보 변경' },
|
||||
{ value: 'GROUP_AUTH_UPDATE', name: '그룹 권한 수정' },
|
||||
{ value: 'GROUP_DELETE', name: '그룹 삭제' },
|
||||
{ value: 'NOTICE_DELETE', name: '인게임 메시지 삭제' },
|
||||
{ value: 'MAIL_DELETE', name: '우편 삭제' },
|
||||
{ value: 'WHITELIST_DELETE', name: '화이트리스트 삭제' },
|
||||
{ value: 'BLACKLIST_DELETE', name: '유저 제재 삭제' },
|
||||
{ value: 'REPORT_DELETE', name: '신고내역 삭제' },
|
||||
];
|
||||
|
||||
|
||||
const handleReset = () => {
|
||||
setSearchData({
|
||||
@@ -85,7 +72,7 @@ const LogViewSearchBar = ({ handleSearch, resultData }) => {
|
||||
<InputLabel>사용 이력</InputLabel>
|
||||
<InputGroup>
|
||||
<SelectInput value={searchData.logOption} onChange={e => setSearchData({ ...searchData, logOption: e.target.value })}>
|
||||
{logOption.map((data, index) => (
|
||||
{opHistoryType.map((data, index) => (
|
||||
<option key={index} value={data.value}>
|
||||
{data.name}
|
||||
</option>
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useCallback, useEffect, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import PaginationIcon from '../../../assets/img/icon/icon-pagination.png';
|
||||
import { INITIAL_CURRENT_PAGE } from '../../../assets/data/adminConstants';
|
||||
|
||||
const FrontPagination = ({
|
||||
data, // 전체 데이터 배열
|
||||
@@ -13,6 +14,10 @@ const FrontPagination = ({
|
||||
}) => {
|
||||
const [blockNum, setBlockNum] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
setCurrentPage(INITIAL_CURRENT_PAGE);
|
||||
},[data])
|
||||
|
||||
// 전체 페이지 수 계산
|
||||
const totalItems = data?.length || 0;
|
||||
const maxPage = Math.ceil(totalItems / itemsPerPage);
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
TableInfo,
|
||||
} from '../../../styles/Components';
|
||||
import { ORDER_OPTIONS, PAGE_SIZE_OPTIONS, ViewTitleCountType } from '../../../assets/data';
|
||||
import { TitleItem, TitleItemLabel, TitleItemValue } from '../../../styles/ModuleComponents';
|
||||
import { TitleItem, TitleItemLabel, TitleItemLink, TitleItemValue } from '../../../styles/ModuleComponents';
|
||||
import { DynamoPagination } from '../index';
|
||||
import React from 'react';
|
||||
|
||||
@@ -14,6 +14,8 @@ const ViewTableInfo = ({
|
||||
children,
|
||||
total,
|
||||
total_all,
|
||||
fail_count,
|
||||
onFailCountClick,
|
||||
orderType = 'desc',
|
||||
handleOrderBy,
|
||||
pageType = 'default',
|
||||
@@ -28,7 +30,7 @@ const ViewTableInfo = ({
|
||||
{total !== undefined && total_all !== undefined &&
|
||||
<ListCount>
|
||||
{COUNT_TYPE_RENDERERS[countType] ?
|
||||
COUNT_TYPE_RENDERERS[countType](total, total_all) :
|
||||
COUNT_TYPE_RENDERERS[countType](total, total_all, fail_count, onFailCountClick) :
|
||||
COUNT_TYPE_RENDERERS[ViewTitleCountType.total](total, total_all)}
|
||||
</ListCount>
|
||||
}
|
||||
@@ -52,7 +54,7 @@ const ViewTableInfo = ({
|
||||
|
||||
const COUNT_TYPE_RENDERERS = {
|
||||
[ViewTitleCountType.total]: (total, total_all) => `총 : ${total ?? 0} 건 / ${total_all ?? 0} 건`,
|
||||
[ViewTitleCountType.calium]: (total, total_all) => (
|
||||
[ViewTitleCountType.calium]: (total, total_all, fail_count, onFailCountClick) => (
|
||||
<>
|
||||
<TitleItem>
|
||||
<TitleItemLabel>누적 충전</TitleItemLabel>
|
||||
@@ -62,6 +64,10 @@ const COUNT_TYPE_RENDERERS = {
|
||||
<TitleItemLabel>잔여 수량</TitleItemLabel>
|
||||
<TitleItemValue color='#B39063' fontWeight='bold'>{total ?? 0}</TitleItemValue>
|
||||
</TitleItem>
|
||||
<TitleItem>
|
||||
<TitleItemLabel>에코시스템 실패</TitleItemLabel>
|
||||
<TitleItemLink color='#D33B27' fontWeight='bold' onClick={onFailCountClick}>{fail_count ?? 0}</TitleItemLink>
|
||||
</TitleItem>
|
||||
</>
|
||||
),
|
||||
};
|
||||
|
||||
253
src/components/common/modal/LogDetailModal.js
Normal file
253
src/components/common/modal/LogDetailModal.js
Normal file
@@ -0,0 +1,253 @@
|
||||
import { styled } from 'styled-components';
|
||||
import React, { Fragment, useEffect, useState } from 'react';
|
||||
|
||||
import { Title } from '../../../styles/Components';
|
||||
import { BtnWrapper, TableStyle } from '../../../styles/Components';
|
||||
import Button from '../../../components/common/button/Button';
|
||||
import Modal from '../../../components/common/modal/Modal';
|
||||
import { TableWrapper } from '../../../styles/Components';
|
||||
import { Tab, TabContent } from '../../../styles/ModuleComponents';
|
||||
import { convertKTC, getFieldLabel } from '../../../utils';
|
||||
import { historyBenField } from '../../../assets/data/data';
|
||||
|
||||
const LogDetailModal = ({ detailView,
|
||||
handleDetailView,
|
||||
detailData,
|
||||
changedData,
|
||||
viewMode = 'both',
|
||||
title = '로그 상세정보'
|
||||
}) => {
|
||||
const [activeTab, setActiveTab] = useState('data');
|
||||
|
||||
// viewMode가 변경될 때 적절한 탭 활성화
|
||||
useEffect(() => {
|
||||
if (viewMode === 'data' || viewMode === 'changed') {
|
||||
setActiveTab(viewMode);
|
||||
}
|
||||
}, [viewMode]);
|
||||
|
||||
// data 객체의 키-값 쌍을 테이블 형식으로 변환
|
||||
const renderDataTable = () => {
|
||||
if (!detailData || !detailData) return null;
|
||||
|
||||
// data 객체를 평탄화하는 함수 (중첩된 객체도 처리)
|
||||
const flattenObject = (obj, prefix = '') => {
|
||||
return Object.keys(obj).reduce((acc, key) => {
|
||||
const newKey = prefix ? `${prefix}.${key}` : key;
|
||||
|
||||
if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
|
||||
// $date나 $oid 같은 특수 키를 포함하는 MongoDB 형식 객체 처리
|
||||
if (obj[key].$date) {
|
||||
acc[newKey] = new Date(obj[key].$date).toLocaleString('ko-KR');
|
||||
return acc;
|
||||
}
|
||||
if (obj[key].$oid) {
|
||||
acc[newKey] = obj[key].$oid;
|
||||
return acc;
|
||||
}
|
||||
if (obj[key].$numberLong) {
|
||||
acc[newKey] = obj[key].$numberLong;
|
||||
return acc;
|
||||
}
|
||||
|
||||
// 일반 중첩 객체는 재귀적으로 평탄화
|
||||
return {...acc, ...flattenObject(obj[key], newKey)};
|
||||
}
|
||||
|
||||
// 배열 값은 JSON 문자열로 변환
|
||||
if (Array.isArray(obj[key])) {
|
||||
acc[newKey] = JSON.stringify(obj[key]);
|
||||
} else {
|
||||
acc[newKey] = obj[key];
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
||||
|
||||
const flattenedData = flattenObject(detailData);
|
||||
|
||||
return (
|
||||
<TableStyle>
|
||||
<caption>데이터 상세 정보</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="120px">필드명</th>
|
||||
<th width="200px">값</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{detailData && Object.entries(flattenedData).map(([key, value], index) => (
|
||||
<tr key={index}>
|
||||
<td>{getFieldLabel(key)}</td>
|
||||
<td>{value !== null && value !== undefined ? String(value) : ''}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</TableStyle>
|
||||
);
|
||||
};
|
||||
|
||||
// changed 배열의 항목들을 테이블로 표시
|
||||
const renderChangedTable = () => {
|
||||
if (!changedData || !Array.isArray(changedData)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const allChangedItems = [];
|
||||
|
||||
changedData.forEach((item, itemIndex) => {
|
||||
if (item.changed && Array.isArray(item.changed)) {
|
||||
item.changed.forEach((changedItem) => {
|
||||
allChangedItems.push({
|
||||
...changedItem,
|
||||
// 어떤 데이터 항목에서 온 것인지 구분하기 위한 정보 추가
|
||||
sourceIndex: itemIndex,
|
||||
sourceInfo: {
|
||||
dbType: item.dbType,
|
||||
timestamp: item.timestamp,
|
||||
operationType: item.operationType,
|
||||
historyType: item.historyType,
|
||||
tableName: item.tableName,
|
||||
tranId: item.tranId,
|
||||
userId: item.userId
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (allChangedItems.length === 0) {
|
||||
return (
|
||||
<TableWrapper>
|
||||
<div style={{ textAlign: 'center', padding: '20px', color: '#666' }}>
|
||||
변경 항목이 없습니다.
|
||||
</div>
|
||||
</TableWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// 값 포맷팅 함수
|
||||
const formatValue = (value) => {
|
||||
if (value === null || value === undefined) return '';
|
||||
if (typeof value === 'object') {
|
||||
if (value.$date) return convertKTC(value.$date,false);
|
||||
if (value.$oid) return value.$oid;
|
||||
if (value.$numberLong) return value.$numberLong;
|
||||
return JSON.stringify(value);
|
||||
}
|
||||
return String(value);
|
||||
};
|
||||
|
||||
return (
|
||||
<TableStyle style={{ minWidth: 'auto', width: '100%', tableLayout: 'fixed' }}>
|
||||
<caption>변경 항목 목록</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="60px">유형</th>
|
||||
<th width="120px">필드명</th>
|
||||
<th width="150px">신규 값</th>
|
||||
<th width="150px">이전 값</th>
|
||||
<th width="100px">작업자</th>
|
||||
<th width="130px">작업일시(KST)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{allChangedItems.map((item, index) => {
|
||||
if (historyBenField.includes(item.fieldName)) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<tr key={index}>
|
||||
<td>{getFieldLabel(item.sourceInfo.operationType)}</td>
|
||||
<td>{item.fieldName}</td>
|
||||
<td>{formatValue(item.newValue)}</td>
|
||||
<td>{formatValue(item.oldValue)}</td>
|
||||
<td>{item.sourceInfo.userId}</td>
|
||||
<td>{convertKTC(item.sourceInfo.timestamp, false)}</td>
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</TableStyle>
|
||||
);
|
||||
};
|
||||
|
||||
// 단일 뷰 또는 탭 뷰 렌더링 결정
|
||||
const renderContent = () => {
|
||||
if ((viewMode === 'data' && !detailData) || (viewMode === 'changed' && !changedData)) return null;
|
||||
|
||||
// 단일 뷰 모드
|
||||
if (viewMode === 'data') {
|
||||
return renderDataTable();
|
||||
}
|
||||
|
||||
if (viewMode === 'changed') {
|
||||
return renderChangedTable();
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* 탭 메뉴 */}
|
||||
<TabContainer>
|
||||
<Tab
|
||||
$active={activeTab === 'data'}
|
||||
onClick={() => setActiveTab('data')}
|
||||
>
|
||||
데이터 정보
|
||||
</Tab>
|
||||
<Tab
|
||||
$active={activeTab === 'changed'}
|
||||
onClick={() => setActiveTab('changed')}
|
||||
>
|
||||
변경 항목
|
||||
</Tab>
|
||||
</TabContainer>
|
||||
|
||||
{/* 탭 컨텐츠 */}
|
||||
<TabContent $active={activeTab === 'data'}>
|
||||
{renderDataTable()}
|
||||
</TabContent>
|
||||
|
||||
<TabContent $active={activeTab === 'changed'}>
|
||||
{renderChangedTable()}
|
||||
</TabContent>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal $view={detailView} min="400px">
|
||||
<Title $align="center">{title}</Title>
|
||||
|
||||
{renderContent()}
|
||||
|
||||
<BtnWrapper2 $justify="center">
|
||||
<Button
|
||||
theme="line"
|
||||
text="확인"
|
||||
handleClick={e => {
|
||||
e.preventDefault();
|
||||
handleDetailView();
|
||||
}}
|
||||
/>
|
||||
</BtnWrapper2>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default LogDetailModal;
|
||||
|
||||
|
||||
const BtnWrapper2 = styled(BtnWrapper)`
|
||||
margin-top: 30px;
|
||||
`;
|
||||
|
||||
const TabContainer = styled.div`
|
||||
display: flex;
|
||||
margin: 20px 0 10px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
`;
|
||||
@@ -70,7 +70,16 @@ export const useEnhancedCommonSearch = (configPath) => {
|
||||
...searchParams,
|
||||
...newParams
|
||||
});
|
||||
} else {
|
||||
} else if (paginationType === 'front') {
|
||||
// front 타입은 단순히 originalHandleSearch 호출
|
||||
// 페이지 정보는 무시하고 모든 데이터 가져오기
|
||||
const completeParams = {
|
||||
...searchParams,
|
||||
...newParams
|
||||
};
|
||||
updateSearchParams(completeParams);
|
||||
return await originalHandleSearch(completeParams, true);
|
||||
} else{
|
||||
updateSearchParams(newParams);
|
||||
return await rdsPagenation.goToPage(1);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import {initReactI18next} from 'react-i18next';
|
||||
const resources = {
|
||||
ko: {
|
||||
translation: {
|
||||
//메시지
|
||||
NULL_MSG: '필수값을 입력해주세요.',
|
||||
DATE_KTC: '* UTC+9 한국시간 기준으로 설정 (UTC+0 자동 반영처리)',
|
||||
NOT_ITEM: '존재하지 않는 아이템코드입니다.',
|
||||
|
||||
@@ -18,14 +18,10 @@ import {
|
||||
authType,
|
||||
modalTypes,
|
||||
} from '../../assets/data';
|
||||
import { INITIAL_PAGE_LIMIT, INITIAL_PAGE_SIZE } from '../../assets/data/adminConstants';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
Button,
|
||||
DownloadProgress,
|
||||
DynamicModal,
|
||||
ExcelDownButton,
|
||||
Pagination,
|
||||
TopButton,
|
||||
ViewTableInfo,
|
||||
} from '../../components/common';
|
||||
@@ -33,26 +29,27 @@ import { TableSkeleton } from '../../components/Skeleton/TableSkeleton';
|
||||
import BusinessLogSearchBar, { useBusinessLogSearch } from '../../components/ServiceManage/searchBar/BusinessLogSearchBar';
|
||||
import styled from 'styled-components';
|
||||
import FrontPagination from '../../components/common/Pagination/FrontPagination';
|
||||
import Loading from '../../components/common/Loading';
|
||||
import CircularProgress from '../../components/common/CircularProgress';
|
||||
import VerticalDotsButton from '../../components/common/button/VerticalDotsButton';
|
||||
import MessageInput from '../../components/common/input/MessageInput';
|
||||
import { AnalyzeAI } from '../../apis';
|
||||
// import MessageInput from '../../components/common/input/MessageInput';
|
||||
// import { AnalyzeAI } from '../../apis';
|
||||
import {
|
||||
INITIAL_CURRENT_PAGE,
|
||||
INITIAL_PAGE_LIMIT,
|
||||
STORAGE_BUSINESS_LOG_SEARCH,
|
||||
} from '../../assets/data/adminConstants';
|
||||
|
||||
const BusinessLogView = () => {
|
||||
const token = sessionStorage.getItem('token');
|
||||
const { t } = useTranslation();
|
||||
const tableRef = useRef(null);
|
||||
|
||||
const [alertMsg, setAlertMsg] = useState('');
|
||||
|
||||
const [expandedRows, setExpandedRows] = useState({});
|
||||
const [downloadState, setDownloadState] = useState({
|
||||
loading: false,
|
||||
progress: 0
|
||||
});
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [currentPage, setCurrentPage] = useState(INITIAL_CURRENT_PAGE);
|
||||
const [itemsPerPage, setItemsPerPage] = useState(500);
|
||||
const [displayData, setDisplayData] = useState([]);
|
||||
|
||||
@@ -65,7 +62,25 @@ const BusinessLogView = () => {
|
||||
handlePageChange,
|
||||
handleOrderByChange,
|
||||
updateSearchParams
|
||||
} = useBusinessLogSearch(token, 500, setAlertMsg);
|
||||
} = useBusinessLogSearch(token, 500);
|
||||
|
||||
useEffect(() => {
|
||||
// 세션 스토리지에서 복사된 메일 데이터 가져오기
|
||||
const paramsData = sessionStorage.getItem(STORAGE_BUSINESS_LOG_SEARCH);
|
||||
|
||||
if (paramsData) {
|
||||
const searchData = JSON.parse(paramsData);
|
||||
|
||||
handleSearch({
|
||||
log_action: searchData.action,
|
||||
start_dt: searchData.start_dt,
|
||||
end_dt: searchData.end_dt
|
||||
});
|
||||
|
||||
// 사용 후 세션 스토리지 데이터 삭제
|
||||
sessionStorage.removeItem(STORAGE_BUSINESS_LOG_SEARCH);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handlePageSizeChange = (newSize) => {
|
||||
setItemsPerPage(newSize);
|
||||
@@ -167,22 +182,14 @@ const BusinessLogView = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const handleModalSubmit = async (type, param = null) => {
|
||||
switch (type) {
|
||||
case "warning":
|
||||
setAlertMsg('')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const handleMessage = (message) => {
|
||||
const params = {}
|
||||
params.message = message;
|
||||
params.type = 'BUSINESS_LOG'
|
||||
params.conditions = searchParams;
|
||||
AnalyzeAI(token, params);
|
||||
|
||||
}
|
||||
// const handleMessage = (message) => {
|
||||
// const params = {}
|
||||
// params.message = message;
|
||||
// params.type = 'BUSINESS_LOG'
|
||||
// params.conditions = searchParams;
|
||||
// AnalyzeAI(token, params);
|
||||
//
|
||||
// }
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -217,7 +224,7 @@ const BusinessLogView = () => {
|
||||
</CircularProgressWrapper>
|
||||
)}
|
||||
</DownloadContainer>
|
||||
<MessageInput onSendMessage={handleMessage} />
|
||||
{/*<MessageInput onSendMessage={handleMessage} />*/}
|
||||
</ViewTableInfo>
|
||||
{dataLoading ? <TableSkeleton width='100%' count={15} /> :
|
||||
<>
|
||||
@@ -274,19 +281,12 @@ const BusinessLogView = () => {
|
||||
itemsPerPage={itemsPerPage}
|
||||
currentPage={currentPage}
|
||||
setCurrentPage={setCurrentPage}
|
||||
pageLimit={10}
|
||||
pageLimit={INITIAL_PAGE_LIMIT}
|
||||
onPageChange={handleClientPageChange}
|
||||
/>}
|
||||
<TopButton />
|
||||
</>
|
||||
}
|
||||
|
||||
<DynamicModal
|
||||
modalType={modalTypes.completed}
|
||||
view={alertMsg ? 'view' : 'hidden'}
|
||||
modalText={alertMsg}
|
||||
handleSubmit={() => handleModalSubmit('warning')}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState, Fragment, useRef } from 'react';
|
||||
import React, { useState, Fragment, useRef } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import 'react-datepicker/dist/react-datepicker.css';
|
||||
@@ -41,6 +41,9 @@ import { getDateOnly, getTimeOnly, secondToMinutes } from '../../utils/date';
|
||||
import { alertTypes, battleEventStatusType } from '../../assets/data/types';
|
||||
import { useAlert } from '../../context/AlertProvider';
|
||||
import { useLoading } from '../../context/LoadingProvider';
|
||||
import LogDetailModal from '../../components/common/modal/LogDetailModal';
|
||||
import { historyTables } from '../../assets/data/data';
|
||||
import { LogHistory } from '../../apis';
|
||||
|
||||
const BattleEvent = () => {
|
||||
const token = sessionStorage.getItem('token');
|
||||
@@ -51,6 +54,7 @@ const BattleEvent = () => {
|
||||
const {withLoading} = useLoading();
|
||||
|
||||
const [detailData, setDetailData] = useState({});
|
||||
const [historyData, setHistoryData] = useState({});
|
||||
|
||||
const {
|
||||
modalState,
|
||||
@@ -58,6 +62,7 @@ const BattleEvent = () => {
|
||||
handleModalClose
|
||||
} = useModal({
|
||||
detail: 'hidden',
|
||||
history: 'hidden'
|
||||
});
|
||||
const [modalType, setModalType] = useState('regist');
|
||||
|
||||
@@ -123,6 +128,17 @@ const BattleEvent = () => {
|
||||
|
||||
const handleModalSubmit = async (type, param = null) => {
|
||||
switch (type) {
|
||||
case "history":
|
||||
const params = {};
|
||||
params.db_type = "MYSQL"
|
||||
params.sql_id = param.id;
|
||||
params.table_name = historyTables.battleEvent
|
||||
|
||||
await LogHistory(token, params).then(data => {
|
||||
setHistoryData(data);
|
||||
handleModalView('history');
|
||||
});
|
||||
break;
|
||||
case "regist":
|
||||
setModalType('regist');
|
||||
handleModalView('detail');
|
||||
@@ -290,40 +306,41 @@ const BattleEvent = () => {
|
||||
</thead>
|
||||
<tbody>
|
||||
{dataList?.event_list?.map(battle => (
|
||||
<tr key={battle.row_num}>
|
||||
<td>
|
||||
<CheckBox name={'select'} id={battle.id}
|
||||
setData={(e) => handleSelectRow(e, battle)}
|
||||
checked={isRowSelected(battle.id)} />
|
||||
</td>
|
||||
<td>{battle.group_id}</td>
|
||||
<td>{battle.event_id}</td>
|
||||
<td>{battle.event_name}</td>
|
||||
<StatusWapper>
|
||||
<StatusLabel $status={battle.repeat_type}>
|
||||
{battleRepeatType.find(data => data.value === battle.repeat_type).name}
|
||||
</StatusLabel>
|
||||
</StatusWapper>
|
||||
<td>{getDateOnly(convertKTCDate(battle.event_start_dt))}</td>
|
||||
<td>{getDateOnly(battle.event_end_dt)}</td>
|
||||
<td>{getTimeOnly(convertKTCDate(battle.event_start_dt))}</td>
|
||||
<td>{getTimeOnly(endTime(convertKTCDate(battle.event_start_dt), battle.event_operation_time))}</td>
|
||||
<StatusWapper>
|
||||
<StatusLabel $status={battle.status}>
|
||||
{battleEventStatus.find(data => data.value === battle.status).name}
|
||||
</StatusLabel>
|
||||
</StatusWapper>
|
||||
<td>{secondToMinutes(battle.round_time)}분</td>
|
||||
<td>{battle.reward_group_id}</td>
|
||||
<td>{battle.round_count}</td>
|
||||
<td>{battle.hot_time}</td>
|
||||
<td>
|
||||
<Button theme="line" text="상세보기"
|
||||
handleClick={e => handleModalSubmit('detail', battle.id)} />
|
||||
</td>
|
||||
<td>{battle.update_by}</td>
|
||||
</tr>
|
||||
))}
|
||||
<tr key={battle.row_num}>
|
||||
<td>
|
||||
<CheckBox name={'select'} id={battle.id}
|
||||
setData={(e) => handleSelectRow(e, battle)}
|
||||
checked={isRowSelected(battle.id)} />
|
||||
</td>
|
||||
<td>{battle.group_id}</td>
|
||||
<td>{battle.event_id}</td>
|
||||
<td>{battle.event_name}</td>
|
||||
<StatusWapper>
|
||||
<StatusLabel $status={battle.repeat_type}>
|
||||
{battleRepeatType.find(data => data.value === battle.repeat_type).name}
|
||||
</StatusLabel>
|
||||
</StatusWapper>
|
||||
<td>{getDateOnly(convertKTCDate(battle.event_start_dt))}</td>
|
||||
<td>{getDateOnly(battle.event_end_dt)}</td>
|
||||
<td>{getTimeOnly(convertKTCDate(battle.event_start_dt))}</td>
|
||||
<td>{getTimeOnly(endTime(convertKTCDate(battle.event_start_dt), battle.event_operation_time))}</td>
|
||||
<StatusWapper>
|
||||
<StatusLabel $status={battle.status}>
|
||||
{battleEventStatus.find(data => data.value === battle.status).name}
|
||||
</StatusLabel>
|
||||
</StatusWapper>
|
||||
<td>{secondToMinutes(battle.round_time)}분</td>
|
||||
<td>{battle.reward_group_id}</td>
|
||||
<td>{battle.round_count}</td>
|
||||
<td>{battle.hot_time}</td>
|
||||
<td>
|
||||
<Button theme="line" text="상세보기"
|
||||
handleClick={e => handleModalSubmit('detail', battle.id)} />
|
||||
</td>
|
||||
<td><Button theme="line" text="히스토리"
|
||||
handleClick={e => handleModalSubmit('history', battle)} /></td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</TableStyle>
|
||||
</TableWrapper>
|
||||
@@ -344,6 +361,14 @@ const BattleEvent = () => {
|
||||
rewardData={battleRewardData}
|
||||
/>
|
||||
|
||||
<LogDetailModal
|
||||
viewMode="changed"
|
||||
detailView={modalState.historyModal}
|
||||
handleDetailView={() => handleModalClose('history')}
|
||||
changedData={historyData}
|
||||
title="히스토리"
|
||||
/>
|
||||
|
||||
</>
|
||||
)
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Fragment, useState } from 'react';
|
||||
import React, { Fragment, useState } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
@@ -33,6 +33,9 @@ import { BattleEventDelete, BattleEventDetailView, BattleEventStop } from '../..
|
||||
import { alertTypes, battleEventStatusType } from '../../assets/data/types';
|
||||
import { useModal, useTable, withAuth } from '../../hooks/hook';
|
||||
import { useLoading } from '../../context/LoadingProvider';
|
||||
import LogDetailModal from '../../components/common/modal/LogDetailModal';
|
||||
import { historyTables } from '../../assets/data/data';
|
||||
import { LogHistory } from '../../apis';
|
||||
|
||||
const Board = () => {
|
||||
const token = sessionStorage.getItem('token');
|
||||
@@ -47,6 +50,15 @@ const Board = () => {
|
||||
const [registView, setRegistView] = useState('hidden');
|
||||
const [detailData, setDetailData] = useState('');
|
||||
const [detailId, setDetailId] = useState('');
|
||||
const [historyData, setHistoryData] = useState({});
|
||||
|
||||
const {
|
||||
modalState,
|
||||
handleModalView,
|
||||
handleModalClose
|
||||
} = useModal({
|
||||
history: 'hidden'
|
||||
});
|
||||
|
||||
const {
|
||||
selectedRows,
|
||||
@@ -64,6 +76,18 @@ const Board = () => {
|
||||
|
||||
const handleModalSubmit = async (type, param = null) => {
|
||||
switch (type) {
|
||||
case "history":
|
||||
const params = {};
|
||||
params.db_type = "MYSQL"
|
||||
params.sql_id = param.id;
|
||||
params.table_name = historyTables.notice
|
||||
|
||||
await LogHistory(token, params).then(data => {
|
||||
setHistoryData(data);
|
||||
console.log(data);
|
||||
handleModalView('history');
|
||||
});
|
||||
break;
|
||||
case "detail":
|
||||
await NoticeDetailView(token, param.id).then(data => {
|
||||
setDetailData(data);
|
||||
@@ -136,9 +160,7 @@ const Board = () => {
|
||||
<th>메시지</th>
|
||||
<th width="80">송출 횟수</th>
|
||||
<th width="100">송출 상태</th>
|
||||
<th width="120">등록자</th>
|
||||
<th width="200">등록자(이메일주소)</th>
|
||||
<th width="200">등록일자</th>
|
||||
<th width="120">히스토리</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -167,9 +189,9 @@ const Board = () => {
|
||||
<td>
|
||||
{sendStatus.find(data => data.value === notice.send_status)?.name}
|
||||
</td>
|
||||
<td>{notice.create_name}</td>
|
||||
<td>{notice.create_by}</td>
|
||||
<td>{convertKTC(notice.create_dt)}</td>
|
||||
<td><Button theme="line" text="히스토리"
|
||||
handleClick={e => handleModalSubmit('history', notice)} />
|
||||
</td>
|
||||
</tr>
|
||||
</Fragment>
|
||||
))}
|
||||
@@ -187,6 +209,13 @@ const Board = () => {
|
||||
/>
|
||||
{/* 인게임 메세지 등록 */}
|
||||
<BoardRegistModal registView={registView} setRegistView={setRegistView} copyData={isCopyData ? detailData : ''} setIsCopyData={setIsCopyData} userInfo={userInfo} />
|
||||
<LogDetailModal
|
||||
viewMode="changed"
|
||||
detailView={modalState.historyModal}
|
||||
handleDetailView={() => handleModalClose('history')}
|
||||
changedData={historyData}
|
||||
title="히스토리"
|
||||
/>
|
||||
</TableWrapper>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { useState, Fragment } from 'react';
|
||||
import React, { useState, Fragment } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import {
|
||||
EventDelete,
|
||||
EventDetailView
|
||||
EventDetailView, LogHistory,
|
||||
} from '../../apis';
|
||||
|
||||
import { authList } from '../../store/authList';
|
||||
@@ -33,6 +33,8 @@ import { useModal, useTable } from '../../hooks/hook';
|
||||
import { INITIAL_PAGE_LIMIT } from '../../assets/data/adminConstants';
|
||||
import { alertTypes } from '../../assets/data/types';
|
||||
import useCommonSearchOld from '../../hooks/useCommonSearchOld';
|
||||
import { historyTables } from '../../assets/data/data';
|
||||
import LogDetailModal from '../../components/common/modal/LogDetailModal';
|
||||
|
||||
const Event = () => {
|
||||
const token = sessionStorage.getItem('token');
|
||||
@@ -43,6 +45,7 @@ const Event = () => {
|
||||
|
||||
const navigate = useNavigate();
|
||||
const [detailData, setDetailData] = useState('');
|
||||
const [historyData, setHistoryData] = useState({});
|
||||
|
||||
const {
|
||||
modalState,
|
||||
@@ -51,6 +54,7 @@ const Event = () => {
|
||||
} = useModal({
|
||||
detail: 'hidden',
|
||||
delete: 'hidden',
|
||||
history: 'hidden'
|
||||
});
|
||||
const [deleteDesc, setDeleteDesc] = useState('');
|
||||
|
||||
@@ -85,6 +89,17 @@ const Event = () => {
|
||||
|
||||
const handleModalSubmit = async (type, param = null) => {
|
||||
switch (type) {
|
||||
case "history":
|
||||
const params = {};
|
||||
params.db_type = "MYSQL"
|
||||
params.sql_id = param.id;
|
||||
params.table_name = historyTables.event
|
||||
|
||||
await LogHistory(token, params).then(data => {
|
||||
setHistoryData(data);
|
||||
handleModalView('history');
|
||||
});
|
||||
break;
|
||||
case "delete":
|
||||
const delete_check = selectedRows.every(row => {
|
||||
const timeDiff = timeDiffMinute(convertKTC(row.start_dt), (new Date));
|
||||
@@ -188,7 +203,7 @@ const Event = () => {
|
||||
<th width="210">종료 일시</th>
|
||||
<th>우편 제목</th>
|
||||
<th width="110">확인 / 수정</th>
|
||||
<th width="200">등록자(처리자)</th>
|
||||
<th width="200">히스토리</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -213,7 +228,9 @@ const Event = () => {
|
||||
<Button theme="line" text="상세보기"
|
||||
handleClick={e => handleDetailModal(e, event.id)} />
|
||||
</td>
|
||||
<td>{event.create_by}</td>
|
||||
<td><Button theme="line" text="히스토리"
|
||||
handleClick={e => handleModalSubmit('history', event)} />
|
||||
</td>
|
||||
</tr>
|
||||
</Fragment>
|
||||
))}
|
||||
@@ -234,6 +251,14 @@ const Event = () => {
|
||||
setDetailData={setDetailData}
|
||||
/>
|
||||
|
||||
<LogDetailModal
|
||||
viewMode="changed"
|
||||
detailView={modalState.historyModal}
|
||||
handleDetailView={() => handleModalClose('history')}
|
||||
changedData={historyData}
|
||||
title="히스토리"
|
||||
/>
|
||||
|
||||
<DynamicModal
|
||||
modalType={modalTypes.childOkCancel}
|
||||
view={modalState.deleteModal}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState, Fragment, useRef } from 'react';
|
||||
import React, { useState, Fragment, useRef } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import 'react-datepicker/dist/react-datepicker.css';
|
||||
@@ -6,7 +6,7 @@ import 'react-datepicker/dist/react-datepicker.css';
|
||||
import {
|
||||
BuildingView,
|
||||
LandAuctionDelete,
|
||||
LandAuctionDetailView, LandView,
|
||||
LandAuctionDetailView, LandView, LogHistory,
|
||||
} from '../../apis';
|
||||
|
||||
import { authList } from '../../store/authList';
|
||||
@@ -34,6 +34,8 @@ import { useLandAuctionSearch } from '../../components/ServiceManage/searchBar/L
|
||||
import { StatusWapper, ChargeBtn, StatusLabel } from '../../styles/ModuleComponents';
|
||||
import { alertTypes } from '../../assets/data/types';
|
||||
import { useAlert } from '../../context/AlertProvider';
|
||||
import LogDetailModal from '../../components/common/modal/LogDetailModal';
|
||||
import { historyTables } from '../../assets/data/data';
|
||||
|
||||
const LandAuction = () => {
|
||||
const token = sessionStorage.getItem('token');
|
||||
@@ -43,6 +45,7 @@ const LandAuction = () => {
|
||||
const { showToast, showModal } = useAlert();
|
||||
|
||||
const [detailData, setDetailData] = useState({});
|
||||
const [historyData, setHistoryData] = useState({});
|
||||
|
||||
const {
|
||||
modalState,
|
||||
@@ -50,6 +53,7 @@ const LandAuction = () => {
|
||||
handleModalClose
|
||||
} = useModal({
|
||||
detail: 'hidden',
|
||||
history: 'hidden'
|
||||
});
|
||||
const [alertMsg, setAlertMsg] = useState('');
|
||||
const [modalType, setModalType] = useState('regist');
|
||||
@@ -81,6 +85,17 @@ const LandAuction = () => {
|
||||
|
||||
const handleModalSubmit = async (type, param = null) => {
|
||||
switch (type) {
|
||||
case "history":
|
||||
const params = {};
|
||||
params.db_type = "MYSQL"
|
||||
params.sql_id = param.id;
|
||||
params.table_name = historyTables.landAuction
|
||||
|
||||
await LogHistory(token, params).then(data => {
|
||||
setHistoryData(data);
|
||||
handleModalView('history');
|
||||
});
|
||||
break;
|
||||
case "regist":
|
||||
setModalType('regist');
|
||||
handleModalView('detail');
|
||||
@@ -230,7 +245,8 @@ const LandAuction = () => {
|
||||
<Button theme="line" text="상세보기"
|
||||
handleClick={e => handleModalSubmit('detail', auction.id)} />
|
||||
</td>
|
||||
<td>{auction.update_by}</td>
|
||||
<td><Button theme="line" text="히스토리"
|
||||
handleClick={e => handleModalSubmit('history', auction)} /></td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
@@ -253,6 +269,14 @@ const LandAuction = () => {
|
||||
buildingData={buildingData}
|
||||
/>
|
||||
|
||||
<LogDetailModal
|
||||
viewMode="changed"
|
||||
detailView={modalState.historyModal}
|
||||
handleDetailView={() => handleModalClose('history')}
|
||||
changedData={historyData}
|
||||
title="히스토리"
|
||||
/>
|
||||
|
||||
</>
|
||||
)
|
||||
};
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import styled from 'styled-components';
|
||||
import { useState, Fragment } from 'react';
|
||||
import React, { useState, Fragment } from 'react';
|
||||
|
||||
import CheckBox from '../../components/common/input/CheckBox';
|
||||
|
||||
import { MailDelete, MailDetailView } from '../../apis';
|
||||
import { LogHistory, MailDelete, MailDetailView } from '../../apis';
|
||||
|
||||
import { Title, FormWrapper, TableStyle, MailTitle, TableWrapper } from '../../styles/Components';
|
||||
import Button from '../../components/common/button/Button';
|
||||
@@ -32,6 +32,8 @@ import { useModal, useTable, withAuth } from '../../hooks/hook';
|
||||
import { useAlert } from '../../context/AlertProvider';
|
||||
import { useLoading } from '../../context/LoadingProvider';
|
||||
import useCommonSearchOld from '../../hooks/useCommonSearchOld';
|
||||
import LogDetailModal from '../../components/common/modal/LogDetailModal';
|
||||
import { historyTables } from '../../assets/data/data';
|
||||
|
||||
const Mail = () => {
|
||||
const token = sessionStorage.getItem('token');
|
||||
@@ -41,6 +43,7 @@ const Mail = () => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [detailData, setDetailData] = useState('');
|
||||
const [historyData, setHistoryData] = useState({});
|
||||
|
||||
const {
|
||||
modalState,
|
||||
@@ -48,6 +51,7 @@ const Mail = () => {
|
||||
handleModalClose
|
||||
} = useModal({
|
||||
detail: 'hidden',
|
||||
history: 'hidden'
|
||||
});
|
||||
|
||||
const {
|
||||
@@ -71,6 +75,17 @@ const Mail = () => {
|
||||
|
||||
const handleModalSubmit = async (type, param = null) => {
|
||||
switch (type) {
|
||||
case "history":
|
||||
const params = {};
|
||||
params.db_type = "MYSQL"
|
||||
params.sql_id = param.id;
|
||||
params.table_name = historyTables.mail
|
||||
|
||||
await LogHistory(token, params).then(data => {
|
||||
setHistoryData(data);
|
||||
handleModalView('history');
|
||||
});
|
||||
break;
|
||||
case "detail":
|
||||
await MailDetailView(token, param).then(data => {
|
||||
setDetailData(data);
|
||||
@@ -167,7 +182,7 @@ const Mail = () => {
|
||||
<th width="100">수신 대상</th>
|
||||
<th>우편 제목</th>
|
||||
<th width="110">확인 / 수정</th>
|
||||
<th width="200">등록자(처리자)</th>
|
||||
<th width="200">히스토리</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -192,12 +207,15 @@ const Mail = () => {
|
||||
<td>{mailReceiveType.map(data => data.value === mail.receive_type && data.name)}</td>
|
||||
<MailTitle>{mail.title}</MailTitle>
|
||||
<td>
|
||||
<Button theme="line" text="상세보기" handleClick={e => handleModalSubmit('detail', mail.id)} />
|
||||
<Button theme="line" text="상세보기"
|
||||
handleClick={e => handleModalSubmit('detail', mail.id)} />
|
||||
</td>
|
||||
<td><Button theme="line" text="히스토리"
|
||||
handleClick={e => handleModalSubmit('history', mail)} />
|
||||
</td>
|
||||
<td>{mail.create_by}</td>
|
||||
</tr>
|
||||
</Fragment>
|
||||
))}
|
||||
))}
|
||||
</tbody>
|
||||
</TableStyle>
|
||||
</TableWrapper>
|
||||
@@ -212,6 +230,14 @@ const Mail = () => {
|
||||
content={detailData}
|
||||
/>
|
||||
|
||||
<LogDetailModal
|
||||
viewMode="changed"
|
||||
detailView={modalState.historyModal}
|
||||
handleDetailView={() => handleModalClose('history')}
|
||||
changedData={historyData}
|
||||
title="히스토리"
|
||||
/>
|
||||
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -36,6 +36,7 @@ import { alertTypes, currencyCodeTypes } from '../../assets/data/types';
|
||||
import { useLoading } from '../../context/LoadingProvider';
|
||||
import { useAlert } from '../../context/AlertProvider';
|
||||
import { userType2 } from '../../assets/data/options';
|
||||
import { STORAGE_MAIL_COPY } from '../../assets/data/adminConstants';
|
||||
|
||||
const MailRegist = () => {
|
||||
const navigate = useNavigate();
|
||||
@@ -49,7 +50,7 @@ const MailRegist = () => {
|
||||
const [sendMin, setSendMin] = useState('00');
|
||||
|
||||
const [item, setItem] = useState('');
|
||||
const [itemCount, setItemCount] = useState('');
|
||||
const [itemCount, setItemCount] = useState('1');
|
||||
const [resource, setResource] = useState(currencyCodeTypes.gold);
|
||||
const [resourceCount, setResourceCount] = useState(0);
|
||||
|
||||
@@ -95,7 +96,7 @@ const MailRegist = () => {
|
||||
|
||||
useEffect(() => {
|
||||
// 세션 스토리지에서 복사된 메일 데이터 가져오기
|
||||
const copiedMailData = sessionStorage.getItem('copyMailData');
|
||||
const copiedMailData = sessionStorage.getItem(STORAGE_MAIL_COPY);
|
||||
|
||||
if (copiedMailData) {
|
||||
const mailData = JSON.parse(copiedMailData);
|
||||
@@ -118,7 +119,7 @@ const MailRegist = () => {
|
||||
}
|
||||
|
||||
// 사용 후 세션 스토리지 데이터 삭제
|
||||
sessionStorage.removeItem('copyMailData');
|
||||
sessionStorage.removeItem(STORAGE_MAIL_COPY);
|
||||
}
|
||||
}, []);
|
||||
|
||||
@@ -161,14 +162,14 @@ const MailRegist = () => {
|
||||
setIsItemNullValue(true);
|
||||
} else if (item.length !== 0) {
|
||||
setIsItemNullValue(false);
|
||||
const itemIndex = resultData.item_list.findIndex(
|
||||
data => data.item === item
|
||||
);
|
||||
|
||||
if (itemIndex !== -1) {
|
||||
showToast('MAIL_ITEM_ADD_DUPL', { type: alertTypes.warning });
|
||||
return;
|
||||
}
|
||||
// const itemIndex = resultData.item_list.findIndex(
|
||||
// data => data.item === item
|
||||
// );
|
||||
//
|
||||
// if (itemIndex !== -1) {
|
||||
// showToast('MAIL_ITEM_ADD_DUPL', { type: alertTypes.warning });
|
||||
// return;
|
||||
// }
|
||||
const newItem = { item: item, item_cnt: itemCount, item_name: data.data.item_info.item_name };
|
||||
|
||||
resultData.item_list.push(newItem);
|
||||
|
||||
433
src/pages/ServiceManage/MenuBannerRegist_bak.js
Normal file
433
src/pages/ServiceManage/MenuBannerRegist_bak.js
Normal file
@@ -0,0 +1,433 @@
|
||||
import React, { useState, Fragment, useEffect } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import Button from '../../components/common/button/Button';
|
||||
import Loading from '../../components/common/Loading';
|
||||
import {
|
||||
Title,
|
||||
BtnWrapper,
|
||||
SearchBarAlert,
|
||||
} from '../../styles/Components';
|
||||
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { MenuBannerSingleRegist } from '../../apis';
|
||||
|
||||
import { authList } from '../../store/authList';
|
||||
import {
|
||||
FormInput, FormInputSuffix, FormInputSuffixWrapper, FormLabel, FormRowGroup,RegistGroup,
|
||||
} from '../../styles/ModuleComponents';
|
||||
import AuthModal from '../../components/common/modal/AuthModal';
|
||||
import { authType, modalTypes } from '../../assets/data';
|
||||
import DynamicModal from '../../components/common/modal/DynamicModal';
|
||||
import { loadConfig, timeDiffMinute } from '../../utils';
|
||||
import { SingleDatePicker, SingleTimePicker } from '../../components/common';
|
||||
import CheckBox from '../../components/common/input/CheckBox';
|
||||
import ImageUploadBtn from '../../components/ServiceManage/ImageUploadBtn';
|
||||
import { useModal } from '../../hooks/hook';
|
||||
|
||||
const MenuBannerRegist = () => {
|
||||
const navigate = useNavigate();
|
||||
const userInfo = useRecoilValue(authList);
|
||||
const { t } = useTranslation();
|
||||
const token = sessionStorage.getItem('token');
|
||||
|
||||
const [loading, setLoading] = useState(false); // 로딩 창
|
||||
const {
|
||||
modalState,
|
||||
handleModalView,
|
||||
handleModalClose
|
||||
} = useModal({
|
||||
cancel: 'hidden',
|
||||
registConfirm: 'hidden',
|
||||
registComplete: 'hidden'
|
||||
});
|
||||
|
||||
const [isNullValue, setIsNullValue] = useState(false); // 데이터 값 체크
|
||||
const [alertMsg, setAlertMsg] = useState('');
|
||||
|
||||
const [resultData, setResultData] = useState(initData); //데이터 정보
|
||||
const [resetDateTime, setResetDateTime] = useState(false);
|
||||
|
||||
const [pageConfig, setPageConfig] = useState(null);
|
||||
const [formData, setFormData] = useState({});
|
||||
|
||||
useEffect(() => {
|
||||
const loadPageConfig = async () => {
|
||||
try {
|
||||
const config = await loadConfig('menuBannerRegist');
|
||||
setPageConfig(config);
|
||||
setFormData(config.initData);
|
||||
} catch (error) {
|
||||
console.error('Failed to load page configuration', error);
|
||||
}
|
||||
};
|
||||
|
||||
loadPageConfig();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (checkCondition()) {
|
||||
setIsNullValue(false);
|
||||
} else {
|
||||
setIsNullValue(true);
|
||||
}
|
||||
}, [resultData]);
|
||||
|
||||
useEffect(() => {
|
||||
if (resetDateTime) {
|
||||
setResetDateTime(false);
|
||||
}
|
||||
}, [resetDateTime]);
|
||||
|
||||
// 시작 날짜 변경 핸들러
|
||||
const handleStartDateChange = (date) => {
|
||||
if (!date) return;
|
||||
|
||||
const newDate = new Date(date);
|
||||
|
||||
if(resultData.end_dt){
|
||||
const endDate = new Date(resultData.end_dt);
|
||||
const startDay = new Date(newDate.getFullYear(), newDate.getMonth(), newDate.getDate());
|
||||
const endDay = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate());
|
||||
|
||||
if (endDay <= startDay) {
|
||||
setAlertMsg(t('DATE_START_DIFF_END_WARNING'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setResultData(prev => ({
|
||||
...prev,
|
||||
start_dt: newDate
|
||||
}));
|
||||
};
|
||||
|
||||
// 시작 시간 변경 핸들러
|
||||
const handleStartTimeChange = (time) => {
|
||||
if (!time) return;
|
||||
|
||||
const newDateTime = resultData.start_dt
|
||||
? new Date(resultData.start_dt)
|
||||
: new Date();
|
||||
|
||||
newDateTime.setHours(
|
||||
time.getHours(),
|
||||
time.getMinutes(),
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
setResultData(prev => ({
|
||||
...prev,
|
||||
start_dt: newDateTime
|
||||
}));
|
||||
};
|
||||
|
||||
// 종료 날짜 변경 핸들러
|
||||
const handleEndDateChange = (date) => {
|
||||
if (!date || !resultData.start_dt) return;
|
||||
|
||||
const startDate = new Date(resultData.start_dt);
|
||||
const endDate = new Date(date);
|
||||
|
||||
// 일자만 비교하기 위해 년/월/일만 추출
|
||||
const startDay = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate());
|
||||
const endDay = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate());
|
||||
|
||||
if (endDay <= startDay) {
|
||||
setAlertMsg(t('DATE_START_DIFF_END_WARNING'));
|
||||
return;
|
||||
}
|
||||
|
||||
setResultData(prev => ({
|
||||
...prev,
|
||||
end_dt: endDate
|
||||
}));
|
||||
};
|
||||
|
||||
// 종료 시간 변경 핸들러
|
||||
const handleEndTimeChange = (time) => {
|
||||
if (!time) return;
|
||||
|
||||
const newDateTime = resultData.end_dt
|
||||
? new Date(resultData.end_dt)
|
||||
: new Date();
|
||||
|
||||
newDateTime.setHours(
|
||||
time.getHours(),
|
||||
time.getMinutes(),
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
setResultData(prev => ({
|
||||
...prev,
|
||||
end_dt: newDateTime
|
||||
}));
|
||||
};
|
||||
|
||||
// 이미지 업로드
|
||||
const handleImageUpload = (language, file, fileName) => {
|
||||
const imageIndex = resultData.image_list.findIndex(img => img.language === language);
|
||||
|
||||
if (imageIndex !== -1) {
|
||||
const updatedImageList = [...resultData.image_list];
|
||||
updatedImageList[imageIndex] = {
|
||||
...updatedImageList[imageIndex],
|
||||
content: fileName,
|
||||
};
|
||||
|
||||
setResultData({
|
||||
...resultData,
|
||||
image_list: updatedImageList
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 이미지 삭제
|
||||
const handleImageDelete = (language) => {
|
||||
const imageIndex = resultData.image_list.findIndex(img => img.language === language);
|
||||
|
||||
if (imageIndex !== -1) {
|
||||
const updatedImageList = [...resultData.image_list];
|
||||
updatedImageList[imageIndex] = {
|
||||
...updatedImageList[imageIndex],
|
||||
content: '',
|
||||
};
|
||||
|
||||
setResultData({
|
||||
...resultData,
|
||||
image_list: updatedImageList
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubmit = async (type, param = null) => {
|
||||
switch (type) {
|
||||
case "submit":
|
||||
if (!checkCondition()) return;
|
||||
const timeDiff = timeDiffMinute(resultData.start_dt, (new Date))
|
||||
if(timeDiff < 60) {
|
||||
setAlertMsg(t('EVENT_TIME_LIMIT_ADD'));
|
||||
return;
|
||||
}
|
||||
|
||||
handleModalView('registConfirm');
|
||||
break;
|
||||
case "cancel":
|
||||
|
||||
handleModalClose('cancel');
|
||||
navigate('/servicemanage/menubanner');
|
||||
break;
|
||||
case "registConfirm":
|
||||
setLoading(true);
|
||||
|
||||
const result = await MenuBannerSingleRegist(token, resultData);
|
||||
|
||||
setLoading(false);
|
||||
handleModalClose('registConfirm');
|
||||
handleModalView('registComplete');
|
||||
break;
|
||||
case "registComplete":
|
||||
handleModalClose('registComplete');
|
||||
|
||||
navigate('/servicemanage/menubanner');
|
||||
break;
|
||||
case "warning":
|
||||
setAlertMsg('');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const checkCondition = () => {
|
||||
return (
|
||||
(resultData.start_dt.length !== 0) &&
|
||||
(resultData.end_dt.length !== 0) &&
|
||||
resultData.title !== '' &&
|
||||
resultData.image_list.every(data => data.content !== '') &&
|
||||
(resultData.is_link === false || (resultData.is_link === true && resultData.link_list.every(data => data.content !== '')))
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{userInfo.auth_list && !userInfo.auth_list.some(auth => auth.id === authType.eventUpdate) ? (
|
||||
<AuthModal/>
|
||||
) : (
|
||||
<>
|
||||
<Title>메뉴배너 등록</Title>
|
||||
<RegistGroup>
|
||||
<FormRowGroup>
|
||||
<FormLabel>등록기간</FormLabel>
|
||||
<SingleDatePicker
|
||||
label="시작일자"
|
||||
dateLabel="시작 일자"
|
||||
onDateChange={handleStartDateChange}
|
||||
selectedDate={resultData?.start_dt}
|
||||
/>
|
||||
<SingleTimePicker
|
||||
selectedTime={resultData?.start_dt}
|
||||
onTimeChange={handleStartTimeChange}
|
||||
/>
|
||||
<SingleDatePicker
|
||||
label="종료일자"
|
||||
dateLabel="종료 일자"
|
||||
onDateChange={handleEndDateChange}
|
||||
selectedDate={resultData?.end_dt}
|
||||
/>
|
||||
<SingleTimePicker
|
||||
selectedTime={resultData?.end_dt}
|
||||
onTimeChange={handleEndTimeChange}
|
||||
/>
|
||||
</FormRowGroup>
|
||||
|
||||
<FormRowGroup>
|
||||
<FormLabel>배너 제목</FormLabel>
|
||||
<FormInput
|
||||
type="text"
|
||||
width='50%'
|
||||
value={resultData?.title}
|
||||
onChange={e => setResultData({ ...resultData, title: e.target.value })}
|
||||
/>
|
||||
</FormRowGroup>
|
||||
<FormLabel>이미지 첨부</FormLabel>
|
||||
{resultData.image_list.map((data, idx) => (
|
||||
<LanguageWrapper key={idx}>
|
||||
<LanguageLabel>{data.language}</LanguageLabel>
|
||||
<ImageUploadBtn
|
||||
onImageUpload={(file, fileName) => handleImageUpload(data.language, file, fileName)}
|
||||
onFileDelete={() => handleImageDelete(data.language)}
|
||||
fileName={data.content}
|
||||
setAlertMessage={setAlertMsg}
|
||||
/>
|
||||
</LanguageWrapper>
|
||||
))}
|
||||
<FormRowGroup>
|
||||
<CheckBox
|
||||
label="이미지 링크 여부"
|
||||
id="reserve"
|
||||
checked={resultData.is_link}
|
||||
setData={e => setResultData({ ...resultData, is_link: e.target.checked })}
|
||||
/>
|
||||
</FormRowGroup>
|
||||
{resultData?.is_link &&
|
||||
<>
|
||||
<FormRowGroup>
|
||||
<FormLabel>웹 링크</FormLabel>
|
||||
<LanguageWrapper width="50%" >
|
||||
{resultData.link_list.map((data, idx) => (
|
||||
<FormInputSuffixWrapper>
|
||||
<FormInput
|
||||
type="text"
|
||||
value={resultData?.link_list[idx].content}
|
||||
onChange={e => {
|
||||
const updatedLinkList = [...resultData.link_list];
|
||||
updatedLinkList[idx] = { ...updatedLinkList[idx], content: e.target.value };
|
||||
setResultData({ ...resultData, link_list: updatedLinkList });
|
||||
}}
|
||||
suffix="true"
|
||||
/>
|
||||
<FormInputSuffix>{data.language}</FormInputSuffix>
|
||||
</FormInputSuffixWrapper>
|
||||
))}
|
||||
</LanguageWrapper>
|
||||
</FormRowGroup>
|
||||
</>
|
||||
}
|
||||
</RegistGroup>
|
||||
|
||||
{isNullValue && (
|
||||
<SearchBarAlert $align="right" $padding="0 0 15px">
|
||||
{t('NULL_MSG')}
|
||||
</SearchBarAlert>
|
||||
)}
|
||||
|
||||
<BtnWrapper $justify="flex-end" $gap="10px">
|
||||
<Button text="취소" theme="line" handleClick={() => handleModalView('cancel')} />
|
||||
<Button
|
||||
type="submit"
|
||||
text="등록"
|
||||
theme={checkCondition() ? 'primary' : 'disable'}
|
||||
handleClick={() => handleSubmit('submit')}
|
||||
/>
|
||||
</BtnWrapper>
|
||||
|
||||
{/* 등록 모달 */}
|
||||
<DynamicModal
|
||||
modalType={modalTypes.confirmOkCancel}
|
||||
view={modalState.registConfirmModal}
|
||||
modalText={t('MENU_BANNER_REGIST_CONFIRM')}
|
||||
handleSubmit={() => handleSubmit('registConfirm')}
|
||||
handleCancel={() => handleModalClose('registConfirm')}
|
||||
/>
|
||||
{/* 완료 모달 */}
|
||||
<DynamicModal
|
||||
modalType={modalTypes.completed}
|
||||
view={modalState.registCompleteModal}
|
||||
modalText={t('REGIST_COMPLTE')}
|
||||
handleSubmit={() => handleSubmit('registComplete')}
|
||||
/>
|
||||
{/* 취소 모달 */}
|
||||
<DynamicModal
|
||||
modalType={modalTypes.confirmOkCancel}
|
||||
view={modalState.cancelModal}
|
||||
modalText={t('MENU_BANNER_REGIST_CANCEL')}
|
||||
handleCancel={() => handleModalClose('cancel')}
|
||||
handleSubmit={() => handleSubmit('cancel')}
|
||||
/>
|
||||
{/* 경고 모달 */}
|
||||
<DynamicModal
|
||||
modalType={modalTypes.completed}
|
||||
view={alertMsg ? 'view' : 'hidden'}
|
||||
modalText={alertMsg}
|
||||
handleSubmit={() => handleSubmit('warning')}
|
||||
/>
|
||||
{loading && <Loading/>}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const initData = {
|
||||
title: '',
|
||||
is_link: false,
|
||||
start_dt: '',
|
||||
end_dt: '',
|
||||
image_list: [
|
||||
{ language: 'KO', content: '' },
|
||||
{ language: 'EN', content: '' },
|
||||
{ language: 'JA', content: '' },
|
||||
],
|
||||
link_list: [
|
||||
{ language: 'KO', content: '' },
|
||||
{ language: 'EN', content: '' },
|
||||
{ language: 'JA', content: '' },
|
||||
],
|
||||
}
|
||||
|
||||
export default MenuBannerRegist;
|
||||
|
||||
|
||||
|
||||
const LanguageWrapper = styled.div`
|
||||
width: ${props => props.width || '100%'};
|
||||
//margin-bottom: 20px;
|
||||
padding-bottom: 20px;
|
||||
padding-left: 90px;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
margin-bottom: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
const LanguageLabel = styled.h4`
|
||||
color: #444;
|
||||
margin: 0 0 10px 20px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
`;
|
||||
341
src/pages/ServiceManage/MenuBanner_bak.js
Normal file
341
src/pages/ServiceManage/MenuBanner_bak.js
Normal file
@@ -0,0 +1,341 @@
|
||||
import { useState, Fragment, useRef } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import 'react-datepicker/dist/react-datepicker.css';
|
||||
|
||||
import { authList } from '../../store/authList';
|
||||
import {
|
||||
authType,
|
||||
modalTypes,
|
||||
landAuctionStatusType, opYNType,
|
||||
} from '../../assets/data';
|
||||
import { Title, FormWrapper, TableStyle, TableWrapper} from '../../styles/Components';
|
||||
import {
|
||||
CheckBox,
|
||||
Button,
|
||||
DynamicModal,
|
||||
Pagination,
|
||||
ViewTableInfo, CaliTable, TableHeader,
|
||||
} from '../../components/common';
|
||||
import { convertKTC, timeDiffMinute } from '../../utils';
|
||||
import { INITIAL_PAGE_SIZE, INITIAL_PAGE_LIMIT } from '../../assets/data/adminConstants';
|
||||
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 { MenuBannerDelete, MenuBannerDetailView } from '../../apis';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import MenuBannerModal from '../../components/ServiceManage/modal/MenuBannerModal';
|
||||
import tableInfo from '../../assets/data/pages/menuBannerTable.json'
|
||||
|
||||
const MenuBanner = () => {
|
||||
const token = sessionStorage.getItem('token');
|
||||
const userInfo = useRecoilValue(authList);
|
||||
const { t } = useTranslation();
|
||||
const tableRef = useRef(null);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [detailData, setDetailData] = useState({});
|
||||
|
||||
const {
|
||||
modalState,
|
||||
handleModalView,
|
||||
handleModalClose
|
||||
} = useModal({
|
||||
detail: 'hidden',
|
||||
deleteConfirm: 'hidden',
|
||||
deleteComplete: 'hidden'
|
||||
});
|
||||
const [alertMsg, setAlertMsg] = useState('');
|
||||
const [modalType, setModalType] = useState('regist');
|
||||
|
||||
const {
|
||||
searchParams,
|
||||
data: dataList,
|
||||
handleSearch,
|
||||
handleReset,
|
||||
handlePageChange,
|
||||
handlePageSizeChange,
|
||||
handleOrderByChange,
|
||||
updateSearchParams
|
||||
} = useMenuBannerSearch(token, INITIAL_PAGE_SIZE);
|
||||
|
||||
const {
|
||||
selectedRows,
|
||||
handleSelectRow,
|
||||
isRowSelected
|
||||
} = useTable(dataList?.event_list || [], {mode: 'single'});
|
||||
|
||||
|
||||
const handleModalSubmit = async (type, param = null) => {
|
||||
switch (type) {
|
||||
case "regist":
|
||||
setModalType('regist');
|
||||
handleModalView('detail');
|
||||
break;
|
||||
case "detail":
|
||||
await MenuBannerDetailView(token, param).then(data => {
|
||||
setDetailData(data.event_detail);
|
||||
setModalType('modify');
|
||||
handleModalView('detail');
|
||||
});
|
||||
break;
|
||||
case "delete":
|
||||
const date_check = selectedRows.every(row => {
|
||||
const timeDiff = timeDiffMinute(convertKTC(row.auction_start_dt), (new Date));
|
||||
return timeDiff < 3;
|
||||
});
|
||||
if(date_check){
|
||||
setAlertMsg(t('LAND_AUCTION_DELETE_DATE_WARNING'));
|
||||
return;
|
||||
}
|
||||
if(selectedRows[0].status === landAuctionStatusType.auction_start || selectedRows[0].status === landAuctionStatusType.stl_end){
|
||||
setAlertMsg(t('LAND_AUCTION_DELETE_STATUS_WARNING'));
|
||||
return;
|
||||
}
|
||||
handleModalView('deleteConfirm');
|
||||
break;
|
||||
case "deleteConfirm":
|
||||
let list = [];
|
||||
let isChecked = false;
|
||||
|
||||
selectedRows.map(data => {
|
||||
// const row = dataList.list.find(row => row.id === Number(data.id));
|
||||
// if(row.status !== commonStatus.wait) isChecked = true;
|
||||
list.push({
|
||||
id: data.id,
|
||||
});
|
||||
});
|
||||
|
||||
if(isChecked) {
|
||||
setAlertMsg(t('LAND_AUCTION_WARNING_DELETE'))
|
||||
handleModalClose('deleteConfirm');
|
||||
return;
|
||||
}
|
||||
|
||||
await MenuBannerDelete(token, list).then(data => {
|
||||
handleModalClose('deleteConfirm');
|
||||
if(data.result === "SUCCESS") {
|
||||
handleModalView('deleteComplete');
|
||||
}else if(data.result === "ERROR_AUCTION_STATUS_IMPOSSIBLE"){
|
||||
setAlertMsg(t('LAND_AUCTION_ERROR_DELETE_STATUS'));
|
||||
}else{
|
||||
setAlertMsg(t('DELETE_FAIL'));
|
||||
}
|
||||
}).catch(reason => {
|
||||
setAlertMsg(t('API_FAIL'));
|
||||
});
|
||||
|
||||
break;
|
||||
case "deleteComplete":
|
||||
handleModalClose('deleteComplete');
|
||||
window.location.reload();
|
||||
break;
|
||||
case "warning":
|
||||
setAlertMsg('')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const handleAction = async (action, item = null) => {
|
||||
switch (action) {
|
||||
case "regist":
|
||||
setModalType('regist');
|
||||
handleModalView('detail');
|
||||
break;
|
||||
case "detail":
|
||||
await MenuBannerDetailView(token, item).then(data => {
|
||||
setDetailData(data.event_detail);
|
||||
setModalType('modify');
|
||||
handleModalView('detail');
|
||||
});
|
||||
break;
|
||||
case "delete":
|
||||
const date_check = selectedRows.every(row => {
|
||||
const timeDiff = timeDiffMinute(convertKTC(row.auction_start_dt), (new Date));
|
||||
return timeDiff < 3;
|
||||
});
|
||||
if(date_check){
|
||||
setAlertMsg(t('LAND_AUCTION_DELETE_DATE_WARNING'));
|
||||
return;
|
||||
}
|
||||
if(selectedRows[0].status === landAuctionStatusType.auction_start || selectedRows[0].status === landAuctionStatusType.stl_end){
|
||||
setAlertMsg(t('LAND_AUCTION_DELETE_STATUS_WARNING'));
|
||||
return;
|
||||
}
|
||||
handleModalView('deleteConfirm');
|
||||
break;
|
||||
case "deleteConfirm":
|
||||
let list = [];
|
||||
let isChecked = false;
|
||||
|
||||
selectedRows.map(data => {
|
||||
// const row = dataList.list.find(row => row.id === Number(data.id));
|
||||
// if(row.status !== commonStatus.wait) isChecked = true;
|
||||
list.push({
|
||||
id: data.id,
|
||||
});
|
||||
});
|
||||
|
||||
if(isChecked) {
|
||||
setAlertMsg(t('LAND_AUCTION_WARNING_DELETE'))
|
||||
handleModalClose('deleteConfirm');
|
||||
return;
|
||||
}
|
||||
|
||||
await MenuBannerDelete(token, list).then(data => {
|
||||
handleModalClose('deleteConfirm');
|
||||
if(data.result === "SUCCESS") {
|
||||
handleModalView('deleteComplete');
|
||||
}else if(data.result === "ERROR_AUCTION_STATUS_IMPOSSIBLE"){
|
||||
setAlertMsg(t('LAND_AUCTION_ERROR_DELETE_STATUS'));
|
||||
}else{
|
||||
setAlertMsg(t('DELETE_FAIL'));
|
||||
}
|
||||
}).catch(reason => {
|
||||
setAlertMsg(t('API_FAIL'));
|
||||
});
|
||||
|
||||
break;
|
||||
case "deleteComplete":
|
||||
handleModalClose('deleteComplete');
|
||||
window.location.reload();
|
||||
break;
|
||||
case "warning":
|
||||
setAlertMsg('')
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Title>메뉴 배너 관리</Title>
|
||||
<FormWrapper>
|
||||
<MenuBannerSearchBar
|
||||
searchParams={searchParams}
|
||||
onSearch={(newParams, executeSearch = true) => {
|
||||
if (executeSearch) {
|
||||
handleSearch(newParams);
|
||||
} else {
|
||||
updateSearchParams(newParams);
|
||||
}
|
||||
}}
|
||||
onReset={handleReset}
|
||||
/>
|
||||
</FormWrapper>
|
||||
{/*<ViewTableInfo total={dataList?.total} total_all={dataList?.total_all} handleOrderBy={handleOrderByChange} handlePageSize={handlePageSizeChange}>*/}
|
||||
{/* {userInfo.auth_list?.some(auth => auth.id === authType.battleEventDelete) && (*/}
|
||||
{/* <Button theme={selectedRows.length === 0 ? 'disable' : 'line'} text="선택 삭제" handleClick={() => handleModalSubmit('delete')} />*/}
|
||||
{/* )}*/}
|
||||
{/* {userInfo.auth_list?.some(auth => auth.id === authType.battleEventUpdate) && (*/}
|
||||
{/* <Button*/}
|
||||
{/* theme="primary"*/}
|
||||
{/* text="이미지 등록"*/}
|
||||
{/* type="button"*/}
|
||||
{/* handleClick={e => {*/}
|
||||
{/* e.preventDefault();*/}
|
||||
{/* navigate('/servicemanage/menubanner/menubannerregist');*/}
|
||||
{/* }}*/}
|
||||
{/* />*/}
|
||||
{/* )}*/}
|
||||
{/*</ViewTableInfo>*/}
|
||||
<TableHeader
|
||||
config={tableInfo.header}
|
||||
total={dataList?.total}
|
||||
total_all={dataList?.total_all}
|
||||
handleOrderBy={handleOrderByChange}
|
||||
handlePageSize={handlePageSizeChange}
|
||||
selectedRows={selectedRows}
|
||||
onAction={handleAction}
|
||||
navigate={navigate}
|
||||
/>
|
||||
|
||||
<CaliTable
|
||||
columns={tableInfo.columns}
|
||||
data={dataList?.list}
|
||||
selectedRows={selectedRows}
|
||||
onSelectRow={handleSelectRow}
|
||||
onAction={handleAction}
|
||||
refProp={tableRef}
|
||||
/>
|
||||
|
||||
{/*<TableWrapper>*/}
|
||||
{/* <TableStyle ref={tableRef}>*/}
|
||||
{/* <caption></caption>*/}
|
||||
{/* <thead>*/}
|
||||
{/* <tr>*/}
|
||||
{/* <th width="40"></th>*/}
|
||||
{/* <th width="70">번호</th>*/}
|
||||
{/* <th width="80">등록 상태</th>*/}
|
||||
{/* <th width="150">시작일(KST)</th>*/}
|
||||
{/* <th width="150">종료일(KST)</th>*/}
|
||||
{/* <th width="300">설명 제목</th>*/}
|
||||
{/* <th width="90">링크여부</th>*/}
|
||||
{/* <th width="100">상세보기</th>*/}
|
||||
{/* <th width="150">히스토리</th>*/}
|
||||
{/* </tr>*/}
|
||||
{/* </thead>*/}
|
||||
{/* <tbody>*/}
|
||||
{/* {dataList?.list?.map(banner => (*/}
|
||||
{/* <tr key={banner.row_num}>*/}
|
||||
{/* <td>*/}
|
||||
{/* <CheckBox name={'select'} id={banner.id}*/}
|
||||
{/* setData={(e) => handleSelectRow(e, banner)}*/}
|
||||
{/* checked={isRowSelected(banner.id)} />*/}
|
||||
{/* </td>*/}
|
||||
{/* <td>{banner.row_num}</td>*/}
|
||||
{/* <StatusWapper>*/}
|
||||
{/* <StatusLabel $status={banner.status}>*/}
|
||||
{/* {opMenuBannerStatus.find(data => data.value === banner.status)?.name}*/}
|
||||
{/* </StatusLabel>*/}
|
||||
{/* </StatusWapper>*/}
|
||||
{/* <td>{convertKTC(banner.start_dt)}</td>*/}
|
||||
{/* <td>{convertKTC(banner.end_dt)}</td>*/}
|
||||
{/* <td>{banner.title}</td>*/}
|
||||
{/* <td>{opYNType.find(data => data.value === banner.is_link)?.name}</td>*/}
|
||||
{/* <td>*/}
|
||||
{/* <Button theme="line" text="상세보기"*/}
|
||||
{/* handleClick={e => handleModalSubmit('detail', banner.id)} />*/}
|
||||
{/* </td>*/}
|
||||
{/* <td>{banner.update_by}</td>*/}
|
||||
{/* </tr>*/}
|
||||
{/* ))}*/}
|
||||
{/* </tbody>*/}
|
||||
{/* </TableStyle>*/}
|
||||
{/*</TableWrapper>*/}
|
||||
|
||||
<Pagination postsPerPage={searchParams.pageSize} totalPosts={dataList?.total_all} setCurrentPage={handlePageChange} currentPage={searchParams.currentPage} pageLimit={INITIAL_PAGE_LIMIT} />
|
||||
|
||||
{/*상세*/}
|
||||
<MenuBannerModal modalType={modalType} detailView={modalState.detailModal} handleDetailView={() => handleModalClose('detail')} content={detailData} setDetailData={setDetailData} />
|
||||
|
||||
{/*삭제 확인*/}
|
||||
<DynamicModal
|
||||
modalType={modalTypes.confirmOkCancel}
|
||||
view={modalState.deleteConfirmModal}
|
||||
handleCancel={() => handleModalClose('deleteConfirm')}
|
||||
handleSubmit={() => handleModalSubmit('deleteConfirm')}
|
||||
modalText={t('MENU_BANNER_SELECT_DELETE')}
|
||||
/>
|
||||
{/*삭제 완료*/}
|
||||
<DynamicModal
|
||||
modalType={modalTypes.completed}
|
||||
view={modalState.deleteCompleteModal}
|
||||
handleSubmit={() => handleModalSubmit('deleteComplete')}
|
||||
modalText={t('DEL_COMPLETE')}
|
||||
/>
|
||||
{/* 경고 모달 */}
|
||||
<DynamicModal
|
||||
modalType={modalTypes.completed}
|
||||
view={alertMsg ? 'view' : 'hidden'}
|
||||
modalText={alertMsg}
|
||||
handleSubmit={() => handleModalSubmit('warning')}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
};
|
||||
|
||||
export default withAuth(authType.battleEventRead)(MenuBanner);
|
||||
@@ -1,12 +1,11 @@
|
||||
import { useState, Fragment, useRef, useTransition } from 'react';
|
||||
import React, { useState, Fragment } from 'react';
|
||||
import { Title, FormWrapper, TextInput } from '../../styles/Components';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import {
|
||||
CommonSearchBar,
|
||||
useCommonSearch,
|
||||
UserBlockDetailModal,
|
||||
} from '../../components/ServiceManage/';
|
||||
import { BlackListDetail, BlackListDelete } from '../../apis';
|
||||
import { BlackListDetail, BlackListDelete, LogHistory } from '../../apis';
|
||||
import Pagination from '../../components/common/Pagination/Pagination';
|
||||
|
||||
import { authType, commonStatus, modalTypes } from '../../assets/data';
|
||||
@@ -21,6 +20,8 @@ import useCommonSearchOld from '../../hooks/useCommonSearchOld';
|
||||
import { ModalInputItem, ModalSubText, RegistInputItem } from '../../styles/ModuleComponents';
|
||||
import DynamicModal from '../../components/common/modal/DynamicModal';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import LogDetailModal from '../../components/common/modal/LogDetailModal';
|
||||
import { historyTables } from '../../assets/data/data';
|
||||
|
||||
const UserBlock = () => {
|
||||
const token = sessionStorage.getItem('token');
|
||||
@@ -31,13 +32,15 @@ const UserBlock = () => {
|
||||
|
||||
const [detail, setDetail] = useState([]);
|
||||
const [deleteDesc, setDeleteDesc] = useState('');
|
||||
const [historyData, setHistoryData] = useState({});
|
||||
const {
|
||||
modalState,
|
||||
handleModalView,
|
||||
handleModalClose
|
||||
} = useModal({
|
||||
detail: 'hidden',
|
||||
delete: 'hidden'
|
||||
delete: 'hidden',
|
||||
history: 'hidden'
|
||||
});
|
||||
|
||||
const {
|
||||
@@ -62,6 +65,17 @@ const UserBlock = () => {
|
||||
|
||||
const handleAction = async (action, item = null) => {
|
||||
switch (action) {
|
||||
case "history":
|
||||
const params = {};
|
||||
params.db_type = "MYSQL"
|
||||
params.sql_id = item.id;
|
||||
params.table_name = historyTables.userBlock
|
||||
|
||||
await LogHistory(token, params).then(data => {
|
||||
setHistoryData(data);
|
||||
handleModalView('history');
|
||||
});
|
||||
break;
|
||||
case "detail":
|
||||
await BlackListDetail(token, item.id).then(data => {
|
||||
setDetail(data);
|
||||
@@ -165,6 +179,14 @@ const UserBlock = () => {
|
||||
handleModal={() => handleModalClose('detail')}
|
||||
/>
|
||||
|
||||
<LogDetailModal
|
||||
viewMode="changed"
|
||||
detailView={modalState.historyModal}
|
||||
handleDetailView={() => handleModalClose('history')}
|
||||
changedData={historyData}
|
||||
title="히스토리"
|
||||
/>
|
||||
|
||||
<DynamicModal
|
||||
modalType={modalTypes.childOkCancel}
|
||||
view={modalState.deleteModal}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState, Fragment, useRef } from 'react';
|
||||
import React, { useState, Fragment, useRef } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import 'react-datepicker/dist/react-datepicker.css';
|
||||
@@ -14,19 +14,27 @@ import { Title, FormWrapper, TableStyle, TableWrapper, PopupMessage } from '../.
|
||||
import {
|
||||
StatusWapper,
|
||||
ChargeBtn,
|
||||
StatusLabel,
|
||||
StatusLabel, TitleItemLabel, TitleItemValue, TitleItem,
|
||||
} from '../../styles/ModuleComponents';
|
||||
import {Button, ExcelDownButton, Pagination, ViewTableInfo} from '../../components/common';
|
||||
import { convertKTC, truncateText } from '../../utils';
|
||||
import { CaliumRequestRegistModal } from '../../components/UserManage';
|
||||
import { CaliumCharge } from '../../apis';
|
||||
import { CaliumCharge, LogHistory } from '../../apis';
|
||||
import { useModal, withAuth } from '../../hooks/hook';
|
||||
import { CommonSearchBar, useCommonSearch } from '../../components/ServiceManage';
|
||||
import { INITIAL_PAGE_LIMIT } from '../../assets/data/adminConstants';
|
||||
import {
|
||||
INITIAL_PAGE_LIMIT,
|
||||
LOG_ACTION_FAIL_CALIUM_ECHO,
|
||||
STORAGE_BUSINESS_LOG_SEARCH,
|
||||
} from '../../assets/data/adminConstants';
|
||||
import { useAlert } from '../../context/AlertProvider';
|
||||
import { useLoading } from '../../context/LoadingProvider';
|
||||
import { alertTypes } from '../../assets/data/types';
|
||||
import useCommonSearchOld from '../../hooks/useCommonSearchOld';
|
||||
import LogDetailModal from '../../components/common/modal/LogDetailModal';
|
||||
import { historyTables } from '../../assets/data/data';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { logAction } from '../../assets/data/options';
|
||||
|
||||
const CaliumRequest = () => {
|
||||
const token = sessionStorage.getItem('token');
|
||||
@@ -34,9 +42,11 @@ const CaliumRequest = () => {
|
||||
const { t } = useTranslation();
|
||||
const { showModal, showToast } = useAlert();
|
||||
const {withLoading} = useLoading();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const tableRef = useRef(null);
|
||||
const [selectCharge, setSelectCharge] = useState({});
|
||||
const [historyData, setHistoryData] = useState({});
|
||||
|
||||
const {
|
||||
modalState,
|
||||
@@ -44,6 +54,7 @@ const CaliumRequest = () => {
|
||||
handleModalClose
|
||||
} = useModal({
|
||||
register: 'hidden',
|
||||
history: 'hidden'
|
||||
});
|
||||
|
||||
const {
|
||||
@@ -61,6 +72,17 @@ const CaliumRequest = () => {
|
||||
|
||||
const handleSubmit = async (type, param = null) => {
|
||||
switch (type) {
|
||||
case "history":
|
||||
const params = {};
|
||||
params.db_type = "MYSQL"
|
||||
params.sql_id = param.id;
|
||||
params.table_name = historyTables.caliumRequest
|
||||
|
||||
await LogHistory(token, params).then(data => {
|
||||
setHistoryData(data);
|
||||
handleModalView('history');
|
||||
});
|
||||
break;
|
||||
case "detail":
|
||||
showModal(param, {
|
||||
type: alertTypes.info
|
||||
@@ -91,6 +113,25 @@ const CaliumRequest = () => {
|
||||
handleSearch(updateSearchParams);
|
||||
});
|
||||
break;
|
||||
case "logMove":
|
||||
const searchParams = {
|
||||
action: LOG_ACTION_FAIL_CALIUM_ECHO,
|
||||
start_dt: (() => {
|
||||
const date = new Date();
|
||||
date.setDate(date.getDate() - 1);
|
||||
return date;
|
||||
})(),
|
||||
end_dt: (() => {
|
||||
const date = new Date();
|
||||
date.setDate(date.getDate() - 1);
|
||||
return date;
|
||||
})(),
|
||||
};
|
||||
|
||||
// 복사한 데이터를 세션 스토리지에 저장
|
||||
sessionStorage.setItem(STORAGE_BUSINESS_LOG_SEARCH, JSON.stringify(searchParams));
|
||||
navigate('/datamanage/businesslogview');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +152,15 @@ const CaliumRequest = () => {
|
||||
onReset={handleReset}
|
||||
/>
|
||||
</FormWrapper>
|
||||
<ViewTableInfo total={dataList?.total} total_all={dataList?.total_all} handleOrderBy={handleOrderByChange} handlePageSize={handlePageSizeChange} countType={ViewTitleCountType.calium}>
|
||||
<ViewTableInfo
|
||||
total={dataList?.total}
|
||||
total_all={dataList?.total_all}
|
||||
fail_count={dataList?.failCount}
|
||||
handleOrderBy={handleOrderByChange}
|
||||
handlePageSize={handlePageSizeChange}
|
||||
countType={ViewTitleCountType.calium}
|
||||
onFailCountClick={() => handleSubmit('logMove')}
|
||||
>
|
||||
<ExcelDownButton tableRef={tableRef} fileName={t('FILE_CALIUM_REQUEST')} />
|
||||
{userInfo.auth_list && userInfo.auth_list.some(auth => auth.id === authType.eventUpdate) && (
|
||||
<Button
|
||||
@@ -138,6 +187,7 @@ const CaliumRequest = () => {
|
||||
<th width="80">요청수량</th>
|
||||
<th width="160">진행상태</th>
|
||||
<th width="210">최종 처리일시</th>
|
||||
<th width="200">히스토리</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -155,15 +205,22 @@ const CaliumRequest = () => {
|
||||
</td>
|
||||
<td>{calium.count}</td>
|
||||
<StatusWapper>
|
||||
<StatusLabel $status={calium.status}>{caliumStatus.map(data => data.value === calium.status && data.name)}</StatusLabel>
|
||||
<StatusLabel
|
||||
$status={calium.status}>{caliumStatus.map(data => data.value === calium.status && data.name)}</StatusLabel>
|
||||
{calium.status === commonStatus.complete && userInfo.auth_list?.some(auth => auth.id === authType.eventUpdate) && calium.create_by === userInfo.name &&
|
||||
<ChargeBtn onClick={() => handleSubmit('chargedConfirm', {id: calium.id, count: calium.count})}>충전</ChargeBtn>
|
||||
<ChargeBtn onClick={() => handleSubmit('chargedConfirm', {
|
||||
id: calium.id,
|
||||
count: calium.count,
|
||||
})}>충전</ChargeBtn>
|
||||
}
|
||||
</StatusWapper>
|
||||
<td>{convertKTC(calium.state_time)}</td>
|
||||
<td><Button theme="line" text="히스토리"
|
||||
handleClick={e => handleSubmit('history', calium)} />
|
||||
</td>
|
||||
</tr>
|
||||
</Fragment>
|
||||
))}
|
||||
))}
|
||||
</tbody>
|
||||
</TableStyle>
|
||||
</TableWrapper>
|
||||
@@ -185,6 +242,14 @@ const CaliumRequest = () => {
|
||||
userInfo={userInfo}
|
||||
/>
|
||||
|
||||
<LogDetailModal
|
||||
viewMode="changed"
|
||||
detailView={modalState.historyModal}
|
||||
handleDetailView={() => handleModalClose('history')}
|
||||
changedData={historyData}
|
||||
title="히스토리"
|
||||
/>
|
||||
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -28,12 +28,16 @@ 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 { useAlert } from '../../context/AlertProvider';
|
||||
import { useLoading } from '../../context/LoadingProvider';
|
||||
import { alertTypes } from '../../assets/data/types';
|
||||
|
||||
const DataInitView = () => {
|
||||
const { t } = useTranslation();
|
||||
const token = sessionStorage.getItem('token');
|
||||
const {showModal, showToast} = useAlert();
|
||||
const {withLoading} = useLoading();
|
||||
|
||||
const [loading, setLoading] = useState(false); // 로딩 창
|
||||
const {
|
||||
modalState,
|
||||
handleModalView,
|
||||
@@ -44,8 +48,6 @@ const DataInitView = () => {
|
||||
registComplete: 'hidden'
|
||||
});
|
||||
|
||||
const [alertMsg, setAlertMsg] = useState('');
|
||||
|
||||
const [resultData, setResultData] = useState(initData); //데이터 정보
|
||||
const [expandedRows, setExpandedRows] = useState({});
|
||||
|
||||
@@ -56,7 +58,7 @@ const DataInitView = () => {
|
||||
handleSearch,
|
||||
handleReset,
|
||||
updateSearchParams
|
||||
} = useDataInitSearch(token, setAlertMsg);
|
||||
} = useDataInitSearch(token);
|
||||
|
||||
const toggleRowExpand = (index) => {
|
||||
setExpandedRows(prev => ({
|
||||
@@ -111,29 +113,23 @@ const DataInitView = () => {
|
||||
handleModalView('registConfirm');
|
||||
break;
|
||||
case "registConfirm":
|
||||
setLoading(true);
|
||||
|
||||
await InitData(token, resultData).then(data => {
|
||||
await withLoading(async () => {
|
||||
return await InitData(token, resultData);
|
||||
}).then(data => {
|
||||
handleModalClose('registConfirm');
|
||||
if(data.result === "SUCCESS") {
|
||||
handleModalView('registComplete');
|
||||
showToast('INIT_COMPLTE', {type: alertTypes.success});
|
||||
}else{
|
||||
setAlertMsg(t('REGIST_FAIL'));
|
||||
showToast('REGIST_FAIL', {type: alertTypes.error});
|
||||
}
|
||||
}).catch(reason => {
|
||||
handleModalClose('registConfirm');
|
||||
setAlertMsg(t('API_FAIL'));
|
||||
showToast('API_FAIL', {type: alertTypes.error});
|
||||
}).finally(() => {
|
||||
setLoading(false);
|
||||
dataReset();
|
||||
});
|
||||
|
||||
break;
|
||||
case "registComplete":
|
||||
dataReset();
|
||||
handleModalClose('registComplete');
|
||||
break;
|
||||
case "warning":
|
||||
setAlertMsg('');
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -192,11 +188,11 @@ const DataInitView = () => {
|
||||
<Fragment key={index}>
|
||||
<tr>
|
||||
<td>{item.timestamp}</td>
|
||||
<td>{item.key}</td>
|
||||
<td>{opInitDataType.find(type => type.value === item.initDataType)?.name}</td>
|
||||
<td>{item.body.key}</td>
|
||||
<td>{opInitDataType.find(type => type.value === item.body.initDataType)?.name}</td>
|
||||
<td>{item.tranId}</td>
|
||||
<td>{opSuccessType.find(type => type.value === item.success)?.name}</td>
|
||||
<td>{item.message}</td>
|
||||
<td>{opSuccessType.find(type => type.value === item.body.success)?.name}</td>
|
||||
<td>{item.body.message}</td>
|
||||
<td>
|
||||
<TableActionButton onClick={() => toggleRowExpand(index)}>
|
||||
{expandedRows[index] ? '접기' : '상세보기'}
|
||||
@@ -209,7 +205,7 @@ const DataInitView = () => {
|
||||
<TableDetailContainer>
|
||||
<TableDetailFlex>
|
||||
<TableDetailColumn>
|
||||
{renderDetailData(item.data)}
|
||||
{renderDetailData(item.body.data)}
|
||||
</TableDetailColumn>
|
||||
</TableDetailFlex>
|
||||
</TableDetailContainer>
|
||||
@@ -230,21 +226,6 @@ const DataInitView = () => {
|
||||
handleSubmit={() => handleSubmit('registConfirm')}
|
||||
handleCancel={() => handleModalClose('registConfirm')}
|
||||
/>
|
||||
{/* 완료 모달 */}
|
||||
<DynamicModal
|
||||
modalType={modalTypes.completed}
|
||||
view={modalState.registCompleteModal}
|
||||
modalText={t('INIT_COMPLTE')}
|
||||
handleSubmit={() => handleSubmit('registComplete')}
|
||||
/>
|
||||
{/* 경고 모달 */}
|
||||
<DynamicModal
|
||||
modalType={modalTypes.completed}
|
||||
view={alertMsg ? 'view' : 'hidden'}
|
||||
modalText={alertMsg}
|
||||
handleSubmit={() => setAlertMsg('')}
|
||||
/>
|
||||
{(loading || dataLoading) && <Loading/>}
|
||||
<TopButton />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,170 +1,106 @@
|
||||
import { Fragment, useState, useEffect } from 'react';
|
||||
import React, { Fragment, useCallback, useState } from 'react';
|
||||
|
||||
import {LogViewSearchBar} from '../../components/ServiceManage';
|
||||
import { Title, FormWrapper, SelectInput, TableInfo, ListCount, ListOption, TableStyle, BtnWrapper, ButtonClose, ModalText } from '../../styles/Components';
|
||||
import Button from '../../components/common/button/Button';
|
||||
import Pagination from '../../components/common/Pagination/Pagination';
|
||||
import Modal from '../../components/common/modal/Modal';
|
||||
|
||||
import LogViewModal from '../../components/UserManage/LogViewModal';
|
||||
|
||||
import { LogViewList } from '../../apis';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { authList } from '../../store/authList';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { logOption } from '../../assets/data';
|
||||
import { convertKTC } from '../../utils';
|
||||
import { CommonSearchBar } from '../../components/ServiceManage';
|
||||
import { Title, FormWrapper } from '../../styles/Components';
|
||||
import { authType } from '../../assets/data';
|
||||
import { useModal, withAuth } from '../../hooks/hook';
|
||||
import { CaliTable } from '../../components/common';
|
||||
import tableInfo from '../../assets/data/pages/historyTable.json';
|
||||
import useEnhancedCommonSearch from '../../hooks/useEnhancedCommonSearch';
|
||||
import FrontPagination from '../../components/common/Pagination/FrontPagination';
|
||||
import { INITIAL_CURRENT_PAGE, INITIAL_PAGE_LIMIT, INITIAL_PAGE_SIZE } from '../../assets/data/adminConstants';
|
||||
import LogDetailModal from '../../components/common/modal/LogDetailModal';
|
||||
|
||||
const LogView = () => {
|
||||
const navigate = useNavigate();
|
||||
const userInfo = useRecoilValue(authList);
|
||||
const [detailData, setDetailData] = useState({});
|
||||
const [currentPage, setCurrentPage] = useState(INITIAL_CURRENT_PAGE);
|
||||
const [displayData, setDisplayData] = useState([]);
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const {
|
||||
modalState,
|
||||
handleModalView,
|
||||
handleModalClose
|
||||
} = useModal({
|
||||
detail: 'hidden',
|
||||
});
|
||||
|
||||
const [stateModal, setStateModal] = useState('hidden');
|
||||
const [dataList, setDataList] = useState([]);
|
||||
const [detailData, setDetailData] = useState('');
|
||||
const [searchData, setSearchData] = useState({});
|
||||
const [orderBy, setOrderBy] = useState('DESC');
|
||||
const [pageSize, setPageSize] = useState('50');
|
||||
const {
|
||||
config,
|
||||
searchParams,
|
||||
data: dataList,
|
||||
handleSearch,
|
||||
handleReset,
|
||||
updateSearchParams,
|
||||
loading
|
||||
} = useEnhancedCommonSearch("historySearch");
|
||||
|
||||
const handleButtonClick = content => {
|
||||
setStateModal('view');
|
||||
setDetailData(content);
|
||||
};
|
||||
const handleClientPageChange = useCallback((slicedData) => {
|
||||
setDisplayData(slicedData);
|
||||
}, []);
|
||||
|
||||
const handleModal = () => {
|
||||
if (stateModal === 'hidden') {
|
||||
setStateModal('view');
|
||||
} else {
|
||||
setStateModal('hidden');
|
||||
const handleAction = async (action, item = null) => {
|
||||
switch (action) {
|
||||
case "detail":
|
||||
handleModalView('detail');
|
||||
setDetailData(item.data);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const handleOrderBy = e => {
|
||||
const order = e.target.value;
|
||||
setOrderBy(order);
|
||||
fetchData(
|
||||
searchData.searchOption,
|
||||
searchData.data,
|
||||
searchData.logOption,
|
||||
searchData.startDate && new Date(searchData.startDate).toISOString(),
|
||||
searchData.endDate && new Date(searchData.endDate).toISOString(),
|
||||
order,
|
||||
pageSize,
|
||||
);
|
||||
};
|
||||
|
||||
const handlePageSize = e => {
|
||||
const size = e.target.value;
|
||||
setPageSize(size);
|
||||
setCurrentPage(1);
|
||||
fetchData(
|
||||
searchData.searchOption,
|
||||
searchData.data,
|
||||
searchData.logOption,
|
||||
searchData.startDate && new Date(searchData.startDate).toISOString(),
|
||||
searchData.endDate && new Date(searchData.endDate).toISOString(),
|
||||
orderBy,
|
||||
size,
|
||||
1,
|
||||
);
|
||||
};
|
||||
|
||||
const fetchData = async (searchType, searchKey, historyType, startDt, endDt, order, size) => {
|
||||
const token = sessionStorage.getItem('token');
|
||||
setDataList(await LogViewList(token, searchType, searchKey, historyType, startDt, endDt, order ? order : orderBy, size ? size : pageSize, currentPage));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchData(
|
||||
searchData.searchOption,
|
||||
searchData.data,
|
||||
searchData.logOption,
|
||||
searchData.startDate && new Date(searchData.startDate).toISOString(),
|
||||
searchData.endDate && new Date(searchData.endDate).toISOString(),
|
||||
orderBy,
|
||||
pageSize,
|
||||
);
|
||||
}, [currentPage]);
|
||||
|
||||
const handleSearch = (searchType, searchKey, historyType, startDt, endDt) => {
|
||||
fetchData(searchType, searchKey, historyType, startDt, endDt);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{userInfo.auth_list && !userInfo.auth_list.some(auth => auth.id === 5) ? (
|
||||
<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>
|
||||
<FormWrapper action="" $flow="row">
|
||||
<LogViewSearchBar handleSearch={handleSearch} resultData={setSearchData} />
|
||||
</FormWrapper>
|
||||
<TableInfo>
|
||||
<ListCount>
|
||||
총 : {dataList && dataList.total} 건 / {dataList && dataList.total_all} 건
|
||||
</ListCount>
|
||||
<ListOption>
|
||||
<SelectInput className="input-select" onChange={e => handleOrderBy(e)}>
|
||||
<option value="DESC">최신일자</option>
|
||||
<option value="ASC">오래된순</option>
|
||||
</SelectInput>
|
||||
<SelectInput className="input-select" onChange={e => handlePageSize(e)}>
|
||||
<option value="50">50개</option>
|
||||
<option value="100">100개</option>
|
||||
</SelectInput>
|
||||
</ListOption>
|
||||
</TableInfo>
|
||||
<TableStyle>
|
||||
<caption></caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="200">일시</th>
|
||||
<th width="200">이름</th>
|
||||
<th width="50%">ID</th>
|
||||
<th width="30%">사용 이력</th>
|
||||
{/* <th width="25%">상세 이력</th> */}
|
||||
<th width="150">상세 보기</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{dataList.list &&
|
||||
dataList.list.map((history, index) => (
|
||||
<Fragment key={index}>
|
||||
<tr>
|
||||
<td>{convertKTC(history.create_dt)}</td>
|
||||
<td>{history.name}</td>
|
||||
<td>{history.mail}</td>
|
||||
<td>{logOption.map(data => data.value === history.history_type && data.name)}</td>
|
||||
<td>
|
||||
<Button theme="line" text="JSON INFO" handleClick={() => handleButtonClick(history.content)} />
|
||||
</td>
|
||||
</tr>
|
||||
</Fragment>
|
||||
))}
|
||||
</tbody>
|
||||
</TableStyle>
|
||||
<Pagination postsPerPage={pageSize} totalPosts={dataList && dataList.total_all} setCurrentPage={setCurrentPage} currentPage={currentPage} pageLimit={10} />
|
||||
<Title>사용 이력 조회</Title>
|
||||
|
||||
{/* 조회조건 */}
|
||||
<FormWrapper>
|
||||
<CommonSearchBar
|
||||
config={config}
|
||||
searchParams={searchParams}
|
||||
onSearch={(newParams, executeSearch = true) => {
|
||||
if (executeSearch) {
|
||||
handleSearch(newParams);
|
||||
} else {
|
||||
updateSearchParams(newParams);
|
||||
}
|
||||
}}
|
||||
onReset={handleReset}
|
||||
/>
|
||||
</FormWrapper>
|
||||
|
||||
{/* 조회테이블 */}
|
||||
<CaliTable
|
||||
columns={tableInfo.columns}
|
||||
data={displayData}
|
||||
onAction={(action, item) => handleAction(action, item)}
|
||||
// refProp={tableRef}
|
||||
loading={loading}
|
||||
/>
|
||||
|
||||
{/* 페이징 */}
|
||||
{dataList?.list &&
|
||||
<FrontPagination
|
||||
data={dataList.list}
|
||||
itemsPerPage={INITIAL_PAGE_SIZE}
|
||||
currentPage={currentPage}
|
||||
setCurrentPage={setCurrentPage}
|
||||
pageLimit={INITIAL_PAGE_LIMIT}
|
||||
onPageChange={handleClientPageChange}
|
||||
/>}
|
||||
|
||||
{/* 상세 */}
|
||||
<LogDetailModal
|
||||
viewMode="data"
|
||||
detailView={modalState.detailModal}
|
||||
handleDetailView={() => handleModalClose('detail')}
|
||||
detailData={detailData}
|
||||
title="상세정보"
|
||||
/>
|
||||
|
||||
<LogViewModal stateModal={stateModal} handleModal={handleModal} data={detailData} />
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default LogView;
|
||||
export default withAuth(authType.adminLogSearchRead)(LogView);
|
||||
|
||||
170
src/pages/UserManage/LogView_bak.js
Normal file
170
src/pages/UserManage/LogView_bak.js
Normal file
@@ -0,0 +1,170 @@
|
||||
import { Fragment, useState, useEffect } from 'react';
|
||||
|
||||
import {LogViewSearchBar} from '../../components/ServiceManage';
|
||||
import { Title, FormWrapper, SelectInput, TableInfo, ListCount, ListOption, TableStyle, BtnWrapper, ButtonClose, ModalText } from '../../styles/Components';
|
||||
import Button from '../../components/common/button/Button';
|
||||
import Pagination from '../../components/common/Pagination/Pagination';
|
||||
import Modal from '../../components/common/modal/Modal';
|
||||
|
||||
import LogViewModal from '../../components/UserManage/LogViewModal';
|
||||
|
||||
import { LogViewList } from '../../apis';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { authList } from '../../store/authList';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { logOption } from '../../assets/data';
|
||||
import { convertKTC } from '../../utils';
|
||||
|
||||
const LogView = () => {
|
||||
const navigate = useNavigate();
|
||||
const userInfo = useRecoilValue(authList);
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
|
||||
const [stateModal, setStateModal] = useState('hidden');
|
||||
const [dataList, setDataList] = useState([]);
|
||||
const [detailData, setDetailData] = useState('');
|
||||
const [searchData, setSearchData] = useState({});
|
||||
const [orderBy, setOrderBy] = useState('DESC');
|
||||
const [pageSize, setPageSize] = useState('50');
|
||||
|
||||
const handleButtonClick = content => {
|
||||
setStateModal('view');
|
||||
setDetailData(content);
|
||||
};
|
||||
|
||||
const handleModal = () => {
|
||||
if (stateModal === 'hidden') {
|
||||
setStateModal('view');
|
||||
} else {
|
||||
setStateModal('hidden');
|
||||
}
|
||||
};
|
||||
|
||||
const handleOrderBy = e => {
|
||||
const order = e.target.value;
|
||||
setOrderBy(order);
|
||||
fetchData(
|
||||
searchData.searchOption,
|
||||
searchData.data,
|
||||
searchData.logOption,
|
||||
searchData.startDate && new Date(searchData.startDate).toISOString(),
|
||||
searchData.endDate && new Date(searchData.endDate).toISOString(),
|
||||
order,
|
||||
pageSize,
|
||||
);
|
||||
};
|
||||
|
||||
const handlePageSize = e => {
|
||||
const size = e.target.value;
|
||||
setPageSize(size);
|
||||
setCurrentPage(1);
|
||||
fetchData(
|
||||
searchData.searchOption,
|
||||
searchData.data,
|
||||
searchData.logOption,
|
||||
searchData.startDate && new Date(searchData.startDate).toISOString(),
|
||||
searchData.endDate && new Date(searchData.endDate).toISOString(),
|
||||
orderBy,
|
||||
size,
|
||||
1,
|
||||
);
|
||||
};
|
||||
|
||||
const fetchData = async (searchType, searchKey, historyType, startDt, endDt, order, size) => {
|
||||
const token = sessionStorage.getItem('token');
|
||||
setDataList(await LogViewList(token, searchType, searchKey, historyType, startDt, endDt, order ? order : orderBy, size ? size : pageSize, currentPage));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchData(
|
||||
searchData.searchOption,
|
||||
searchData.data,
|
||||
searchData.logOption,
|
||||
searchData.startDate && new Date(searchData.startDate).toISOString(),
|
||||
searchData.endDate && new Date(searchData.endDate).toISOString(),
|
||||
orderBy,
|
||||
pageSize,
|
||||
);
|
||||
}, [currentPage]);
|
||||
|
||||
const handleSearch = (searchType, searchKey, historyType, startDt, endDt) => {
|
||||
fetchData(searchType, searchKey, historyType, startDt, endDt);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{userInfo.auth_list && !userInfo.auth_list.some(auth => auth.id === 5) ? (
|
||||
<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>
|
||||
<FormWrapper action="" $flow="row">
|
||||
<LogViewSearchBar handleSearch={handleSearch} resultData={setSearchData} />
|
||||
</FormWrapper>
|
||||
<TableInfo>
|
||||
<ListCount>
|
||||
총 : {dataList && dataList.total} 건 / {dataList && dataList.total_all} 건
|
||||
</ListCount>
|
||||
<ListOption>
|
||||
<SelectInput className="input-select" onChange={e => handleOrderBy(e)}>
|
||||
<option value="DESC">최신일자</option>
|
||||
<option value="ASC">오래된순</option>
|
||||
</SelectInput>
|
||||
<SelectInput className="input-select" onChange={e => handlePageSize(e)}>
|
||||
<option value="50">50개</option>
|
||||
<option value="100">100개</option>
|
||||
</SelectInput>
|
||||
</ListOption>
|
||||
</TableInfo>
|
||||
<TableStyle>
|
||||
<caption></caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="200">일시</th>
|
||||
<th width="200">이름</th>
|
||||
<th width="50%">ID</th>
|
||||
<th width="30%">사용 이력</th>
|
||||
{/* <th width="25%">상세 이력</th> */}
|
||||
<th width="150">상세 보기</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{dataList.list &&
|
||||
dataList.list.map((history, index) => (
|
||||
<Fragment key={index}>
|
||||
<tr>
|
||||
<td>{convertKTC(history.create_dt)}</td>
|
||||
<td>{history.name}</td>
|
||||
<td>{history.mail}</td>
|
||||
<td>{logOption.map(data => data.value === history.history_type && data.name)}</td>
|
||||
<td>
|
||||
<Button theme="line" text="JSON INFO" handleClick={() => handleButtonClick(history.content)} />
|
||||
</td>
|
||||
</tr>
|
||||
</Fragment>
|
||||
))}
|
||||
</tbody>
|
||||
</TableStyle>
|
||||
<Pagination postsPerPage={pageSize} totalPosts={dataList && dataList.total_all} setCurrentPage={setCurrentPage} currentPage={currentPage} pageLimit={10} />
|
||||
|
||||
<LogViewModal stateModal={stateModal} handleModal={handleModal} data={detailData} />
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default LogView;
|
||||
@@ -344,6 +344,20 @@ export const TableWrapper = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
export const PopupTableWrapper = styled.div`
|
||||
min-width: 680px;
|
||||
overflow: auto;
|
||||
&::-webkit-scrollbar {
|
||||
height: 10px;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: #666666;
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
background: #d9d9d9;
|
||||
}
|
||||
`;
|
||||
|
||||
export const State = styled.span`
|
||||
color: ${props => props.color || '#2c2c2c'};
|
||||
`;
|
||||
|
||||
@@ -735,6 +735,17 @@ export const TitleItemValue = styled.div`
|
||||
color: ${props => props.color || 'black'};
|
||||
`;
|
||||
|
||||
export const TitleItemLink = styled.a`
|
||||
font-weight: ${props => props.fontWeight || 500};
|
||||
color: ${props => props.color || 'black'};
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
`;
|
||||
|
||||
export const ChargeBtn = styled.button`
|
||||
&&{
|
||||
width: 60px;
|
||||
@@ -831,4 +842,22 @@ export const CopyBtn = styled.div`
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
`;
|
||||
|
||||
export const Tab = styled.div`
|
||||
padding: 10px 20px;
|
||||
cursor: pointer;
|
||||
border-bottom: 2px solid ${props => props.$active ? '#4a6cf7' : 'transparent'};
|
||||
color: ${props => props.$active ? '#4a6cf7' : '#666'};
|
||||
font-weight: ${props => props.$active ? 'bold' : 'normal'};
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
`;
|
||||
|
||||
export const TabContent = styled.div`
|
||||
display: ${props => props.$active ? 'block' : 'none'};
|
||||
padding: 10px 0;
|
||||
`;
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as optionsConfig from '../assets/data/options';
|
||||
import { logFieldLabels } from '../assets/data/data';
|
||||
|
||||
export const convertKTC = (dt, nation = true) => {
|
||||
if (!dt) return "";
|
||||
@@ -73,4 +74,16 @@ export const loadConfig = async (configPath) => {
|
||||
console.error(`Failed to load search configuration: ${configPath}`, error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const getFieldLabel = (key, value) => {
|
||||
if (logFieldLabels[key]) {
|
||||
return logFieldLabels[key];
|
||||
}
|
||||
|
||||
if (typeof value === 'string' && logFieldLabels[value]) {
|
||||
return logFieldLabels[value];
|
||||
}
|
||||
|
||||
return key;
|
||||
};
|
||||
Reference in New Issue
Block a user