524 lines
15 KiB
JavaScript
524 lines
15 KiB
JavaScript
import { useState, useEffect, Fragment } from 'react';
|
|
|
|
import { Title, SelectInput, BtnWrapper, TextInput, Label, InputLabel, Textarea, SearchBarAlert } from '../../../styles/Components';
|
|
import Button from '../../common/button/Button';
|
|
import Modal from '../../common/modal/Modal';
|
|
import { EventIsItem, EventModify } from '../../../apis';
|
|
|
|
import { authList } from '../../../store/authList';
|
|
import { useRecoilValue } from 'recoil';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { authType, benItems, commonStatus, wellType } from '../../../assets/data';
|
|
import {
|
|
AppendRegistBox, AppendRegistTable, AreaBtnClose,
|
|
BtnDelete, DetailInputItem, DetailInputRow,
|
|
DetailModalWrapper, RegistGroup, DetailRegistInfo, DetailState,
|
|
Item, ItemList, LangArea
|
|
} from '../../../styles/ModuleComponents';
|
|
import { convertKTC, combineDateTime, timeDiffMinute, convertKTCDate } from '../../../utils';
|
|
import DateTimeInput from '../../common/input/DateTimeInput';
|
|
import { useLoading } from '../../../context/LoadingProvider';
|
|
import { useAlert } from '../../../context/AlertProvider';
|
|
import { alertTypes } from '../../../assets/data/types';
|
|
|
|
const EventDetailModal = ({ detailView, handleDetailView, content, setDetailData }) => {
|
|
const userInfo = useRecoilValue(authList);
|
|
const { t } = useTranslation();
|
|
const token = sessionStorage.getItem('token');
|
|
const {withLoading} = useLoading();
|
|
const {showModal, showToast} = useAlert();
|
|
|
|
const id = content && content.id;
|
|
const updateAuth = userInfo.auth_list && userInfo.auth_list.some(auth => auth.id === authType.eventUpdate);
|
|
|
|
const [time, setTime] = useState({
|
|
start_hour: '00',
|
|
start_min: '00',
|
|
end_hour: '00',
|
|
end_min: '00',
|
|
}); //시간 정보
|
|
|
|
const [item, setItem] = useState('');
|
|
const [itemCount, setItemCount] = useState('');
|
|
const [resource, setResource] = useState('19010001');
|
|
const [resourceCount, setResourceCount] = useState('');
|
|
|
|
const [resultData, setResultData] = useState({});
|
|
|
|
const [isNullValue, setIsNullValue] = useState(false);
|
|
// 과거 판단
|
|
const [isPast, setIsPast] = useState(false);
|
|
const [isChanged, setIsChanged] = useState(false);
|
|
|
|
const [btnValidation, setBtnValidation] = useState(false);
|
|
const [isReadOnly, setIsReadOnly] = useState(false);
|
|
const [itemCheckMsg, setItemCheckMsg] = useState('');
|
|
|
|
useEffect(() => {
|
|
if(content){
|
|
const start_dt_KTC = convertKTCDate(content.start_dt)
|
|
const end_dt_KTC = convertKTCDate(content.end_dt)
|
|
|
|
setResultData({
|
|
start_dt: start_dt_KTC,
|
|
end_dt: end_dt_KTC,
|
|
event_type: content.event_type,
|
|
mail_list: content.mail_list,
|
|
item_list: content.item_list,
|
|
});
|
|
|
|
setTime({ ...time,
|
|
start_hour: String(start_dt_KTC.getHours()).padStart(2, '0'),
|
|
start_min: String(start_dt_KTC.getMinutes()).padStart(2, '0'),
|
|
end_hour: String(end_dt_KTC.getHours()).padStart(2, '0'),
|
|
end_min: String(end_dt_KTC.getMinutes()).padStart(2, '0')
|
|
});
|
|
|
|
start_dt_KTC < (new Date) ? setIsPast(true) : setIsPast(false);
|
|
content.mail_list.length === 1 && setBtnValidation(true);
|
|
}
|
|
|
|
setItem('');
|
|
|
|
}, [content]);
|
|
|
|
useEffect(() => {
|
|
if(!updateAuth || isPast){
|
|
setIsReadOnly(true);
|
|
}else{
|
|
setIsReadOnly(false);
|
|
}
|
|
}, [updateAuth, isPast]);
|
|
|
|
useEffect(() => {
|
|
if (conditionCheck()) {
|
|
setIsNullValue(false);
|
|
} else {
|
|
setIsNullValue(true);
|
|
}
|
|
}, [resultData]);
|
|
|
|
useEffect(() => {
|
|
setItemCheckMsg('');
|
|
}, [item]);
|
|
|
|
// 아이템 수량 숫자 체크
|
|
const handleItemCount = e => {
|
|
if (e.target.value === '0' || e.target.value === '-0') {
|
|
setItemCount('1');
|
|
e.target.value = '1';
|
|
} else if (e.target.value < 0) {
|
|
let plusNum = Math.abs(e.target.value);
|
|
setItemCount(plusNum);
|
|
} else {
|
|
setItemCount(e.target.value);
|
|
}
|
|
};
|
|
|
|
// 아이템 추가
|
|
const handleItemList = async () => {
|
|
if(benItems.includes(item)){
|
|
showToast('MAIL_ITEM_ADD_BEN', {type: alertTypes.warning});
|
|
return;
|
|
}
|
|
if(item.length === 0 || itemCount.length === 0) return;
|
|
|
|
const result = await EventIsItem(token, {item: item});
|
|
|
|
if(result.data.result === "ERROR"){
|
|
setItemCheckMsg(t('NOT_ITEM'));
|
|
return;
|
|
}
|
|
|
|
const itemIndex = resultData.item_list.findIndex((data) => data.item === item);
|
|
if (itemIndex !== -1) {
|
|
setItemCheckMsg(t('MAIL_ITEM_ADD_DUPL'));
|
|
return;
|
|
}
|
|
const newItem = { item: item, item_cnt: itemCount, item_name: result.data.data.item_info.item_name };
|
|
|
|
resultData.item_list.push(newItem);
|
|
|
|
setIsChanged(true);
|
|
setItem('');
|
|
setItemCount('');
|
|
};
|
|
|
|
// 아이템 삭제
|
|
const onItemRemove = id => {
|
|
let filterList = resultData.item_list && resultData.item_list.filter(item => item !== resultData.item_list[id]);
|
|
setIsChanged(true);
|
|
|
|
setResultData({ ...resultData, item_list: filterList });
|
|
};
|
|
|
|
// 자원 수량 숫자 체크
|
|
const handleResourceCount = e => {
|
|
if (e.target.value === '0' || e.target.value === '-0') {
|
|
setResourceCount('1');
|
|
e.target.value = '1';
|
|
} else if (e.target.value < 0) {
|
|
let plusNum = Math.abs(e.target.value);
|
|
setResourceCount(plusNum);
|
|
} else {
|
|
setResourceCount(e.target.value);
|
|
}
|
|
};
|
|
|
|
// 자원 추가
|
|
const handleResourceList = (e) => {
|
|
if(resource.length === 0 || resourceCount.length === 0) return;
|
|
|
|
const itemIndex = resultData.item_list.findIndex(
|
|
(item) => item.item === resource
|
|
);
|
|
|
|
if (itemIndex !== -1) {
|
|
const item_cnt = resultData.item_list[itemIndex].item_cnt;
|
|
resultData.item_list[itemIndex].item_cnt = Number(item_cnt) + Number(resourceCount);
|
|
} else {
|
|
const name = wellType.find(well => well.value === resource).name;
|
|
const newItem = { item: resource, item_cnt: resourceCount, item_name: name };
|
|
resultData.item_list.push(newItem);
|
|
}
|
|
setIsChanged(true);
|
|
setResource('')
|
|
setResourceCount('');
|
|
};
|
|
|
|
// 입력창 삭제
|
|
const onLangDelete = language => {
|
|
let filterList = resultData.mail_list && resultData.mail_list.filter(el => el.language !== language);
|
|
|
|
if (filterList.length === 1) setBtnValidation(true);
|
|
|
|
setIsChanged(true);
|
|
setResultData({ ...resultData, mail_list: filterList });
|
|
};
|
|
|
|
// 날짜 처리
|
|
const handleDateChange = (data, type) => {
|
|
const date = new Date(data);
|
|
setResultData({
|
|
...resultData,
|
|
[`${type}_dt`]: combineDateTime(date, time[`${type}_hour`], time[`${type}_min`]),
|
|
});
|
|
setIsChanged(true);
|
|
};
|
|
|
|
// 시간 처리
|
|
const handleTimeChange = (e, type) => {
|
|
const { id, value } = e.target;
|
|
const newTime = { ...time, [`${type}_${id}`]: value };
|
|
setTime(newTime);
|
|
|
|
const date = resultData[`${type}_dt`] ? new Date(resultData[`${type}_dt`]) : new Date();
|
|
|
|
setResultData({
|
|
...resultData,
|
|
[`${type}_dt`]: combineDateTime(date, newTime[`${type}_hour`], newTime[`${type}_min`]),
|
|
});
|
|
setIsChanged(true);
|
|
};
|
|
|
|
// 확인 버튼 후 다 초기화
|
|
const handleReset = () => {
|
|
setBtnValidation(false);
|
|
setIsNullValue(false);
|
|
setIsChanged(false);
|
|
};
|
|
|
|
const conditionCheck = () => {
|
|
return (
|
|
content && content.mail_list.every(data => data.content !== '' && data.title !== '') &&
|
|
isChanged
|
|
);
|
|
};
|
|
|
|
const handleSubmit = async (type, param = null) => {
|
|
switch (type) {
|
|
case "submit":
|
|
if (!conditionCheck()) return;
|
|
|
|
showModal('MAIL_UPDATE_SAVE', {
|
|
type: alertTypes.confirm,
|
|
onConfirm: () => handleSubmit('updateConfirm')
|
|
});
|
|
break;
|
|
case "updateConfirm":
|
|
const timeDiff = timeDiffMinute(resultData.start_dt, (new Date))
|
|
// 이벤트 시작 30분전이나 이미 SystemMail이 add된 상태에서는 수정할 수 없다.
|
|
if(content.add_flag || timeDiff <= 30){
|
|
showToast('EVENT_TIME_LIMIT_UPDATE', {type: alertTypes.warning});
|
|
return;
|
|
}
|
|
withLoading( async () => {
|
|
return await EventModify(token, id, resultData);
|
|
}).catch(error => {
|
|
showToast('API_FAIL', {type: alertTypes.error});
|
|
}).finally(() => {
|
|
showToast('UPDATE_COMPLETED', {type: alertTypes.success});
|
|
handleDetailView();
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
|
|
const detailState = (status) => {
|
|
switch (status) {
|
|
case commonStatus.wait:
|
|
return <DetailState>대기</DetailState>;
|
|
case commonStatus.running:
|
|
return <DetailState>진행중</DetailState>;
|
|
case commonStatus.finish:
|
|
return <DetailState result={commonStatus.finish}>완료</DetailState>;
|
|
case commonStatus.fail:
|
|
return <DetailState result={commonStatus.fail}>실패</DetailState>;
|
|
case commonStatus.delete:
|
|
return <DetailState result={commonStatus.delete}>삭제</DetailState>;
|
|
default:
|
|
return null;
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<Modal min="960px" $view={detailView}>
|
|
<Title $align="center">이벤트 상세 정보</Title>
|
|
{content &&
|
|
<DetailRegistInfo>
|
|
<span>등록자 : {content.create_by}</span>
|
|
<span>등록일 : {convertKTC(content.create_dt, false)}</span>
|
|
{typeof content.update_by !== 'undefined' && (
|
|
<>
|
|
<span>수정자 : {content.update_by}</span>
|
|
<span>수정일 : {convertKTC(content.update_dt, false)}</span>
|
|
</>
|
|
)}
|
|
</DetailRegistInfo>
|
|
}
|
|
<DetailModalWrapper>
|
|
{content &&
|
|
<RegistGroup>
|
|
<DetailInputRow>
|
|
<DateTimeInput
|
|
title="이벤트 기간"
|
|
dateName="시작 일자"
|
|
selectedDate={convertKTCDate(content.start_dt)}
|
|
handleSelectedDate={data => handleDateChange(data, 'start')}
|
|
onChange={e => handleTimeChange(e, 'start')}
|
|
|
|
/>
|
|
<DateTimeInput
|
|
dateName="종료 일자"
|
|
selectedDate={convertKTCDate(content.end_dt)}
|
|
handleSelectedDate={data => handleDateChange(data, 'end')}
|
|
onChange={e => handleTimeChange(e, 'end')}
|
|
/>
|
|
</DetailInputRow>
|
|
<DetailInputRow>
|
|
<DetailInputItem>
|
|
<InputLabel>이벤트 상태</InputLabel>
|
|
<div>{detailState(content.status)}</div>
|
|
</DetailInputItem>
|
|
{content.status === commonStatus.delete &&
|
|
<DetailInputItem>
|
|
<InputLabel>삭제 사유</InputLabel>
|
|
<div>{content.delete_desc}</div>
|
|
</DetailInputItem>
|
|
}
|
|
</DetailInputRow>
|
|
|
|
</RegistGroup>
|
|
}
|
|
{resultData.mail_list &&
|
|
resultData.mail_list.map(data => {
|
|
return (
|
|
<Fragment key={data.language}>
|
|
<AppendRegistBox>
|
|
<LangArea>
|
|
언어 : {data.language}
|
|
{btnValidation === false && !isReadOnly ? (
|
|
<AreaBtnClose
|
|
onClick={e => {
|
|
e.preventDefault();
|
|
onLangDelete(data.language);
|
|
}}
|
|
/>
|
|
) : (
|
|
<AreaBtnClose opacity="10%" />
|
|
)}
|
|
</LangArea>
|
|
<AppendRegistTable>
|
|
<tbody>
|
|
<tr>
|
|
<th width="120">
|
|
<Label>제목</Label>
|
|
</th>
|
|
<td>
|
|
<DetailInputItem>
|
|
<TextInput
|
|
placeholder="우편 제목 입력"
|
|
maxLength="30"
|
|
id={data.language}
|
|
value={data.title}
|
|
readOnly={isReadOnly}
|
|
onChange={e => {
|
|
let list = [...resultData.mail_list];
|
|
let findIndex = resultData.mail_list && resultData.mail_list.findIndex(item => item.language === e.target.id);
|
|
list[findIndex].title = e.target.value.trimStart();
|
|
|
|
setResultData({ ...resultData, mail_list: list });
|
|
setIsChanged(true);
|
|
}}
|
|
/>
|
|
</DetailInputItem>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>
|
|
<Label>내용</Label>
|
|
</th>
|
|
<td>
|
|
<Textarea
|
|
value={data.content}
|
|
readOnly={isReadOnly}
|
|
id={data.language}
|
|
onChange={e => {
|
|
if (e.target.value.length > 2000) {
|
|
return;
|
|
}
|
|
let list = [...resultData.mail_list];
|
|
let findIndex = resultData.mail_list && resultData.mail_list.findIndex(item => item.language === e.target.id);
|
|
list[findIndex].content = e.target.value.trimStart();
|
|
|
|
setResultData({ ...resultData, mail_list: list });
|
|
setIsChanged(true);
|
|
}}
|
|
/>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</AppendRegistTable>
|
|
</AppendRegistBox>
|
|
</Fragment>
|
|
);
|
|
})}
|
|
<AppendRegistBox>
|
|
<AppendRegistTable>
|
|
<tbody>
|
|
<tr>
|
|
<th width="120">
|
|
<Label>아이템 첨부</Label>
|
|
</th>
|
|
<td>
|
|
<DetailInputItem>
|
|
<TextInput
|
|
placeholder="Item Meta id 입력"
|
|
value={item}
|
|
onChange={e => {
|
|
let list = [];
|
|
list = e.target.value.trimStart();
|
|
setItem(list);
|
|
}}
|
|
disabled={isReadOnly}
|
|
/>
|
|
<TextInput
|
|
placeholder="수량"
|
|
value={itemCount}
|
|
type="number"
|
|
onChange={e => handleItemCount(e)}
|
|
width="90px"
|
|
disabled={isReadOnly}
|
|
/>
|
|
<Button
|
|
text="추가"
|
|
theme={itemCount.length === 0 || item.length === 0 ? 'disable' : 'search'}
|
|
handleClick={handleItemList}
|
|
/>
|
|
{itemCheckMsg && <SearchBarAlert>{itemCheckMsg}</SearchBarAlert>}
|
|
</DetailInputItem>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th width="120">
|
|
<Label>자원 첨부</Label>
|
|
</th>
|
|
<td>
|
|
<DetailInputItem>
|
|
<SelectInput onChange={e => setResource(e.target.value)} value={resource} disabled={isReadOnly}>
|
|
{wellType.map((data, index) => (
|
|
<option key={index} value={data.value}>
|
|
{data.name}
|
|
</option>
|
|
))}
|
|
</SelectInput>
|
|
<TextInput
|
|
placeholder="수량"
|
|
type="number"
|
|
value={resourceCount}
|
|
disabled={isReadOnly}
|
|
onChange={e => handleResourceCount(e)}
|
|
width="200px"
|
|
/>
|
|
<Button
|
|
text="추가"
|
|
theme={resourceCount.length === 0 || resource.length === 0 ? 'disable' : 'search'}
|
|
handleClick={handleResourceList}
|
|
width="100px"
|
|
height="35px"
|
|
errorMessage={isReadOnly} />
|
|
</DetailInputItem>
|
|
|
|
<div>
|
|
{resultData.item_list && (
|
|
<ItemList>
|
|
{resultData.item_list.map((data, index) => {
|
|
return (
|
|
<Item key={index}>
|
|
<span>
|
|
{data.item_name}[{data.item}] ({data.item_cnt})
|
|
</span>
|
|
{!isReadOnly && <BtnDelete onClick={() => onItemRemove(index)}></BtnDelete>}
|
|
</Item>
|
|
);
|
|
})}
|
|
</ItemList>
|
|
)}
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</AppendRegistTable>
|
|
</AppendRegistBox>
|
|
</DetailModalWrapper>
|
|
<BtnWrapper $justify="flex-end" $gap="10px" $paddingTop="20px">
|
|
<Button
|
|
text="확인"
|
|
theme="line"
|
|
name="확인버튼"
|
|
handleClick={() => {
|
|
handleDetailView();
|
|
handleReset();
|
|
setDetailData('');
|
|
}}
|
|
/>
|
|
{!isReadOnly && (
|
|
<Button
|
|
type="submit"
|
|
text="수정"
|
|
id="수정버튼"
|
|
theme={conditionCheck() ? 'primary' : 'disable'}
|
|
handleClick={() => handleSubmit('submit')}
|
|
/>
|
|
)}
|
|
</BtnWrapper>
|
|
</Modal>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default EventDetailModal;
|
|
|
|
|