This commit is contained in:
2025-02-12 18:29:27 +09:00
commit 513ea114cc
290 changed files with 84274 additions and 0 deletions

View File

@@ -0,0 +1,620 @@
import { styled } from 'styled-components';
import { useState, useRef, Fragment, useEffect } from 'react';
import Button from '../common/button/Button';
import CheckBox from '../common/input/CheckBox';
import Modal from '../common/modal/Modal';
import { Title, BtnWrapper, SelectInput, TextInput, DatePickerWrapper, InputLabel, Textarea, ModalText, SearchBarAlert } from '../../styles/Components';
import CloseIcon from '../../assets/img/icon/icon-close.png';
import DatePickerComponent from '../common/Date/DatePickerComponent';
import { HourList, MinuteList, modalTypes } from '../../assets/data';
import { NoticeRegist } from '../../apis';
import { convertKTC, convertKTCDate } from '../../utils';
import DynamicModal from '../common/modal/DynamicModal';
import { useTranslation } from 'react-i18next';
import {
BoxWrapper, InputGroup2,
MessageBox, MessageWrapper,
NoticeInputGroup, NoticeInputItem, NoticeInputItem2,
NoticeInputRow, NoticeInputRow2,
NoticeRegistGroup,
RegistInputItem, RepeatTime, SubText, SubTextRow, TitleLang,
} from '../../styles/ModuleComponents';
import { languageType } from '../../assets/data/options';
const BoardRegistModal = ({ registView, setRegistView, copyData, setIsCopyData }) => {
const [doubleSubmitFlag, setDoubleSubmitFlag] = useState(false);
const { t } = useTranslation();
const [sendHour, setSendHour] = useState('00');
const [sendMin, setSendMin] = useState('00');
const [endHour, setEndHour] = useState('00');
const [endMin, setEndMin] = useState('00');
const [repeatHour, setRepeatHour] = useState('00');
const [repeatMin, setRepeatMin] = useState('00');
const [confirmModal, setConfirmModal] = useState('hidden');
const [completeModal, setCompleteModal] = useState('hidden');
const [errorModal, setErrorModal] = useState('hidden');
const [confirmText, setConfirmText] = useState('');
const [completeText, setCompleteText] = useState('');
const [isNullValue, setIsNullValue] = useState(false);
const [btnValidation, setBtnValidation] = useState(false);
const [message_lang, setMessage_lang] = useState('KO');
const itemId = useRef(1);
const resetData = {
send_dt: '',
message_type: 'CHATTING',
is_repeat: false,
repeat_type: 'COUNT',
repeat_dt: '00:00:00',
repeat_cnt: '1',
game_message: [
{ language: 'KO', content: '' },
{ language: 'EN', content: '' },
{ language: 'JA', content: '' },
],
};
const [resultData, setResultData] = useState({
send_dt: '',
end_dt: '',
message_type: 'CHATTING',
is_repeat: false,
repeat_type: 'COUNT',
repeat_dt: '00:00:00',
repeat_cnt: '1',
game_message: [
{ language: 'KO', content: '' },
{ language: 'EN', content: '' },
{ language: 'JA', content: '' },
],
});
const KOREAN_TIME = copyData && convertKTCDate(copyData.detail.send_dt);
// console.log(resultData);
useEffect(() => {
setResultData({
send_dt: copyData && '',
end_dt: copyData && '',
message_type: copyData ? copyData.detail.message_type : 'CHATTING',
is_repeat: copyData ? copyData.detail.is_repeat : false,
repeat_type: copyData ? copyData.detail.repeat_type : 'COUNT',
repeat_dt: copyData ? copyData.detail.repeat_dt : '00:00:00',
repeat_cnt: copyData ? copyData.detail.repeat_cnt : '1',
game_message: copyData
? copyData.game_message
: [
{ language: 'KO', content: '' },
{ language: 'EN', content: '' },
{ language: 'JA', content: '' },
],
});
if (copyData && copyData.game_message.length <= 1) {
setBtnValidation(true);
}
}, [copyData]);
const handleRepeatTime = e => {
if (e.target.id === 'hour') setRepeatHour(e.target.value);
else if (e.target.id === 'min') setRepeatMin(e.target.value);
setResultData({ ...resultData, repeat_dt: (e.target.id === 'hour' ? e.target.value : repeatHour) + ':' + (e.target.id === 'min' ? e.target.value : repeatMin) + ':00' });
};
// 날짜 설정
const handleSelectedDate = data => {
const sendDate = new Date(data);
if (resultData.send_dt.length === 0 || typeof resultData.send_dt.length != 'undefined') {
setSendHour('00');
setSendMin('00');
}
const resultSendData = new Date(sendDate.getFullYear(), sendDate.getMonth(), sendDate.getDate(), sendHour, sendMin);
setResultData({ ...resultData, send_dt: resultSendData });
};
// 시간 설정
const handleSendTime = e => {
let sendDate = '';
if (resultData.send_dt.length === 0 || typeof resultData.send_dt.length != 'undefined') {
sendDate = new Date();
} else {
sendDate = new Date(resultData.send_dt);
}
if (e.target.id === 'hour') setSendHour(e.target.value);
else if (e.target.id === 'min') setSendMin(e.target.value);
// console.log(sendDate);
const result = new Date(sendDate.getFullYear(), sendDate.getMonth(), sendDate.getDate(), e.target.id === 'hour' ? e.target.value : sendHour, e.target.id === 'min' ? e.target.value : sendMin);
setResultData({ ...resultData, send_dt: result });
};
// 종료 날짜 설정
const handleSelectedEndDate = data => {
const endDate = new Date(data);
if (resultData.end_dt.length === 0 || typeof resultData.end_dt.length != 'undefined') {
setEndHour('00');
setEndMin('00');
}
let resultEndData = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate(), endHour, endMin);
if (resultData.send_dt > resultEndData){
alert("송출 일자보다 작을 수 없습니다.");
resultEndData = new Date(resultData.send_dt);
}
setResultData({ ...resultData, end_dt: resultEndData });
};
//종료 시간 설정
const handleEndTime = e => {
let endDate = '';
if (resultData.end_dt.length === 0 || typeof resultData.end_dt.length != 'undefined') {
endDate = new Date();
} else {
endDate = new Date(resultData.end_dt);
}
if (e.target.id === 'hour') setEndHour(e.target.value);
else if (e.target.id === 'min') setEndMin(e.target.value);
// console.log(sendDate);
let result = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate(), e.target.id === 'hour' ? e.target.value : endHour, e.target.id === 'min' ? e.target.value : endMin);
if (resultData.send_dt > result){
alert("송출 일자보다 작을 수 없습니다.");
result = new Date(resultData.send_dt);
}
setResultData({ ...resultData, end_dt: result });
};
const handleDelete = language => {
let filterList = resultData.game_message.filter(el => el.language !== language);
if (filterList.length === 1) {
setBtnValidation(true);
} else if (filterList.length > 1) {
setBtnValidation(false);
}
setResultData({ ...resultData, game_message: filterList });
};
// 반복횟수 입력 데이터 폼 처리
const handleRepeatValue = e => {
// e.target.value.length === 0 ? setIsNullValue(true) : setIsNullValue(false);
if (e.target.value === '0' || e.target.value === '-0' || e.target.value.length === 0) {
setResultData({ ...resultData, repeat_cnt: '1' });
e.target.value = '1';
} else if (e.target.value < 0) {
let plusNum = Math.abs(e.target.value);
setResultData({ ...resultData, repeat_cnt: plusNum });
} else {
setResultData({ ...resultData, repeat_cnt: e.target.value });
}
};
// 등록 버튼
const handleRegistBtn = e => {
e.preventDefault();
if (
!resultData.game_message.some(data => data.content !== '') ||
resultData.game_message.length === 0 ||
resultData.send_dt.length === 0 ||
typeof resultData.send_dt.length != 'undefined' ||
(resultData.is_repeat === true && resultData.repeat_dt === '00:00:00') ||
(resultData.is_repeat === true && resultData.message_type === "COUNT" && resultData.repeat_cnt.length === 0) ||
(resultData.is_repeat === true && resultData.message_type === "COUNT" && resultData.end_dt.length === 0) ||
(resultData.is_repeat === true && resultData.message_type === "COUNT" && typeof resultData.end_dt.length !== 'undefined')
) {
setIsNullValue(true);
} else {
setIsNullValue(false);
setConfirmText('인게임 메시지를 등록하시겠습니까?');
handleConfirmModal('regist');
}
};
// 취소 버튼
const handleCancelBtn = e => {
e.preventDefault();
setConfirmText('인게임 메시지 등록을 취소하시겠습니까?');
handleConfirmModal('cancel');
};
// 입력창 글자 제한
const handleInputData = e => {
if (e.target.value.length > 250) {
return;
}
let list = [...resultData.game_message];
let findIndex = resultData.game_message.findIndex(item => item.language === e.target.id);
list[findIndex].content = e.target.value.trimStart();
setResultData({ ...resultData, game_message: list });
};
// 알림창 텍스트
const handleSubmitNotice = async () => {
const token = sessionStorage.getItem('token');
if (confirmText === '인게임 메시지를 등록하시겠습니까?') {
const message = await NoticeRegist(token, resultData);
message.data.data.message !== '등록 하였습니다.' ? setCompleteText(message.data.data.message) : setCompleteText('등록이 완료되었습니다.');
handleConfirmModal();
handleCompleteModal();
setIsNullValue(false);
setRegistView('hidden');
} else if (confirmText === '인게임 메시지 등록을 취소하시겠습니까?') {
handleConfirmModal();
handleCompleteModal();
setCompleteText('등록이 취소되었습니다.');
setRegistView('hidden');
}
itemId.current = 1;
};
// 언어 선택
const handleLanguage = e => {
setMessage_lang(e.target.value);
if(!resultData.game_message.some(({language}) => language === e.target.value))
setResultData({ ...resultData, game_message: [...resultData.game_message, {language: e.target.value, content: ''}] })
}
// 확인 모달
const handleConfirmModal = step => {
if (confirmModal === 'hidden') {
setConfirmModal('view');
} else {
setConfirmModal('hidden');
}
};
// 완료 모달창
const handleCompleteModal = () => {
setIsCopyData(false);
if (completeModal === 'hidden') {
setCompleteModal('view');
} else {
setCompleteModal('hidden');
setResultData(resetData);
window.location.reload();
}
};
// 필수값 입력 모달창
const handleErrorModal = () => {
if (errorModal === 'hidden') {
setErrorModal('view');
} else {
setErrorModal('hidden');
}
};
// 내용 복사일 때 이동 페이지
return (
<>
<Modal min="960px" $view={registView}>
{/* 등록 후 정보 확인시 타이틀 텍스트 변경 인게임 메시지 등록 -> 인게임 메시지 정보 */}
<Title $align="center"> 인게임 메시지 등록</Title>
<MessageWrapper>
<InputLabel>[메세지 등록 설정]</InputLabel>
<NoticeRegistGroup>
<NoticeInputRow>
<RegistInputItem>
<InputLabel>송출 일자(예약)</InputLabel>
<InputGroup2>
<NoticeInputGroup>
<DatePickerWrapper>
<DatePickerComponent name="시작 일자" handleSelectedDate={data => handleSelectedDate(data)} selectedDate={resultData.send_dt} pastDate={new Date()} />
</DatePickerWrapper>
<SelectInput
onChange={e => handleSendTime(e)}
id="hour"
value={
resultData && String(new Date(resultData.send_dt).getHours()) < 10
? '0' + String(new Date(resultData.send_dt).getHours())
: (resultData && String(new Date(resultData.send_dt).getHours())) || ''
}>
{HourList.map(hour => (
<option
value={hour}
key={hour}
// selected={
// resultData && String(new Date(resultData.send_dt).getHours()) < 10
// ? '0' + String(new Date(resultData.send_dt).getHours()) === hour
// : resultData && String(new Date(resultData.send_dt).getHours()) === hour
// ? 'selected'
// : ''
// }
>
{hour}
</option>
))}
</SelectInput>
<SelectInput
onChange={e => handleSendTime(e)}
id="min"
value={
resultData && String(new Date(resultData.send_dt).getMinutes()) < 10
? '0' + String(new Date(resultData.send_dt).getMinutes())
: (resultData && String(new Date(resultData.send_dt).getMinutes())) || ''
}>
{MinuteList.map(min => (
<option
value={min}
key={min}
// selected={
// resultData && String(new Date(resultData.send_dt).getMinutes()) < 10
// ? '0' + String(new Date(resultData.send_dt).getMinutes()) === min
// : resultData && String(new Date(resultData.send_dt).getMinutes()) === min
// ? 'selected'
// : ''
// }
>
{min}
</option>
))}
</SelectInput>
</NoticeInputGroup>
<SubText>* UTC+9 한국시간 기준으로 설정 (UTC+0 자동 반영처리)</SubText>
</InputGroup2>
</RegistInputItem>
<RegistInputItem>
<InputLabel>메시지 타입</InputLabel>
<SelectInput onChange={e => setResultData({ ...resultData, message_type: e.target.value })} value={resultData.message_type || ''}>
<option value="CHATTING">채팅</option>
<option value="CHATTING_TOAST">채팅 + 토스트</option>
</SelectInput>
</RegistInputItem>
</NoticeInputRow>
<NoticeInputRow>
<CheckBox label="반복 발송" id="input-regist" inline={false} checked={resultData.is_repeat} setData={e => setResultData({ ...resultData, is_repeat: e.target.checked })} style={{display: 'hidden'}}/>
{resultData.is_repeat === true && (
<>
<RegistInputItem>
<InputLabel>반복 타입</InputLabel>
<SelectInput onChange={e => setResultData({ ...resultData, repeat_type: e.target.value })} value={resultData.repeat_type || ''}>
<option value="COUNT">횟수</option>
<option value="DATE">일자</option>
<option value="TIME">특정시간</option>
</SelectInput>
</RegistInputItem>
</>
)}
</NoticeInputRow>
<NoticeInputRow>
{resultData.is_repeat === true && (
<>
{resultData.repeat_type !== "COUNT" && (
<>
<NoticeInputItem>
<InputLabel>종료 일자</InputLabel>
<InputGroup2>
<NoticeInputGroup>
<DatePickerWrapper>
<DatePickerComponent name="종료 일자" handleSelectedDate={data => handleSelectedEndDate(data)} selectedDate={resultData.end_dt} pastDate={new Date()} />
</DatePickerWrapper>
<SelectInput
onChange={e => handleEndTime(e)}
id="hour"
value={
resultData && String(new Date(resultData.end_dt).getHours()) < 10
? '0' + String(new Date(resultData.end_dt).getHours())
: (resultData && String(new Date(resultData.end_dt).getHours())) || ''
}>
{HourList.map(hour => (
<option
value={hour}
key={hour}
>
{hour}
</option>
))}
</SelectInput>
<SelectInput
onChange={e => handleEndTime(e)}
id="min"
value={
resultData && String(new Date(resultData.end_dt).getMinutes()) < 10
? '0' + String(new Date(resultData.end_dt).getMinutes())
: (resultData && String(new Date(resultData.end_dt).getMinutes())) || ''
}>
{MinuteList.map(min => (
<option
value={min}
key={min}
>
{min}
</option>
))}
</SelectInput>
</NoticeInputGroup>
</InputGroup2>
</NoticeInputItem>
</>
)}
<RegistInputItem>
<RepeatTime>
{resultData.repeat_type === "TIME" && (<span>발송시간</span>)}
<SelectInput onChange={e => handleRepeatTime(e)} id="hour" value={resultData.repeat_dt.split(':')[0] || ''}>
{HourList.map(hour => (
<option
value={hour}
key={hour}
>
{hour}
</option>
))}
</SelectInput>
<SelectInput onChange={e => handleRepeatTime(e)} id="min" value={resultData.repeat_dt.split(':')[1] || ''}>
{MinuteList.map(min => (
<option
value={min}
key={min}
>
{min}
</option>
))}
</SelectInput>
{resultData.repeat_type !== "TIME" ? (
<>
<span>마다</span>
<SubText>* 최초 송출 이후 설정된 시간 단위마다 송출</SubText>
</>
) : (<SubText>* 설정된 시간에만 송출</SubText>)}
</RepeatTime>
</RegistInputItem>
{resultData.repeat_type === "COUNT" && (
<>
<NoticeInputItem>
<InputLabel>반복 횟수</InputLabel>
<NoticeInputGroup>
<TextInput
type="number"
value={resultData.repeat_cnt || ''}
onChange={e => {
handleRepeatValue(e);
}}
width="80px"
/>
<span></span>
</NoticeInputGroup>
</NoticeInputItem>
</>
)}
</>
)}
</NoticeInputRow>
</NoticeRegistGroup>
<NoticeInputRow2>
<InputLabel>
[메세지 작성]
<SubTextRow>* 작성하지 않은 언어는 발송되지 않습니다.</SubTextRow>
</InputLabel>
<NoticeInputItem2>
<InputLabel>언어</InputLabel>
<SelectInput onChange={e => handleLanguage(e) } value={message_lang}>
{languageType.map((data, index) => (
<option key={index} value={data.value}>
{data.name}
</option>
))}
</SelectInput>
</NoticeInputItem2>
</NoticeInputRow2>
<BoxWrapper>
{resultData.game_message.map(content => {
return (
<Fragment key={content.language}>
{message_lang === content.language && (
<MessageBox>
{/* <BtnWrapper $justify="flex-end">
{btnValidation === false ? (
<ButtonClose
onClick={e => {
e.preventDefault();
handleDelete(content.language);
}}
/>
) : (
<ButtonClose opacity="10%" />
)}
</BtnWrapper> */}
<TitleLang>언어 : {content.language}</TitleLang>
<div>
<Textarea id={content.language} onChange={e => handleInputData(e)} defaultValue={content.content || ''} maxLength={250} />
</div>
</MessageBox>
)}
</Fragment>
);
})}
</BoxWrapper>
</MessageWrapper>
{isNullValue && <SearchBarAlert $marginTop="25px">필수값을 입력해주세요.</SearchBarAlert>}
<BtnWrapper $gap="10px" $justify="center" $marginTop="20px">
<Button text="취소" theme="line" handleClick={handleCancelBtn} />
<Button
type="submit"
text="등록"
name="등록버튼"
theme={
// resultData.game_message.map(data => data.content === '').includes(true) ||
!resultData.game_message.some(data => data.content !== '') ||
resultData.game_message.length === 0 ||
resultData.send_dt.length === 0 ||
typeof resultData.send_dt.length != 'undefined' ||
(resultData.is_repeat === true && resultData.repeat_dt === '00:00:00') ||
(resultData.is_repeat === true && resultData.message_type === "COUNT" && resultData.repeat_cnt.length === 0) ||
(resultData.is_repeat === true && resultData.message_type === "COUNT" && resultData.end_dt.length === 0) ||
(resultData.is_repeat === true && resultData.message_type === "COUNT" && typeof resultData.end_dt.length !== 'undefined')
? 'disable'
: 'primary'
}
handleClick={handleRegistBtn}
/>
</BtnWrapper>
</Modal>
{/* 확인 모달 */}
<DynamicModal
modalType={modalTypes.confirmOkCancel}
view={confirmModal}
modalText={confirmText}
handleSubmit={() => {
doubleSubmitFlag || handleSubmitNotice();
setDoubleSubmitFlag(true);
}}
handleCancel={handleConfirmModal}
/>
{/* 완료 모달 */}
<DynamicModal
modalType={modalTypes.completed}
view={completeModal}
modalText={completeText}
handleSubmit={handleCompleteModal}
/>
{/* 필수값 미입력 모달 */}
<DynamicModal
modalType={modalTypes.completed}
view={errorModal}
modalText={t('NULL_MSG')}
handleSubmit={handleErrorModal}
/>
</>
);
};
export default BoardRegistModal;