diff --git a/src/_redux/features/comn/message/messageState.ts b/src/_redux/features/comn/message/messageState.ts index 570dad4c..83222ce0 100644 --- a/src/_redux/features/comn/message/messageState.ts +++ b/src/_redux/features/comn/message/messageState.ts @@ -1,6 +1,8 @@ +import { ReactNode } from 'react'; + export interface IMsgState { header: string; - body: string; + body: string | ReactNode; isOpen: boolean; isHistoryBack: boolean; isRefresh: boolean; diff --git a/src/components/account/find/AccountFindPassword.js b/src/components/account/find/AccountFindPassword.js index 6291c9c7..0e8ec92e 100644 --- a/src/components/account/find/AccountFindPassword.js +++ b/src/components/account/find/AccountFindPassword.js @@ -155,10 +155,6 @@ export const AccountFindPassword = props => { }; const handlerConfirm = async () => { - const modalHeader = { - send: '인증번호 발송', - confirm: '인증번호 인증' - }; if (!inputId) { handlerOpenModal(MODAL_HEADER.crtfyhp, '아이디를' + MODAL_BODY.valid); return; diff --git a/src/components/laanc/LaancQr.js b/src/components/laanc/LaancQr.js index f49251f3..7b2bcd4a 100644 --- a/src/components/laanc/LaancQr.js +++ b/src/components/laanc/LaancQr.js @@ -1,18 +1,16 @@ import { useEffect, useState, useRef } from 'react'; import { ModalHeader, ModalBody, ModalFooter, Button } from '@component/ui'; -import ErrorModal from '../../components/modal/ErrorModal'; import axios from '../../modules/utils/customAxiosUtil'; import { checkLaancTsQr } from '@src/_redux/features/laanc/laancThunk'; import { useDispatch, useSelector } from '@store/storeConfig/store'; +import { openModal } from '@src/_redux/features/comn/message/messageSlice'; +import { MODAL_BODY, MODAL_CRTFYHP, MODAL_HEADER } from '@src/configs/msgConst'; // 이제 handleUserEvent는 300ms 동안 추가 호출이 없을 때만 실행됩니다. export default function LaancQr({ isPopUp, setIsPopUp, data, handlerStep }) { + const dispatch = useDispatch(); + const [isPolling, setIsPolling] = useState(true); - const [isErrorModal, setIsErrorModal] = useState({ - isOpen: false, - title: '', - desc: '' - }); const pollingIntervalRef = useRef(null); // 언마운트시 폴링 중지 @@ -59,11 +57,7 @@ export default function LaancQr({ isPopUp, setIsPopUp, data, handlerStep }) { setIsPopUp(false); handlerStep(2); } else if (res.data.errorCode === 'QR001') { - setIsErrorModal({ - isOpen: true, - title: '인증 만료', - desc: <>인증 시간이 만료되었습니다. - }); + dispatch(openModal({ header: '인증 만료', body: MODAL_CRTFYHP.expire })); setIsPopUp(false); } // else if (type === 'user') { @@ -74,12 +68,7 @@ export default function LaancQr({ isPopUp, setIsPopUp, data, handlerStep }) { // axios 호출 에러 처리 로직 const handleError = error => { - console.log('>>', error); - setIsErrorModal({ - isOpen: true, - title: '오류', - desc: <>처리중 오류가 발생하였습니다 - }); + dispatch(openModal({ header: MODAL_HEADER.error, body: MODAL_BODY.error })); }; // 사용자 확인 버튼 헨들러 @@ -117,7 +106,6 @@ export default function LaancQr({ isPopUp, setIsPopUp, data, handlerStep }) { QR코드 스캔 후 드론자격증명 앱을통해 유효성 검사 진행 부탁드립니다.{' '}

- ); } diff --git a/src/components/laanc/map/FlightArea.js b/src/components/laanc/map/FlightArea.js index 9ff4a263..5d6d2dd2 100644 --- a/src/components/laanc/map/FlightArea.js +++ b/src/components/laanc/map/FlightArea.js @@ -47,6 +47,7 @@ import gimpo from '../../map/geojson/gimpoAirportAirArea.json'; import threebox from 'threebox-plugin'; import { initFlightBasState } from '@src/_redux/features/laanc/laancState'; +import { openModal } from '@src/_redux/features/comn/message/messageSlice'; const LaancAreaMap = lazy(() => import('./LaancAreaMap')); @@ -57,6 +58,7 @@ const FeatureAirZone = lazy(() => import('../../map/mapbox/feature/FeatureAirZone') ); const LaancDrawModal = lazy(() => import('./LaancDrawModal')); + export default function FlightArea({ centeredModal, setCenteredModal, @@ -86,7 +88,7 @@ export default function FlightArea({ // 날씨 모달 const [formModal, setFormModal] = useState(false); - // 비행구역 설정 관련 모달 + // 특별비행신청 모달(드론 원스톱 바로가기 기능) const [modal, setModal] = useState({ title: '', desc: '', @@ -135,7 +137,7 @@ export default function FlightArea({ }, [areaCoordList, centeredModal, previewLayer]); /** - * 비행구역 설정 관련 모달 표출 + * 특별비행신청 모달 표출 */ const handlerModal = () => { setModal(!modal); @@ -147,17 +149,18 @@ export default function FlightArea({ */ const handlerDrawType = val => { if (drawObj.getMode().includes('draw')) { - setModal({ - title: '비행 구역 설정', - desc: ( - <> - 비행구역 설정이 완료되지 않았습니다. -
- 비행구역 설정 완료 후 타입 변경 부탁드립니다. - - ), - isOpen: true - }); + dispatch( + openModal({ + header: '비행 구역 설정', + body: ( + <> + 비행구역 설정이 완료되지 않았습니다. +
+ 비행구역 설정 완료 후 타입 변경 부탁드립니다. + + ) + }) + ); } else { dispatch(clientDrawTypeChange(val)); } @@ -516,6 +519,7 @@ export default function FlightArea({ ) : null} {page === 1 ? ( + // 비행구역 설정 모달 { @@ -625,6 +629,7 @@ export default function FlightArea({ ) : null} + {/* 날씨 모달 */} import('./LaancMapSearch')); const FeatureAirZone = lazy(() => @@ -220,7 +222,12 @@ export default function LaancAreaMap({ */ const handlerConfirm = areaList => { if (areaList === undefined) { - alert('영역을 설정해 주세요.'); + dispatch( + openModal({ + header: MODAL_HEADER.error, + body: '영역을 설정해 주세요.' + }) + ); return; } diff --git a/src/components/laanc/map/LaancDrawControl.js b/src/components/laanc/map/LaancDrawControl.js index ab0cac74..18c0c87a 100644 --- a/src/components/laanc/map/LaancDrawControl.js +++ b/src/components/laanc/map/LaancDrawControl.js @@ -20,6 +20,8 @@ import axios from '../../../modules/utils/customAxiosUtil'; import createSupplementaryPointsForCircle from 'mapbox-gl-draw-circle/lib/utils/create_supplementary_points_circle'; import createSupplementaryPoints from 'mapbox-gl-draw-circle/node_modules/@mapbox/mapbox-gl-draw/src/lib/create_supplementary_points'; import Constants from 'mapbox-gl-draw-circle/node_modules/@mapbox/mapbox-gl-draw/src/constants'; +import { openModal } from '@src/_redux/features/comn/message/messageSlice'; +import { MODAL_BODY, MODAL_HEADER } from '@src/configs/msgConst'; const ErrorModal = lazy(() => import('../../modal/ErrorModal')); export default function LaancDrawControl(props) { @@ -44,13 +46,6 @@ export default function LaancDrawControl(props) { // 지도 렌더 횟수 const [number, setNumber] = useState(0); - // 에러 모달창 정보 - const [isErrorModal, setIsErrorModal] = useState({ - isOpen: false, - title: '', - desc: '' - }); - // 비행구역 타입 변경에 따른 그리기모드 셋팅 useEffect(() => { if (drawType === 'DONE') { @@ -274,11 +269,12 @@ export default function LaancDrawControl(props) { // 좌표 최소 개수 체크 if (pointLength < minPoint) { - props.setModal({ - title: '좌표 최소 개수', - desc: <>좌표를 {desc} 개 점으로 이어주세요., - isOpen: true - }); + dispatch( + openModal({ + header: '좌표 최소 개수', + body: <>좌표를 {desc} 개 점으로 이어주세요. + }) + ); handlerRemoveError(obj.id); return; } @@ -359,28 +355,28 @@ export default function LaancDrawControl(props) { } if (elev1.data[0] === 0 || elev2.length > 0) isBreak = true; } catch (error) { - { - setIsErrorModal({ - isOpen: true, - title: '오류', - desc: '처리중 오류가 발생하였습니다' - }); - } + dispatch( + openModal({ + header: MODAL_HEADER.error, + body: MODAL_BODY.error + }) + ); return; } if (isBreak) { - props.setModal({ - title: '비행 불가 지역', - desc: ( - <> - 설정하신 비행구역 중 허용고도가 0m인 구역이 있습니다. -
- 비행구역 설정 시 허용고도를 다시 확인해주시기 바랍니다. - - ), - isOpen: true - }); + dispatch( + openModal({ + header: '비행 불가 지역', + body: ( + <> + 설정하신 비행구역 중 허용고도가 0m인 구역이 있습니다. +
+ 비행구역 설정 시 허용고도를 다시 확인해주시기 바랍니다. + + ) + }) + ); handlerRemoveError(id); return; } else { @@ -411,6 +407,7 @@ export default function LaancDrawControl(props) { } if (isBreak) { + // 드론원스톱 버튼 있음. props.setModal({ title: '특별 비행 신청', desc: ( @@ -860,11 +857,5 @@ export default function LaancDrawControl(props) { } }; - return ( - <> - - - - - ); + return null; } diff --git a/src/components/laanc/step/LaancStep1.js b/src/components/laanc/step/LaancStep1.js index e83d317e..212a040d 100644 --- a/src/components/laanc/step/LaancStep1.js +++ b/src/components/laanc/step/LaancStep1.js @@ -1,4 +1,4 @@ -import React, { useEffect, useState, useRef, lazy, Suspense } from 'react'; +import { useEffect, useState, useRef, lazy, Suspense } from 'react'; import { useLocation } from 'react-router-dom'; import { useDispatch, useSelector } from '@store/storeConfig/store'; import Flatpickr from 'react-flatpickr'; @@ -25,12 +25,12 @@ import { Modal, Popover } from '@component/ui'; +import { openModal } from '@src/_redux/features/comn/message/messageSlice'; +import { MODAL_BODY, MODAL_HEADER } from '@src/configs/msgConst'; const LaancModal = lazy(() => import('../LaancModal')); const LaancQr = lazy(() => import('../../../components/laanc/LaancQr')); const FlightArea = lazy(() => import('../map/FlightArea')); -const ErrorModal = lazy(() => import('../../modal/ErrorModal')); -const InfoModal = lazy(() => import('../../modal/InfoModal')); export default function LaancStep1({ detailData, setDetailData, @@ -72,16 +72,6 @@ export default function LaancStep1({ const [popoverSchFltEndDt, setPopoverSchFltEndDt] = useState(false); // 모달 - const [isErrorModal, setIsErrorModal] = useState({ - isOpen: false, - title: '', - desc: '' - }); - const [isInfoModal, setIsInfoModal] = useState({ - isOpen: false, - title: '', - desc: '' - }); const [isLaancModal, setIsLaancModal] = useState({ isOpen: false, title: '', @@ -123,20 +113,17 @@ export default function LaancStep1({ maxElev; if (controlledAltitudeExceededWarning) { - setIsErrorModal({ - isOpen: true, - title: '검토 결과 사전안내', - desc: ( - <> - 유효성 검사에 실패하여 미 승인 대상입니다. -
- 제출하신 비행계획서의 고도는 {laancElev[0]}m이하에서만 비행이 - 가능합니다. -
- 고도 설정을 다시 확인해주시기 바랍니다. - - ) - }); + handlerOpenModal( + '검토 결과 사전안내', + <> + 유효성 검사에 실패하여 미 승인 대상입니다. +
+ 제출하신 비행계획서의 고도는 {laancElev[0]}m이하에서만 비행이 + 가능합니다. +
+ 고도 설정을 다시 확인해주시기 바랍니다. + + ); handleChange({ type: 'area', name: 'fltElev', @@ -146,6 +133,16 @@ export default function LaancStep1({ } }, [[laancElev]]); + // 단순 메시지 표출 모달 + const handlerOpenModal = (header, body) => { + dispatch( + openModal({ + header: header, + body: body + }) + ); + }; + // 비행계획서 작성 핸들러 const handleChange = ({ name, value, type, index, pIndex }) => { const arrName = `${type}List`; @@ -264,124 +261,81 @@ export default function LaancStep1({ detailData.arcrftList[0].arcrftWghtCd == '11'); if (!detailData.fltType) { - setIsErrorModal({ - isOpen: true, - title: '필수값 입력 오류', - desc: '비행 종류(상업/비상업)를 선택해주세요.' - }); + handlerOpenModal( + MODAL_HEADER.valid, + '비행 종류(상업/비상업)를 선택해 주세요.' + ); return false; } else if ( !schFltStDt.isAfter(currentDate) || !schFltEndDt.isAfter(currentDate) ) { - setIsErrorModal({ - isOpen: true, - title: '필수값 입력 오류', - desc: '비행 일자가 이미 지난 일자입니다.' - }); + handlerOpenModal(MODAL_HEADER.valid, '비행 일자가 이미 지난 일자입니다.'); return false; } else if (schFltStDt.isAfter(schFltEndDt)) { - setIsErrorModal({ - isOpen: true, - title: '필수값 입력 오류', - desc: '비행일자를 확인해주세요.' - }); + handlerOpenModal(MODAL_HEADER.valid, '비행일자를 확인해 주세요.'); return false; } else if (schFltStDt.format('A h:mm') === 'PM 11:00') { - setIsErrorModal({ + setIsLaancModal({ isOpen: true, - title: '특별 비행', + title: '특별 비행 신청', desc: ( <> - 야간 비행은 특별 비행에 해당됩니다. + 야간 비행 신청의 경우 특별 비행 신청을 진행하셔야 합니다.
- 특별 비행의 경우 드론원스톱을 통해서 신청해주시기 바랍니다. + 드론원스톱을 통해서 신청해 주시기 바랍니다. - ) + ), + type: '드론원스톱 바로가기', + url: 'https://drone.onestop.go.kr/' }); return false; } else if (schFltStDt.format('A h:mm') === 'PM 5:00') { - setIsErrorModal({ - isOpen: true, - title: '비행구역 및 비행일자 중복', - desc: ( - <> - 설정하신 비행구역 및 비행시간에 이미 승인완료된 신청건이 있습니다. -
다시 설정 부탁드립니다. - - ) - }); + handlerOpenModal( + '비행구역 및 비행일자 중복', + <> + 설정하신 비행구역 및 비행시간에 이미 승인완료된 신청건이 있습니다. +
다시 설정 부탁드립니다. + + ); return false; } else if (!detailData.fltPurpose) { - setIsErrorModal({ - isOpen: true, - title: '필수값 입력 오류', - desc: '비행목적을 선택해 주세요.' - }); - + handlerOpenModal(MODAL_HEADER.valid, '비행목적을 선택해 주세요.'); return false; } else if ( !detailData.areaList[0].fltElev || detailData.areaList[0].fltElev === 0 ) { - setIsErrorModal({ - isOpen: true, - title: '필수값 입력 오류', - desc: '고도를 입력해 주세요.' - }); - + handlerOpenModal(MODAL_HEADER.valid, '고도를 입력해 주세요.'); return false; } else if (!detailData.areaList[0].bufferZone) { - setIsErrorModal({ - isOpen: true, - title: '필수값 입력 오류', - desc: '반경을 입력해 주세요.' - }); - + handlerOpenModal(MODAL_HEADER.valid, '반경을 입력해 주세요.'); return false; } else if ( detailData.areaList[0].concatBufferZone != detailData.areaList[0].bufferZone && detailData.areaList[0].areaType === 'LINE' ) { - setIsErrorModal({ - isOpen: true, - title: '필수값 입력 오류', - desc: <>적용 버튼을 누르지 않고 값을 변경 할 수 없습니다. - }); + handlerOpenModal( + MODAL_HEADER.valid, + '적용 버튼을 누르지 않고 값을 변경 할 수 없습니다.' + ); } else if (!detailData.areaList[0].fltMethod) { - setIsErrorModal({ - isOpen: true, - title: '필수값 입력 오류', - desc: '비행방식를 입력해 주세요.' - }); - + handlerOpenModal(MODAL_HEADER.valid, '비행방식을 입력해 주세요.'); return false; } else if ( detailData.areaList[0].fltMethod === '00' && !detailData.areaList[0].fltMothoeRm ) { // 비행 방식 직접 입력칸 활성화 후 작성 시 조건문 - setIsErrorModal({ - isOpen: true, - title: '필수값 입력 오류', - desc: '비행방식을 입력해 주세요.' - }); + handlerOpenModal(MODAL_HEADER.valid, '비행방식을 입력해 주세요.'); return false; } else if (validateAircraftWeightCode) { - setIsErrorModal({ - isOpen: true, - title: '필수값 입력 오류', - desc: '기체 종류를 입력해 주세요.' - }); + handlerOpenModal(MODAL_HEADER.valid, '기체 종류를 입력해 주세요.'); return false; } else if (validateidntfNumCode) { - setIsErrorModal({ - isOpen: true, - title: '필수값 입력 오류', - desc: '기체 신고 번호를 입력해 주세요.' - }); + handlerOpenModal(MODAL_HEADER.valid, '기체 신고 번호를 입력해 주세요.'); return false; } else { handlerLaanc(); @@ -407,27 +361,18 @@ export default function LaancStep1({ detailData.areaList ); if (elev.data[0] === 0) { - setIsErrorModal({ - title: '비행 불가 지역', - desc: ( - <> - 설정하신 비행구역 중 허용고도가 0m인 구역이 있습니다. -
- 버퍼존을 다시 확인해주시기 바랍니다. - - ), - isOpen: true - }); + handlerOpenModal( + '비행 불가 지역', + <> + 설정하신 비행구역 중 허용고도가 0m인 구역이 있습니다. +
+ 버퍼존을 다시 확인해주시기 바랍니다. + + ); } dispatch(laancAltitudeData.success(elev.data)); } catch (error) { - { - setIsErrorModal({ - isOpen: true, - title: '오류', - desc: '처리중 오류가 발생하였습니다' - }); - } + handlerOpenModal(MODAL_HEADER.error, MODAL_BODY.error); } } } @@ -455,11 +400,10 @@ export default function LaancStep1({ value: 0 }); fltElevRef.current.blur(); - setIsErrorModal({ - isOpen: true, - title: '비행 구역 설정', - desc: '비행 구역 설정을 먼저 설정 해 주세요' - }); + handlerOpenModal( + '비행 구역 설정', + '비행 구역 설정을 먼저 설정 해 주세요.' + ); return false; } break; @@ -497,11 +441,10 @@ export default function LaancStep1({ // 날짜 선택 핸들러 const handleOpenFlatpickr = () => { if (detailData.areaList[0].coordList[0].lat === 0) { - setIsErrorModal({ - isOpen: true, - title: '비행 구역 설정', - desc: '비행 구역 설정을 먼저 설정 해 주세요' - }); + handlerOpenModal( + '비행 구역 설정', + '비행 구역 설정을 먼저 설정 해 주세요.' + ); closeFlatpickr(); return false; } @@ -546,33 +489,27 @@ export default function LaancStep1({ !laancArea?.duplicated && parseInt(value.replace('/^0+/', 'm', ''), 10) <= maxElev ) { - setIsErrorModal({ - isOpen: true, - title: '고도 재설정 알림', - desc: ( - <> - 관제권 및 비행금지 공역을 제외한 지역에서는 주간에 150m이하 -
- 고도에서는 비행승인없이 비행가능합니다. - - ) - }); + handlerOpenModal( + '고도 재설정 알림', + <> + 관제권 및 비행금지 공역을 제외한 지역에서는 주간에 150m이하 +
+ 고도에서는 비행승인없이 비행가능합니다. + + ); } if (controlledAltitudeExceededWarning) { - setIsErrorModal({ - isOpen: true, - title: '검토 결과 사전안내', - desc: ( - <> - 유효성 검사에 실패하여 미 승인 대상입니다. -
- 제출하신 비행계획서의 고도는 {laancElev[0]}m이하에서만 비행이 - 가능합니다. -
- 고도 설정을 다시 확인해주시기 바랍니다. - - ) - }); + handlerOpenModal( + '검토 결과 사전안내', + <> + 유효성 검사에 실패하여 미 승인 대상입니다. +
+ 제출하신 비행계획서의 고도는 {laancElev[0]}m이하에서만 비행이 + 가능합니다. +
+ 고도 설정을 다시 확인해주시기 바랍니다. + + ); handleChange({ type: 'area', name: 'fltElev', @@ -613,20 +550,17 @@ export default function LaancStep1({ const maxElev = 150; if (laancNotRequired) { - setIsErrorModal({ - isOpen: true, - title: '검토 결과 사전안내', - desc: ( - <> - 검토 결과 미 승인 대상입니다. -

- 제줄하신 비행계획서는 별도의 승인이 필요없습니다. -
- 조종자 준수사항에 유의하여 비행하시기 바랍니다. -

- - ) - }); + handlerOpenModal( + '검토 결과 사전안내', + <> + 검토 결과 미 승인 대상입니다. +

+ 제줄하신 비행계획서는 별도의 승인이 필요없습니다. +
+ 조종자 준수사항에 유의하여 비행하시기 바랍니다. +

+ + ); return; } else if (detailData.areaList[0].fltMethod === '군집비행') { handleChange({ @@ -673,11 +607,7 @@ export default function LaancStep1({ // setIsPopUp(true); 잠시 주석 return; } catch (error) { - setIsErrorModal({ - isOpen: true, - title: '오류', - desc: <>처리중 오류가 발생하였습니다 - }); + handlerOpenModal(MODAL_HEADER.error, MODAL_BODY.error); } } } @@ -1375,8 +1305,6 @@ export default function LaancStep1({ /> */}
- - diff --git a/src/components/laanc/step/LaacnStep3.js b/src/components/laanc/step/LaancStep3.js similarity index 99% rename from src/components/laanc/step/LaacnStep3.js rename to src/components/laanc/step/LaancStep3.js index 30960f45..cd8cd48d 100644 --- a/src/components/laanc/step/LaacnStep3.js +++ b/src/components/laanc/step/LaancStep3.js @@ -19,7 +19,7 @@ import { HOST } from '../../../configs/constants'; pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`; const FlightArea = lazy(() => import('../map/FlightArea')); -export default function LaacnStep3({ +export default function LaancStep3({ disabledAnimation, data, setDisabledAnimation, diff --git a/src/configs/msgConst.ts b/src/configs/msgConst.ts index 927c4ecd..020cc38a 100644 --- a/src/configs/msgConst.ts +++ b/src/configs/msgConst.ts @@ -1,7 +1,7 @@ // 인증번호 모달 메시지 export const MODAL_CRTFYHP = { send: '인증번호를 발송하였습니다.', - expire: '인증번호가 만료되었습니다.', + expire: '인증시간이 만료되었습니다.', confirm: '인증되었습니다.', failed: '인증번호가 잘못되었습니다.', valid: '인증번호를 입력해주세요.', @@ -23,6 +23,6 @@ export const MODAL_BODY = { save: '저장을 완료하였습니다.', delete: '삭제를 완료하였습니다.', confirm: '확인이 완료되었습니다.', - valid: ' 입력해주세요.', + valid: ' 입력해 주세요.', failed: ' 실패하였습니다.' }; diff --git a/src/containers/account/mypage/AccountMypageContainer.js b/src/containers/account/mypage/AccountMypageContainer.js index d2f8c1d6..f205b2e7 100644 --- a/src/containers/account/mypage/AccountMypageContainer.js +++ b/src/containers/account/mypage/AccountMypageContainer.js @@ -154,10 +154,7 @@ const AccountMypageContainer = () => { return; } if (sendCount >= 3) { - handlerOpenModal( - MODAL_HEADER.crtfyhp, - '인증번호 발송은 3회까지만 가능합니다.' - ); + handlerOpenModal(MODAL_HEADER.crtfyhp, MODAL_CRTFYHP.count); return; } if (inputHpno.length < 11) { diff --git a/src/containers/laanc/LaancPlanContainer.js b/src/containers/laanc/LaancPlanContainer.js index 9edca883..103db416 100644 --- a/src/containers/laanc/LaancPlanContainer.js +++ b/src/containers/laanc/LaancPlanContainer.js @@ -8,7 +8,7 @@ import { clientDrawTypeChange } from '@src/_redux/features/control/map/mapSlice' const LaancStep1 = lazy(() => import('../../components/laanc/step/LaancStep1')); const LaancStep2 = lazy(() => import('../../components/laanc/step/LaancStep2')); -const LaancStep3 = lazy(() => import('../../components/laanc/step/LaacnStep3')); +const LaancStep3 = lazy(() => import('../../components/laanc/step/LaancStep3')); const ErrorModal = lazy(() => import('../../components/modal/ErrorModal')); export default function LaancPlanContainer({