421 lines
13 KiB
JavaScript
421 lines
13 KiB
JavaScript
import { useState, Fragment, useEffect } from 'react';
|
|
import { useTranslation } from 'react-i18next';
|
|
import Button from '../common/button/Button';
|
|
import Loading from '../common/Loading';
|
|
|
|
import {
|
|
Title,
|
|
BtnWrapper,
|
|
SearchBarAlert, SelectInput, InputLabel,
|
|
} from '../../styles/Components';
|
|
|
|
import {
|
|
FormHelperText,
|
|
FormInput,
|
|
FormLabel,
|
|
FormTextArea,
|
|
FormTextAreaWrapper,
|
|
MessageWrapper,
|
|
FormRowGroup,
|
|
NoticeInputRow2,
|
|
NoticeInputItem2, BoxWrapper, FormStatusBar, FormStatusLabel, FormStatusWarning, FormButtonContainer,
|
|
} from '../../styles/ModuleComponents';
|
|
import { modalTypes } from '../../assets/data';
|
|
import {DynamicModal, Modal, DateTimeRangePicker} from '../common';
|
|
import { LandAuctionModify, LandAuctionSingleRegist } from '../../apis';
|
|
import {
|
|
AUCTION_MIN_MINUTE_TIME,
|
|
ONE_MINUTE,
|
|
ONE_MINUTE_MS,
|
|
TYPE_MODIFY,
|
|
TYPE_REGISTRY,
|
|
} from '../../assets/data/adminConstants';
|
|
import { landAuctionStatus, landAuctionStatusType, languageType, CurrencyType } from '../../assets/data';
|
|
import { useModal } from '../../hooks/hook';
|
|
import { convertKTCDate } from '../../utils';
|
|
import { msToMinutes } from '../../utils/date';
|
|
import { useAlert } from '../../context/AlertProvider';
|
|
import { alertTypes } from '../../assets/data/types';
|
|
|
|
const LandAuctionModal = ({ modalType, detailView, handleDetailView, content, setDetailData, landData, buildingData }) => {
|
|
const { t } = useTranslation();
|
|
const token = sessionStorage.getItem('token');
|
|
const { showToast, showModal } = useAlert();
|
|
|
|
const [loading, setLoading] = useState(false);
|
|
const [message_lang, setMessage_lang] = useState('KO');
|
|
|
|
const [isNullValue, setIsNullValue] = useState(false); // 데이터 값 체크
|
|
const [selectLand, setSelectLand] = useState(initLandData);
|
|
|
|
const [resultData, setResultData] = useState(initData); //데이터 정보
|
|
const [resetDateTime, setResetDateTime] = useState(false);
|
|
|
|
useEffect(() => {
|
|
if(modalType === TYPE_MODIFY && content && Object.keys(content).length > 0){
|
|
setResultData({
|
|
land_id: content.land_id,
|
|
land_name: content.land_name,
|
|
land_socket: content.land_socket,
|
|
land_size: content.land_size,
|
|
auction_seq: content.auction_seq,
|
|
currency_type: content.currency_type,
|
|
start_price: content.start_price,
|
|
resv_start_dt: convertKTCDate(content.resv_start_dt),
|
|
resv_end_dt: convertKTCDate(content.resv_end_dt),
|
|
auction_start_dt: convertKTCDate(content.auction_start_dt),
|
|
auction_end_dt: convertKTCDate(content.auction_end_dt),
|
|
});
|
|
const land = landData.find(land => land.id === parseInt(content.land_id));
|
|
setSelectLand(land);
|
|
}
|
|
}, [modalType, content]);
|
|
|
|
useEffect(() => {
|
|
if (checkCondition()) {
|
|
setIsNullValue(false);
|
|
} else {
|
|
setIsNullValue(true);
|
|
}
|
|
}, [resultData]);
|
|
|
|
useEffect(() => {
|
|
if (resetDateTime) {
|
|
setResetDateTime(false);
|
|
}
|
|
}, [resetDateTime]);
|
|
|
|
// 입력 수량 처리
|
|
const handleCount = e => {
|
|
const regex = /^\d*\.?\d{0,2}$/;
|
|
if (!regex.test(e.target.value) && e.target.value !== '-') {
|
|
return;
|
|
}
|
|
|
|
let count = 0;
|
|
if (e.target.value === '-0') {
|
|
count = 1;
|
|
} else if (e.target.value < 0) {
|
|
let plusNum = Math.abs(e.target.value);
|
|
count = plusNum;
|
|
} else{
|
|
count = e.target.value;
|
|
}
|
|
setResultData((prevState) => ({
|
|
...prevState,
|
|
start_price: count,
|
|
}));
|
|
};
|
|
|
|
const handleReservationChange = {
|
|
start: (date) => {
|
|
setResultData(prev => ({ ...prev, resv_start_dt: date }));
|
|
},
|
|
end: (date) => {
|
|
setResultData(prev => ({ ...prev, resv_end_dt: date }));
|
|
}
|
|
};
|
|
|
|
const handleAuctionChange = {
|
|
start: (date) => {
|
|
setResultData(prev => ({ ...prev, auction_start_dt: date }));
|
|
},
|
|
end: (date) => {
|
|
setResultData(prev => ({ ...prev, auction_end_dt: date }));
|
|
}
|
|
};
|
|
|
|
const handleLand = e => {
|
|
const land_id = e.target.value;
|
|
const land = landData.find(land => land.id === parseInt(land_id));
|
|
const instance = buildingData.find(building => building.id === parseInt(land.buildingId))?.socket;
|
|
setSelectLand(land);
|
|
setResultData({ ...resultData, land_id: land_id, land_name: land.name, land_size: land.size, land_socket: instance });
|
|
}
|
|
|
|
const handleReset = () => {
|
|
setMessage_lang('KO')
|
|
setDetailData({});
|
|
setSelectLand(initLandData);
|
|
setResultData(initData);
|
|
setResetDateTime(true);
|
|
handleDetailView();
|
|
}
|
|
|
|
const handleSubmit = async (type, param = null) => {
|
|
switch (type) {
|
|
case "submit":
|
|
if (!checkCondition()) return;
|
|
|
|
const minAllowedTime = new Date(new Date().getTime() + 5 * 60000);
|
|
if (isView('recv') && resultData.resv_start_dt < minAllowedTime) {
|
|
showToast('LAND_AUCTION_MODEL_RESV_START_WARNING', {type: alertTypes.warning});
|
|
return;
|
|
}
|
|
if (resultData.auction_start_dt < minAllowedTime) {
|
|
showToast('LAND_AUCTION_MODEL_AUCTION_START_WARNING', {type: alertTypes.warning});
|
|
return;
|
|
}
|
|
if(resultData.resv_start_dt >= resultData.auction_start_dt || resultData.resv_start_dt >= resultData.auction_end_dt) {
|
|
showToast('LAND_AUCTION_MODEL_AUCTION_DIFF_RESERVATION', {type: alertTypes.warning});
|
|
return;
|
|
}
|
|
if(resultData.auction_start_dt >= resultData.auction_end_dt) {
|
|
showToast('LAND_AUCTION_MODEL_AUCTION_DIFF_AUCTION', {type: alertTypes.warning});
|
|
return;
|
|
}
|
|
const diffAuctionTime = resultData.auction_end_dt - resultData.auction_start_dt;
|
|
if(msToMinutes(diffAuctionTime) < AUCTION_MIN_MINUTE_TIME){
|
|
showToast('LAND_AUCTION_MODEL_MIN_TIME_WARNING', {type: alertTypes.warning});
|
|
return;
|
|
}
|
|
|
|
//화면에 머물면서 상태는 안바꼈을 경우가 있기에 경매시작시간 지났을경우 차단
|
|
if (modalType === TYPE_MODIFY && resultData.auction_start_dt < new Date()) {
|
|
showToast('LAND_AUCTION_MADEL_MODIFY_START', {type: alertTypes.warning});
|
|
return;
|
|
}
|
|
|
|
showModal(isView('modify') ? 'LAND_UPDATE_CONFIRM' : 'LAND_REGIST_CONFIRM', {
|
|
type: alertTypes.confirm,
|
|
onConfirm: () => handleSubmit('registConfirm')
|
|
});
|
|
|
|
break;
|
|
case "registConfirm":
|
|
setLoading(true);
|
|
|
|
if(isView('modify')){
|
|
await LandAuctionModify(token, content?.id, resultData).then(data => {
|
|
setLoading(false);
|
|
if(data.result === "SUCCESS") {
|
|
showToast('UPDATE_COMPLETED', {type: alertTypes.success});
|
|
}else if(data.result === "ERROR_AUCTION_STATUS_IMPOSSIBLE"){
|
|
showToast('LAND_AUCTION_ERROR_MODIFY_STATUS', {type: alertTypes.error});
|
|
}else{
|
|
showToast('UPDATE_FAIL', {type: alertTypes.error});
|
|
}
|
|
}).catch(reason => {
|
|
showToast('API_FAIL', {type: alertTypes.error});
|
|
}).finally(() => {
|
|
handleReset();
|
|
});
|
|
}
|
|
else{
|
|
await LandAuctionSingleRegist(token, resultData).then(data => {
|
|
setLoading(false);
|
|
if(data.result === "SUCCESS") {
|
|
showToast('REGIST_COMPLTE', {type: alertTypes.success});
|
|
}else if(data.result === "ERROR_LAND_AUCTION_IMPOSSIBLE"){
|
|
showToast('LAND_AUCTION_ERROR_PROGRESS', {type: alertTypes.error});
|
|
}else if(data.result === "ERROR_AUCTION_LAND_OWNER"){
|
|
showToast('LAND_AUCTION_ERROR_OWNER', {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.start_price > 0
|
|
&& resultData.auction_start_dt !== ''
|
|
&& resultData.auction_end_dt !== ''
|
|
&& resultData.resv_start_dt !== ''
|
|
&& resultData.resv_end_dt !== ''
|
|
&& resultData.land_id !== ''
|
|
);
|
|
};
|
|
|
|
const isView = (label) => {
|
|
switch (label) {
|
|
case "recv":
|
|
return modalType === TYPE_REGISTRY || (modalType === TYPE_MODIFY && content?.status === landAuctionStatusType.wait);
|
|
case "auction":
|
|
case "price":
|
|
case "message":
|
|
return modalType === TYPE_REGISTRY || (modalType === TYPE_MODIFY &&(content?.status === landAuctionStatusType.resv_start || content?.status === landAuctionStatusType.wait));
|
|
case "modify":
|
|
return modalType === TYPE_MODIFY && (content?.status === landAuctionStatusType.resv_start || content?.status === landAuctionStatusType.wait);
|
|
case "registry":
|
|
return modalType === TYPE_REGISTRY
|
|
default:
|
|
return modalType === TYPE_MODIFY && (content?.status === landAuctionStatusType.stl_end
|
|
|| content?.status === landAuctionStatusType.auction_start
|
|
|| content?.status === landAuctionStatusType.auction_end
|
|
|| content?.status === landAuctionStatusType.fail
|
|
|| content?.status === landAuctionStatusType.cancel
|
|
);
|
|
}
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<Modal min="760px" $view={detailView}>
|
|
<Title $align="center">{isView('registry') ? "랜드 경매 등록" : isView('modify') ? "랜드 경매 수정" : "랜드 경매 상세"}</Title>
|
|
<MessageWrapper>
|
|
<FormRowGroup>
|
|
<FormLabel>랜드선택</FormLabel>
|
|
<SelectInput value={resultData.land_id} onChange={e => handleLand(e)} disabled={!isView('registry')} width="400px">
|
|
{landData && landData.map((data, index) => (
|
|
<option key={index} value={data.id}>
|
|
{data.name}({data.id})
|
|
</option>
|
|
))}
|
|
</SelectInput>
|
|
</FormRowGroup>
|
|
<FormRowGroup>
|
|
<FormLabel>랜드 이름</FormLabel>
|
|
<FormInput
|
|
type="text"
|
|
disabled={true}
|
|
width='400px'
|
|
value={resultData?.land_name}
|
|
/>
|
|
</FormRowGroup>
|
|
<FormRowGroup>
|
|
<FormLabel>랜드 크기</FormLabel>
|
|
<FormInput
|
|
type="text"
|
|
disabled={true}
|
|
width='200px'
|
|
value={resultData?.land_size}
|
|
/>
|
|
<FormLabel>인스턴스 수</FormLabel>
|
|
<FormInput
|
|
type="text"
|
|
disabled={true}
|
|
width='200px'
|
|
value={resultData?.land_socket}
|
|
/>
|
|
</FormRowGroup>
|
|
|
|
<FormRowGroup>
|
|
<FormLabel>입찰 재화</FormLabel>
|
|
<SelectInput value={resultData.currency_type} width='200px' disabled={true} >
|
|
{CurrencyType.map((data, index) => (
|
|
<option key={index} value={data.value}>
|
|
{data.name}
|
|
</option>
|
|
))}
|
|
</SelectInput>
|
|
<FormLabel>입찰시작가</FormLabel>
|
|
<FormInput
|
|
type="number"
|
|
name="price"
|
|
value={resultData.start_price}
|
|
step={"0.01"}
|
|
min={0}
|
|
width='200px'
|
|
disabled={!isView('price')}
|
|
onChange={e => handleCount(e)}
|
|
/>
|
|
</FormRowGroup>
|
|
<DateTimeRangePicker
|
|
label="예약기간"
|
|
startDate={resultData.resv_start_dt}
|
|
endDate={resultData.resv_end_dt}
|
|
onStartDateChange={handleReservationChange.start}
|
|
onEndDateChange={handleReservationChange.end}
|
|
pastDate={new Date()}
|
|
disabled={!isView('recv')}
|
|
startLabel="시작 일자"
|
|
endLabel="종료 일자"
|
|
reset={resetDateTime}
|
|
/>
|
|
<DateTimeRangePicker
|
|
label="경매기간"
|
|
startDate={resultData.auction_start_dt}
|
|
endDate={resultData.auction_end_dt}
|
|
onStartDateChange={handleAuctionChange.start}
|
|
onEndDateChange={handleAuctionChange.end}
|
|
pastDate={new Date()}
|
|
disabled={!isView('auction')}
|
|
startLabel="시작 일자"
|
|
endLabel="종료 일자"
|
|
reset={resetDateTime}
|
|
/>
|
|
{!isView() && isNullValue && <SearchBarAlert $marginTop="25px" $align="right">{t('REQUIRED_VALUE_CHECK')}</SearchBarAlert>}
|
|
</MessageWrapper>
|
|
|
|
<BtnWrapper $gap="10px" $marginTop="10px">
|
|
<FormStatusBar>
|
|
<FormStatusLabel>
|
|
현재상태: {landAuctionStatus.find(data => data.value === content?.status)?.name || "등록"}
|
|
</FormStatusLabel>
|
|
<FormStatusWarning>
|
|
{isView('registry') ? '' : t('LAND_AUCTION_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>
|
|
|
|
{loading && <Loading/>}
|
|
</>
|
|
);
|
|
};
|
|
|
|
export const initData = {
|
|
land_id: '',
|
|
land_name: '',
|
|
land_size: '',
|
|
land_socket: '',
|
|
currency_type: 'Calium',
|
|
start_price: 0,
|
|
resv_start_dt: '',
|
|
resv_end_dt: '',
|
|
auction_start_dt: '',
|
|
auction_end_dt: ''
|
|
}
|
|
|
|
export const initLandData = {
|
|
land_id: 0,
|
|
name: '',
|
|
size: '',
|
|
socket: '',
|
|
desc: '',
|
|
open: false,
|
|
owner: ''
|
|
}
|
|
|
|
export default LandAuctionModal;
|
|
|