Files
operationSystem-front/src/pages/ServiceManage/MenuBannerRegist.js
bcjang fa290b64ec api 공통 모듈생성
search, api 공통 모듈 생성
공통모듈 화면 별 반영
2025-05-01 07:04:14 +09:00

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;
`;