417 lines
10 KiB
JavaScript
417 lines
10 KiB
JavaScript
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 { loadConfig, timeDiffMinute } from '../../utils';
|
|
import { SingleDatePicker, SingleTimePicker } from '../../components/common';
|
|
import CheckBox from '../../components/common/input/CheckBox';
|
|
import ImageUploadBtn from '../../components/ServiceManage/ImageUploadBtn';
|
|
import CaliForm from '../../components/common/Custom/CaliForm';
|
|
import { useAlert } from '../../context/AlertProvider';
|
|
import { alertTypes } from '../../assets/data/types';
|
|
|
|
const MenuBannerRegist = () => {
|
|
const navigate = useNavigate();
|
|
const userInfo = useRecoilValue(authList);
|
|
const { t } = useTranslation();
|
|
const token = sessionStorage.getItem('token');
|
|
const { showToast, showModal } = useAlert();
|
|
|
|
const [loading, setLoading] = useState(false); // 로딩 창
|
|
|
|
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({});
|
|
const [isFormValid, setIsFormValid] = useState(false);
|
|
|
|
useEffect(() => {
|
|
if(alertMsg){
|
|
showToast(alertMsg, {
|
|
type: alertTypes.error
|
|
})
|
|
}
|
|
}, [alertMsg]);
|
|
|
|
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();
|
|
}, []);
|
|
|
|
const handleFieldValidation = (isValid, errors) => {
|
|
setIsFormValid(isValid);
|
|
|
|
if (errors._form) {
|
|
setAlertMsg(t(errors._form));
|
|
}
|
|
};
|
|
|
|
// 폼 제출 핸들러
|
|
const handleFormSubmit = (data) => {
|
|
setFormData(data);
|
|
};
|
|
|
|
|
|
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 "cancel":
|
|
navigate('/servicemanage/menubanner');
|
|
break;
|
|
case "registConfirm":
|
|
setLoading(true);
|
|
|
|
const result = await MenuBannerSingleRegist(token, resultData);
|
|
|
|
setLoading(false);
|
|
showToast('REGIST_COMPLTE', {
|
|
type: alertTypes.success,
|
|
duration: 4000,
|
|
});
|
|
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={() =>
|
|
showModal('MENU_BANNER_REGIST_CANCEL', {
|
|
type: alertTypes.confirm,
|
|
onConfirm: () => handleSubmit('cancel'),
|
|
})}
|
|
/>
|
|
<Button
|
|
type="submit"
|
|
text="등록"
|
|
theme={checkCondition() ? 'primary' : 'disable'}
|
|
handleClick={() =>
|
|
showModal('MENU_BANNER_REGIST_CONFIRM', {
|
|
type: alertTypes.confirm,
|
|
onConfirm: () => handleSubmit('registConfirm'),
|
|
})}
|
|
/>
|
|
</BtnWrapper>
|
|
|
|
{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;
|
|
`;
|
|
|