Files
operationSystem-front/src/components/modal/BattleEventModal.js
bcjang 5143b45610 모달 스크롤 추가
detailGrid 수정
전투이벤트, 랜드경매, 이벤트, 메일 상세 수정
랜드경매 예약종료일 제거
2025-08-09 09:50:14 +09:00

385 lines
10 KiB
JavaScript

import React, { useState, Fragment, useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import Button from '../common/button/Button';
import {
Title,
BtnWrapper,
SearchBarAlert, SelectInput,
} from '../../styles/Components';
import {
FormInput,
FormLabel,
MessageWrapper,
FormRowGroup,
FormStatusBar,
FormStatusLabel,
FormStatusWarning,
FormButtonContainer,
} from '../../styles/ModuleComponents';
import { DetailLayout, Modal, SingleDatePicker, SingleTimePicker } from '../common';
import { NONE, TYPE_MODIFY, TYPE_REGISTRY } from '../../assets/data/adminConstants';
import { convertKTCDate } from '../../utils';
import {
battleEventHotTime,
battleEventRoundCount,
battleEventStatus,
battleRepeatType,
} from '../../assets/data/options';
import { BattleEventModify, BattleEventSingleRegist } from '../../apis/Battle';
import { alertTypes, battleEventStatusType } from '../../assets/data/types';
import { isValidDayRange } from '../../utils/date';
import { useAlert } from '../../context/AlertProvider';
import { useLoading } from '../../context/LoadingProvider';
const BattleEventModal = ({ modalType, detailView, handleDetailView, content, setDetailData, configData, rewardData, gameModeData }) => {
const { t } = useTranslation();
const token = sessionStorage.getItem('token');
const { showToast, showModal } = useAlert();
const {withLoading} = useLoading();
const [isNullValue, setIsNullValue] = useState(false);
const [resultData, setResultData] = useState(initData);
useEffect(() => {
if(modalType === TYPE_MODIFY && content && Object.keys(content).length > 0){
setResultData({
group_id: content.group_id,
id: content.id,
event_id: content.id,
event_name: content.event_name,
repeat_type: content.repeat_type,
config_id: content.config_id,
reward_group_id: content.reward_group_id,
round_count: content.round_count,
hot_time: content.hot_time,
round_time: content.round_time,
game_mode_id: content.game_mode_id,
status: content.status,
event_start_dt: convertKTCDate(content.event_start_dt),
event_end_dt: content.event_end_dt,
event_operation_time: content.event_operation_time,
});
}
}, [modalType, content]);
useEffect(() => {
if (checkCondition()) {
setIsNullValue(false);
} else {
setIsNullValue(true);
}
}, [resultData]);
const opGameMode = useMemo(() => {
return gameModeData?.map(item => ({
value: item.id,
name: `${item.desc}(${item.id})`
})) || [];
}, [gameModeData]);
const handleReset = () => {
setDetailData({});
setResultData(initData);
handleDetailView();
}
const handleSubmit = async (type, param = null) => {
switch (type) {
case "submit":
if (!checkCondition()) return;
const minAllowedTime = new Date(new Date().getTime() + 10 * 60000);
const startDt = resultData.event_start_dt;
const endDt = resultData.event_end_dt;
if (modalType === TYPE_REGISTRY && startDt < minAllowedTime) {
showToast('BATTLE_EVENT_MODAL_START_DT_WARNING', {type: alertTypes.warning});
return;
}
if(resultData.repeat_type !== 'NONE' && !isValidDayRange(startDt, endDt)) {
showToast('BATTLE_EVENT_MODAL_START_DT_WARNING', {type: alertTypes.warning});
return;
}
//화면에 머물면서 상태는 안바꼈을 경우가 있기에 시작시간 지났을경우 차단
if (modalType === TYPE_REGISTRY && startDt < new Date()) {
showToast('BATTLE_EVENT_MODAL_START_DT_WARNING', {type: alertTypes.warning});
return;
}
//최소 진행시간
if(resultData.event_operation_time < 10){
showToast('BATTLE_EVENT_MODAL_OPERATION_TIME_MIN_CHECK_WARNING', {type: alertTypes.warning});
return;
}
//최대 진행시간
if(resultData.repeat_type !== 'NONE' && resultData.event_operation_time > 1400){
showToast('BATTLE_EVENT_MODAL_OPERATION_TIME_MAX_CHECK_WARNING', {type: alertTypes.warning});
return;
}
// if(resultData.round_time === 0){
// const config = configData.find(data => data.id === resultData.config_id);
// setResultData({ ...resultData, round_time: config.round_time });
// }
showModal(isView('modify') ? 'BATTLE_EVENT_UPDATE_CONFIRM' : 'BATTLE_EVENT_REGIST_CONFIRM', {
type: alertTypes.confirm,
onConfirm: () => handleSubmit('registConfirm')
});
break;
case "registConfirm":
const params = {
...resultData,
event_operation_time: resultData.event_operation_time * 60
};
if(isView('modify')){
await withLoading( async () => {
return await BattleEventModify(token, content?.id, params);
}).then(data => {
if(data.result === "SUCCESS") {
showToast('UPDATE_COMPLETED', {type: alertTypes.success});
}else if(data.result === "ERROR_BATTLE_EVENT_TIME_OVER"){
showToast('BATTLE_EVENT_MODAL_TIME_CHECK_WARNING', {type: alertTypes.error});
}else{
showToast('UPDATE_FAIL', {type: alertTypes.error});
}
}).catch(reason => {
showToast('API_FAIL', {type: alertTypes.error});
}).finally(() => {
handleReset();
});
}
else{
await withLoading( async () => {
return await BattleEventSingleRegist(token, params);
}).then(data => {
if(data.result === "SUCCESS") {
showToast('REGIST_COMPLTE', {type: alertTypes.success});
}else if(data.result === "ERROR_BATTLE_EVENT_TIME_OVER"){
showToast('BATTLE_EVENT_MODAL_TIME_CHECK_WARNING', {type: alertTypes.error});
}else{
showToast('REGIST_FAIL', {type: alertTypes.error});
}
}).catch(reason => {
showToast('API_FAIL', {type: alertTypes.error});
}).finally(() => {
handleReset();
});
}
break;
}
}
const checkCondition = () => {
return (
resultData.event_start_dt !== ''
&& resultData.group_id !== ''
&& resultData.game_mode_id > 0
&& resultData.event_name !== ''
&& (resultData.repeat_type === 'NONE' || (resultData.repeat_type !== 'NONE' && resultData.event_end_dt !== ''))
);
};
const isView = (label) => {
switch (label) {
case "modify":
return modalType === TYPE_MODIFY && (content?.status === battleEventStatusType.stop);
case "start_dt":
case "repeat":
case "registry":
return modalType === TYPE_REGISTRY
case "end_dt":
case "group":
case "name":
case "config":
case "reward":
case "round":
case "hot":
case "mode":
case "operation_time":
return modalType === TYPE_REGISTRY || (modalType === TYPE_MODIFY &&(content?.status === battleEventStatusType.stop));
default:
return modalType === TYPE_MODIFY && (content?.status !== battleEventStatusType.stop);
}
}
const itemGroups = [
{
items: [
{
row: 0,
col: 0,
colSpan: 2,
type: 'text',
key: 'group_id',
label: '그룹 ID',
disabled: !isView('group'),
width: '150px',
},
{
row: 0,
col: 2,
colSpan: 2,
type: 'text',
key: 'event_name',
label: '이벤트명',
disabled: !isView('name'),
width: '250px',
},
{
row: 1,
col: 0,
colSpan: 2,
type: 'date',
key: 'event_start_dt',
label: '시작일시',
disabled: !isView('start_dt'),
format: 'YYYY-MM-DD HH:mm',
width: '200px',
showTime: true
},
{
row: 1,
col: 2,
colSpan: 2,
type: 'number',
key: 'event_operation_time',
label: '진행시간(분)',
disabled: !isView('operation_time'),
width: '100px',
min: 10,
},
{
row: 3,
col: 0,
colSpan: 2,
type: 'select',
key: 'repeat_type',
label: '반복',
disabled: !isView('repeat'),
width: '150px',
options: battleRepeatType
},
...(resultData?.repeat_type !== 'NONE' ? [{
row: 3,
col: 2,
colSpan: 2,
type: 'date',
key: 'event_end_dt',
label: '종료일',
disabled: !isView('end_dt'),
format: 'YYYY-MM-DD',
width: '200px'
}] : []),
{
row: 4,
col: 0,
colSpan: 2,
type: 'select',
key: 'game_mode_id',
label: '게임 모드',
disabled: !isView('mode'),
width: '150px',
options: opGameMode
},
{
row: 4,
col: 2,
colSpan: 2,
type: 'select',
key: 'hot_time',
label: '핫타임',
disabled: !isView('hot'),
width: '150px',
options: battleEventHotTime.map(value => ({
value: value,
name: `${value}`
}))
},
]
}
];
return (
<>
<Modal min="760px" $view={detailView}>
<Title $align="center">{isView('registry') ? "전투시스템 이벤트 등록" : isView('modify') ? "전투시스템 이벤트 수정" : "전투시스템 이벤트 상세"}</Title>
<DetailLayout
itemGroups={itemGroups}
formData={resultData}
onChange={setResultData}
disabled={false}
columnCount={4}
/>
{!isView() && isNullValue && <SearchBarAlert $marginTop="25px" $align="right">{t('REQUIRED_VALUE_CHECK')}</SearchBarAlert>}
<BtnWrapper $gap="10px" $marginTop="10px">
<FormStatusBar>
<FormStatusLabel>
현재상태: {battleEventStatus.find(data => data.value === content?.status)?.name || "등록"}
</FormStatusLabel>
<FormStatusWarning>
{isView('registry') ? '' : t('BATTLE_EVENT_MODAL_STATUS_WARNING')}
</FormStatusWarning>
</FormStatusBar>
<FormButtonContainer $gap="5px">
{isView() ?
<Button
text="확인"
name="확인버튼"
theme="line"
handleClick={() => handleReset()}
/>
:
<>
<Button
text="취소"
theme="line"
handleClick={() => showModal('CANCEL_CONFIRM', {
type: alertTypes.confirm,
onConfirm: () => handleReset()
})}
/>
<Button
type="submit"
text={isView('modify') ? "수정" : "등록"}
name="등록버튼"
theme={
checkCondition()
? 'primary'
: 'disable'
}
handleClick={() => handleSubmit('submit')}
/>
</>
}
</FormButtonContainer>
</BtnWrapper>
</Modal>
</>
);
};
export const initData = {
group_id: '',
event_name: '',
repeat_type: 'NONE',
config_id: 1,
round_time: 0,
reward_group_id: 1,
round_count: 1,
hot_time: 1,
game_mode_id: '',
event_start_dt: '',
event_end_dt: '',
event_operation_time: 10
}
export default BattleEventModal;