|
|
|
@ -1,85 +1,78 @@
|
|
|
|
|
import { useCallback, useEffect, useLayoutEffect, useState } from 'react'; |
|
|
|
|
import { useSelector, useDispatch } from 'react-redux'; |
|
|
|
|
import { Button, Nav, NavItem, NavLink, TabContent, TabPane } from 'reactstrap'; |
|
|
|
|
import { Button, TabContent, TabPane } from 'reactstrap'; |
|
|
|
|
import AppCollapse from '@components/app-collapse'; |
|
|
|
|
import { LIST } from '../../../modules/cstmrService/faq/action'; |
|
|
|
|
import { |
|
|
|
|
LIST, |
|
|
|
|
INSERT, |
|
|
|
|
UPDATE, |
|
|
|
|
DELETE |
|
|
|
|
} from '../../../modules/cstmrService/faq/action'; |
|
|
|
|
import FaqSearchBox from '../../../components/cstmrService/faq/FaqSearchBox'; |
|
|
|
|
import FaqForm from '../../../components/cstmrService/faq/FaqForm'; |
|
|
|
|
|
|
|
|
|
const data = [ |
|
|
|
|
import FaqTab from '../../../components/cstmrService/faq/FaqTab'; |
|
|
|
|
import { ErrorModal } from '../../../components/modal/ErrorModal'; |
|
|
|
|
import { InfoModal } from '../../../components/modal/InfoModal'; |
|
|
|
|
import { ConfirmModal } from '../../../components/modal/ConfirmModal'; |
|
|
|
|
const tabList = [ |
|
|
|
|
{ |
|
|
|
|
title: ( |
|
|
|
|
<div className='faq-q'> |
|
|
|
|
<h5> |
|
|
|
|
<span className='faq-icon-q'>Q</span> |
|
|
|
|
<span className='ti'> |
|
|
|
|
<span>[장치신고]</span>드론을 구매했는데 기체신고를 해야하나요? |
|
|
|
|
</span> |
|
|
|
|
</h5> |
|
|
|
|
<div> |
|
|
|
|
<Button.Ripple color='flat-primary'>수정하기</Button.Ripple> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
), |
|
|
|
|
content: ( |
|
|
|
|
<div className='faq-a'> |
|
|
|
|
<span className='faq-icon-a'>A</span> |
|
|
|
|
<span className='faq-a-text'> |
|
|
|
|
{/* br처리? 줄바꿈.. 추후에 생각 */} |
|
|
|
|
네 그렇습니다. |
|
|
|
|
<br /> |
|
|
|
|
<br /> |
|
|
|
|
- 사용용도가 영리 목적인 경우 : 무게에 상관없이 모두 신고 |
|
|
|
|
<br /> |
|
|
|
|
- 사용용도가 비영리 목적인 경우 |
|
|
|
|
<br /> |
|
|
|
|
· (무인멀티콥터, 무인비행기, 무인헬리콥터) 최대이륙중량 2kg 초과 시 |
|
|
|
|
신고 |
|
|
|
|
<br /> |
|
|
|
|
· (무인비행선) 연료의 무게를 제외한 자체무게가 12kg 초과, 길이 7m 초과 |
|
|
|
|
시 신고 <br /> |
|
|
|
|
</span> |
|
|
|
|
</div> |
|
|
|
|
) |
|
|
|
|
title: '전체', |
|
|
|
|
value: '전체' |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
title: ( |
|
|
|
|
<div className='faq-q'> |
|
|
|
|
<h5> |
|
|
|
|
<span className='faq-icon-q'>Q</span> |
|
|
|
|
<span className='ti'> |
|
|
|
|
<span>[비행승인]</span>실내에서 비행할 때에도 비행승인을 받아야 |
|
|
|
|
할까? |
|
|
|
|
</span> |
|
|
|
|
</h5> |
|
|
|
|
<div> |
|
|
|
|
<Button.Ripple color='flat-primary'>수정하기</Button.Ripple> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
), |
|
|
|
|
content: ( |
|
|
|
|
<div className='faq-a'> |
|
|
|
|
<span className='faq-icon-a'>A</span> |
|
|
|
|
<span className='faq-a-text'> |
|
|
|
|
사방/천장이 막혀있는 밀폐된 실내 공간에서의 비행은 승인을 필요로 하지 |
|
|
|
|
않습니다. 또한, 적절한 조명장치가 있는 실내 공간이라면 야간에도 비행이 |
|
|
|
|
가능합니다. 다면 어떠한 경우에도 인명과 재산에 위험을 초래할 우려가 |
|
|
|
|
없도록 주의하여 비행하여야 합니다. |
|
|
|
|
</span> |
|
|
|
|
</div> |
|
|
|
|
) |
|
|
|
|
title: '장치 신고', |
|
|
|
|
value: '장치신고' |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
title: '사업 등록', |
|
|
|
|
value: '사업등록' |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
title: '비행 승인', |
|
|
|
|
value: '비행승인' |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
title: '항공 촬영', |
|
|
|
|
value: '항공촬영' |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
title: '기타', |
|
|
|
|
value: '기타' |
|
|
|
|
} |
|
|
|
|
]; |
|
|
|
|
|
|
|
|
|
const initFormData = { |
|
|
|
|
category: '장치신고', |
|
|
|
|
content: '', |
|
|
|
|
expsrYn: 'Y', |
|
|
|
|
title: '', |
|
|
|
|
faqSno: 0 |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
export default function FaqContainer() { |
|
|
|
|
// ** States & Vars
|
|
|
|
|
const [activeTab, setActiveTab] = useState('전체'); |
|
|
|
|
const { user } = useSelector(state => state.authState); |
|
|
|
|
const [searchText, setSearchText] = useState(''); |
|
|
|
|
|
|
|
|
|
// ** Function to toggle tabs
|
|
|
|
|
const toggle = tab => setActiveTab(tab); |
|
|
|
|
const [formData, setFormData] = useState(initFormData); |
|
|
|
|
const [formMode, setFormMode] = useState('create'); |
|
|
|
|
const [isOpenFormModal, setIsOpenFormModal] = useState(false); |
|
|
|
|
const [validationModal, setValidationModal] = useState({ |
|
|
|
|
errorType: { |
|
|
|
|
isOpen: false, |
|
|
|
|
desc: '', |
|
|
|
|
title: '필수값 입력 오류' |
|
|
|
|
}, |
|
|
|
|
successType: { |
|
|
|
|
isOpen: false, |
|
|
|
|
desc: '', |
|
|
|
|
title: '필수값 입력 오류' |
|
|
|
|
}, |
|
|
|
|
confirmType: { |
|
|
|
|
isOpen: false, |
|
|
|
|
desc: '', |
|
|
|
|
title: '필수값 입력 오류' |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const dispatch = useDispatch(); |
|
|
|
|
const { faqList } = useSelector(state => state.faqState); |
|
|
|
@ -110,9 +103,128 @@ export default function FaqContainer() {
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const handlerOpenFormModal = () => { |
|
|
|
|
setFormData(initFormData); |
|
|
|
|
setIsOpenFormModal(!isOpenFormModal); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const handlerChangeTab = useCallback( |
|
|
|
|
val => { |
|
|
|
|
setActiveTab(val); |
|
|
|
|
}, |
|
|
|
|
[activeTab] |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
const handlerChangeFormData = useCallback( |
|
|
|
|
(type, val) => { |
|
|
|
|
setFormData({ |
|
|
|
|
...formData, |
|
|
|
|
[type]: val |
|
|
|
|
}); |
|
|
|
|
}, |
|
|
|
|
[formData] |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
const handlerSubmitForm = () => { |
|
|
|
|
if (!formData.title) { |
|
|
|
|
setValidationModal({ |
|
|
|
|
...validationModal, |
|
|
|
|
errorType: { |
|
|
|
|
...validationModal.errorType, |
|
|
|
|
isOpen: true, |
|
|
|
|
desc: '제목을 입력해주세요.' |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!formData.content) { |
|
|
|
|
setValidationModal({ |
|
|
|
|
...validationModal, |
|
|
|
|
errorType: { |
|
|
|
|
...validationModal.errorType, |
|
|
|
|
isOpen: true, |
|
|
|
|
desc: '내용을 입력해주세요.' |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (formMode === 'create') { |
|
|
|
|
dispatch( |
|
|
|
|
INSERT.request({ |
|
|
|
|
search: { |
|
|
|
|
category: activeTab, |
|
|
|
|
word: searchText |
|
|
|
|
}, |
|
|
|
|
form: { |
|
|
|
|
...formData |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
); |
|
|
|
|
} else { |
|
|
|
|
dispatch( |
|
|
|
|
UPDATE.request({ |
|
|
|
|
search: { |
|
|
|
|
category: activeTab, |
|
|
|
|
word: searchText |
|
|
|
|
}, |
|
|
|
|
form: { |
|
|
|
|
...formData |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
setIsOpenFormModal(false); |
|
|
|
|
setFormData(initFormData); |
|
|
|
|
setValidationModal({ |
|
|
|
|
...validationModal, |
|
|
|
|
successType: { |
|
|
|
|
title: formMode === 'create' ? '등록' : '수정', |
|
|
|
|
isOpen: true, |
|
|
|
|
desc: `${formMode === 'create' ? '등록' : '수정'}되었습니다.` |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const handlerFaqModify = val => { |
|
|
|
|
setFormMode('update'); |
|
|
|
|
setFormData({ |
|
|
|
|
...formData, |
|
|
|
|
category: val.category, |
|
|
|
|
content: val.content, |
|
|
|
|
expsrYn: val.expsrYn, |
|
|
|
|
title: val.title, |
|
|
|
|
faqSno: val.faqSno |
|
|
|
|
}); |
|
|
|
|
setIsOpenFormModal(true); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const handlerDeleteConfirmFaq = () => { |
|
|
|
|
setValidationModal({ |
|
|
|
|
...validationModal, |
|
|
|
|
confirmType: { |
|
|
|
|
isOpen: true, |
|
|
|
|
title: '삭제', |
|
|
|
|
desc: '정말 삭제하시겠습니까?' |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const handlerDeleteFaq = () => { |
|
|
|
|
dispatch( |
|
|
|
|
DELETE.request({ |
|
|
|
|
search: { |
|
|
|
|
category: activeTab, |
|
|
|
|
word: searchText |
|
|
|
|
}, |
|
|
|
|
faqSno: formData.faqSno |
|
|
|
|
}) |
|
|
|
|
); |
|
|
|
|
setIsOpenFormModal(false); |
|
|
|
|
setFormData(initFormData); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const handlerFaqList = () => { |
|
|
|
|
if (faqList?.length <= 0 || !faqList) return []; |
|
|
|
|
return faqList.map(i => { |
|
|
|
@ -126,9 +238,16 @@ export default function FaqContainer() {
|
|
|
|
|
{i.title} |
|
|
|
|
</span> |
|
|
|
|
</h5> |
|
|
|
|
<div> |
|
|
|
|
<Button.Ripple color='flat-primary'>수정하기</Button.Ripple> |
|
|
|
|
</div> |
|
|
|
|
{user?.authId !== 'USER' && ( |
|
|
|
|
<div> |
|
|
|
|
<Button.Ripple |
|
|
|
|
color='flat-primary' |
|
|
|
|
onClick={() => handlerFaqModify(i)} |
|
|
|
|
> |
|
|
|
|
수정하기 |
|
|
|
|
</Button.Ripple> |
|
|
|
|
</div> |
|
|
|
|
)} |
|
|
|
|
</div> |
|
|
|
|
), |
|
|
|
|
content: ( |
|
|
|
@ -156,7 +275,10 @@ export default function FaqContainer() {
|
|
|
|
|
className='faq-admin-plus' |
|
|
|
|
outline |
|
|
|
|
color='primary' |
|
|
|
|
onClick={() => setIsOpenFormModal(!isOpenFormModal)} |
|
|
|
|
onClick={() => { |
|
|
|
|
setFormMode('create'); |
|
|
|
|
setIsOpenFormModal(!isOpenFormModal); |
|
|
|
|
}} |
|
|
|
|
> |
|
|
|
|
질문 등록하기 |
|
|
|
|
</Button> |
|
|
|
@ -164,58 +286,11 @@ export default function FaqContainer() {
|
|
|
|
|
</div> |
|
|
|
|
{/* 탭 컨텐츠 */} |
|
|
|
|
<div> |
|
|
|
|
<div className='tab-menu'> |
|
|
|
|
<Nav pills> |
|
|
|
|
<NavItem> |
|
|
|
|
<NavLink |
|
|
|
|
active={activeTab === '전체'} |
|
|
|
|
onClick={() => toggle('전체')} |
|
|
|
|
> |
|
|
|
|
<span className=''>전체</span> |
|
|
|
|
</NavLink> |
|
|
|
|
</NavItem> |
|
|
|
|
<NavItem> |
|
|
|
|
<NavLink |
|
|
|
|
active={activeTab === '장치신고'} |
|
|
|
|
onClick={() => toggle('장치신고')} |
|
|
|
|
> |
|
|
|
|
<span className=''>장치 신고</span> |
|
|
|
|
</NavLink> |
|
|
|
|
</NavItem> |
|
|
|
|
<NavItem> |
|
|
|
|
<NavLink |
|
|
|
|
active={activeTab === '사업등록'} |
|
|
|
|
onClick={() => toggle('사업등록')} |
|
|
|
|
> |
|
|
|
|
<span className=''>사업 등록</span> |
|
|
|
|
</NavLink> |
|
|
|
|
</NavItem> |
|
|
|
|
<NavItem> |
|
|
|
|
<NavLink |
|
|
|
|
active={activeTab === '비행승인'} |
|
|
|
|
onClick={() => toggle('비행승인')} |
|
|
|
|
> |
|
|
|
|
<span className=''>비행 승인</span> |
|
|
|
|
</NavLink> |
|
|
|
|
</NavItem> |
|
|
|
|
<NavItem> |
|
|
|
|
<NavLink |
|
|
|
|
active={activeTab === '항공촬영'} |
|
|
|
|
onClick={() => toggle('항공촬영')} |
|
|
|
|
> |
|
|
|
|
<span className=''>항공 촬영</span> |
|
|
|
|
</NavLink> |
|
|
|
|
</NavItem> |
|
|
|
|
<NavItem> |
|
|
|
|
<NavLink |
|
|
|
|
active={activeTab === '기타'} |
|
|
|
|
onClick={() => toggle('기타')} |
|
|
|
|
> |
|
|
|
|
<span className=''>기타</span> |
|
|
|
|
</NavLink> |
|
|
|
|
</NavItem> |
|
|
|
|
</Nav> |
|
|
|
|
</div> |
|
|
|
|
<FaqTab |
|
|
|
|
activeTab={activeTab} |
|
|
|
|
handlerChangeTab={handlerChangeTab} |
|
|
|
|
tabList={tabList} |
|
|
|
|
/> |
|
|
|
|
<div> |
|
|
|
|
<TabContent activeTab={activeTab}> |
|
|
|
|
<TabPane tabId={activeTab}> |
|
|
|
@ -223,17 +298,53 @@ export default function FaqContainer() {
|
|
|
|
|
<AppCollapse data={handlerFaqList()} accordion type='margin' /> |
|
|
|
|
</div> |
|
|
|
|
</TabPane> |
|
|
|
|
{/* <TabPane tabId='2'>장치신고</TabPane> |
|
|
|
|
<TabPane tabId='3'>사업 등록</TabPane> |
|
|
|
|
<TabPane tabId='4'>비행 승인</TabPane> |
|
|
|
|
<TabPane tabId='5'>항공 촬영</TabPane> |
|
|
|
|
<TabPane tabId='6'>기타</TabPane> */} |
|
|
|
|
</TabContent> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
<FaqForm |
|
|
|
|
isOpenFormModal={isOpenFormModal} |
|
|
|
|
handlerOpenFormModal={handlerOpenFormModal} |
|
|
|
|
tabList={tabList} |
|
|
|
|
formData={formData} |
|
|
|
|
handlerChangeFormData={handlerChangeFormData} |
|
|
|
|
handlerSubmitForm={handlerSubmitForm} |
|
|
|
|
handlerDeleteConfirmFaq={handlerDeleteConfirmFaq} |
|
|
|
|
user={user} |
|
|
|
|
formMode={formMode} |
|
|
|
|
/> |
|
|
|
|
<ErrorModal |
|
|
|
|
modal={validationModal.errorType} |
|
|
|
|
setModal={val => { |
|
|
|
|
setValidationModal({ |
|
|
|
|
...validationModal, |
|
|
|
|
errorType: { |
|
|
|
|
...val |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
}} |
|
|
|
|
/> |
|
|
|
|
<InfoModal |
|
|
|
|
modal={validationModal.successType} |
|
|
|
|
setModal={val => { |
|
|
|
|
setValidationModal({ |
|
|
|
|
...validationModal, |
|
|
|
|
successType: { |
|
|
|
|
...val |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
}} |
|
|
|
|
/> |
|
|
|
|
<ConfirmModal |
|
|
|
|
modal={validationModal.confirmType} |
|
|
|
|
setModal={val => { |
|
|
|
|
setValidationModal({ |
|
|
|
|
...validationModal, |
|
|
|
|
confirmType: { |
|
|
|
|
...val |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
}} |
|
|
|
|
handlerConfirm={handlerDeleteFaq} |
|
|
|
|
/> |
|
|
|
|
</div> |
|
|
|
|
); |
|
|
|
|