sanguu516
3 months ago
9 changed files with 1872 additions and 70 deletions
@ -0,0 +1,105 @@
|
||||
import { useState } from 'react'; |
||||
import Flatpickr from 'react-flatpickr'; |
||||
import { Button, Input, CustomInput, Col, Row } from '@component/ui'; |
||||
import { Search, Calendar } from 'react-feather'; |
||||
import dayjs from 'dayjs'; |
||||
|
||||
export default function NewFlightApprovalsReport(props) { |
||||
// 식별번호
|
||||
const [filterId, setFilterId] = useState(''); |
||||
|
||||
// 지역
|
||||
const [filterArea, setFilterArea] = useState(''); |
||||
// 달력
|
||||
const [searchDate, setSearchDate] = useState({ |
||||
startDate: dayjs().format('YYYY-MM-DD'), |
||||
endDate: dayjs().format('YYYY-MM-DD') |
||||
}); |
||||
|
||||
const handleKeyDown = e => { |
||||
if (e.key === 'Enter') { |
||||
props.handlerSearch(filterId, searchDate, filterArea); |
||||
} |
||||
}; |
||||
|
||||
return ( |
||||
<div className='layer-content'> |
||||
<div className='layer-ti'> |
||||
<h4>비행승인 신청 검토결과 현황</h4> |
||||
</div> |
||||
<div className='layer-ti-sub'> |
||||
검색일자 또는 신청번호/검토결과를 입력해주세요. |
||||
</div> |
||||
<div className='layer-search layer-search-form'> |
||||
<div className='calendar-flat'> |
||||
<Flatpickr |
||||
placeholder='날짜를 선택해주세요' |
||||
id='searchDate' |
||||
options={{ |
||||
mode: 'range', |
||||
defaultDate: [searchDate.startDate, searchDate.endDate] |
||||
}} |
||||
onChange={date => { |
||||
setSearchDate({ |
||||
startDate: dayjs(date[0]).format('YYYY-MM-DD'), |
||||
endDate: dayjs(date[1]).format('YYYY-MM-DD') |
||||
}); |
||||
}} |
||||
className='form-control flat-picker bg-transparent border-0 shadow-none' |
||||
/> |
||||
<Calendar size={14} /> |
||||
</div> |
||||
<div className='list-input'> |
||||
<Input |
||||
type='text' |
||||
bsSize='sm' |
||||
placeholder='신청번호 또는 검토결과를 입력해주세요.' |
||||
value={filterId} |
||||
onChange={e => setFilterId(`${e.target.value}`)} |
||||
onKeyPress={handleKeyDown} |
||||
/> |
||||
</div> |
||||
|
||||
<div className='search-box'> |
||||
<div |
||||
className='search-list-ti' |
||||
style={{ |
||||
color: '#555', |
||||
border: '1px solid #ddd', |
||||
minWidth: '50px', |
||||
width: '60px' |
||||
}} |
||||
> |
||||
지역 |
||||
</div> |
||||
<div className='search-list'> |
||||
<div className='search-list-cont'> |
||||
<CustomInput |
||||
inline |
||||
type='select' |
||||
id='' |
||||
bsSize='sm' |
||||
value={filterArea} |
||||
onChange={e => setFilterArea(e.target.value)} |
||||
> |
||||
<option value='' selected> |
||||
전체 |
||||
</option> |
||||
<option value='gimpo'>김포공항 관제권</option> |
||||
</CustomInput> |
||||
</div> |
||||
</div> |
||||
<Button |
||||
color='primary' |
||||
onClick={() => |
||||
props.handlerSearch(filterId, searchDate, filterArea) |
||||
} |
||||
size='sm' |
||||
> |
||||
검색 |
||||
</Button> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
); |
||||
} |
@ -0,0 +1,444 @@
|
||||
import { useEffect, useState } from 'react'; |
||||
import { useDispatch, useSelector } from '@src/redux/store'; |
||||
import { Button, Card } from '@component/ui'; |
||||
import dayjs from 'dayjs'; |
||||
import { openModal } from '@src/redux/features/comn/message/messageSlice'; |
||||
import { Table } from 'antd'; |
||||
import { FaAngleDown, FaAngleUp } from 'react-icons/fa'; |
||||
|
||||
export default function NewFlightApprovalsTable(props) { |
||||
const dispatch = useDispatch(); |
||||
|
||||
// 비행승인 목록
|
||||
const { laancAprvList, laancElev } = useSelector(state => state.laancState); |
||||
|
||||
// 승인, 미승인, 비대상 건수
|
||||
const [approvalCdValue, setApprovalCdValue] = useState({ |
||||
S: 0, |
||||
F: 0, |
||||
U: 0 |
||||
}); |
||||
|
||||
// 확장된 행 키
|
||||
const [expandedRowKeys, setExpandedRowKeys] = useState([]); |
||||
|
||||
// 승인, 미승인, 비대상 건수 계산
|
||||
useEffect(() => { |
||||
resApprovalCd(); |
||||
}, [laancAprvList]); |
||||
|
||||
const columns = [ |
||||
{ |
||||
title: ( |
||||
<> |
||||
신청 |
||||
<br /> |
||||
번호 |
||||
</> |
||||
), |
||||
dataIndex: 'applyNo', |
||||
align: 'center', |
||||
width: '40px', |
||||
key: 'applyNo', |
||||
editable: true |
||||
}, |
||||
{ |
||||
title: ( |
||||
<> |
||||
신청 <br /> |
||||
일자 |
||||
</> |
||||
), |
||||
dataIndex: 'applyDt', |
||||
width: '60px', |
||||
align: 'center', |
||||
key: 'applyDt', |
||||
editable: true, |
||||
render: text => dayjs(text).format('YYYY-MM-DD') |
||||
}, |
||||
{ |
||||
title: ( |
||||
<> |
||||
신청 <br /> |
||||
구역 수 |
||||
</> |
||||
), |
||||
dataIndex: 'areaList', |
||||
align: 'center', |
||||
width: '85px', |
||||
key: 'areaList', |
||||
editable: true, |
||||
render: areaList => <>총{areaList.length}건</> |
||||
}, |
||||
{ |
||||
title: <>신청자</>, |
||||
dataIndex: 'applyDt', |
||||
width: '78px', |
||||
align: 'center', |
||||
key: 'applyDt', |
||||
editable: true, |
||||
render: text => '홍*동' |
||||
}, |
||||
{ |
||||
title: ( |
||||
<> |
||||
비행 <br /> |
||||
구역 |
||||
</> |
||||
), |
||||
dataIndex: 'applyDt', |
||||
width: '75px', |
||||
align: 'center', |
||||
key: 'applyDt', |
||||
editable: true, |
||||
render: text => '서울시 마포구상암동 1674 (원추)' |
||||
}, |
||||
{ |
||||
title: ( |
||||
<> |
||||
증심좌표 <br /> |
||||
(위도/경도) |
||||
</> |
||||
), |
||||
dataIndex: 'areaList', |
||||
align: 'center', |
||||
width: '85px', |
||||
key: 'latLon', |
||||
editable: true, |
||||
render: areaList => ( |
||||
<> |
||||
{areaList[0].lat.toFixed(5)}, |
||||
<br /> |
||||
{areaList[0].lon.toFixed(5)} |
||||
</> |
||||
) |
||||
}, |
||||
{ |
||||
title: ( |
||||
<> |
||||
반경 <br /> |
||||
(M) |
||||
</> |
||||
), |
||||
dataIndex: 'areaList', |
||||
align: 'center', |
||||
width: '70px', |
||||
key: 'bufferZone', |
||||
editable: true, |
||||
render: areaList => <>{areaList[0].bufferZone}</> |
||||
}, |
||||
{ |
||||
title: ( |
||||
<> |
||||
고도 <br /> |
||||
(M) |
||||
</> |
||||
), |
||||
dataIndex: 'areaList', |
||||
key: 'fltElev', |
||||
align: 'center', |
||||
width: '70px', |
||||
editable: true, |
||||
render: areaList => <>{areaList[0].fltElev}</> |
||||
}, |
||||
{ |
||||
title: ( |
||||
<> |
||||
검토 <br /> |
||||
결과 |
||||
</> |
||||
), |
||||
dataIndex: 'areaList', |
||||
align: 'center', |
||||
width: '85px', |
||||
key: 'approvalCd', |
||||
editable: true, |
||||
render: areaList => ( |
||||
<> |
||||
{areaList[0].approvalCd === 'U' |
||||
? '비대상' |
||||
: areaList[0].approvalCd === 'S' |
||||
? '승인' |
||||
: '미승인'} |
||||
</> |
||||
) |
||||
}, |
||||
{ |
||||
title: <>더보기</>, |
||||
dataIndex: 'areaList', |
||||
align: 'center', |
||||
width: '80px', |
||||
key: 'more', |
||||
editable: true, |
||||
render: (areaList, record) => |
||||
areaList.length > 2 ? ( |
||||
<Button color='flat-dark' onClick={() => handleExpand(record.key)}> |
||||
{expandedRowKeys.includes(record.key) ? ( |
||||
<> |
||||
더보기 |
||||
<FaAngleUp /> |
||||
</> |
||||
) : ( |
||||
<> |
||||
더보기 |
||||
<FaAngleDown /> |
||||
</> |
||||
)} |
||||
</Button> |
||||
) : ( |
||||
<>-</> |
||||
) |
||||
} |
||||
]; |
||||
|
||||
const expandedRowRender = record => { |
||||
const childColumns = [ |
||||
{ |
||||
dataIndex: 'applyNo', |
||||
width: '30px', |
||||
align: 'center', |
||||
key: 'applyNo' |
||||
}, |
||||
{ |
||||
dataIndex: 'applyDt', |
||||
width: '85px', |
||||
align: 'center', |
||||
key: 'applyDt' |
||||
}, |
||||
{ |
||||
dataIndex: 'zoneNo', |
||||
align: 'center', |
||||
width: '85px', |
||||
key: 'zoneNo', |
||||
editable: true |
||||
}, |
||||
{ |
||||
align: 'center', |
||||
width: '85px', |
||||
key: 'latLon', |
||||
dataIndex: ['lat', 'lon'], |
||||
render: (text, record) => { |
||||
const lat = record.lat; |
||||
const lon = record.lon; |
||||
return ( |
||||
<> |
||||
{lat.toFixed(5)} /<br /> |
||||
{lon.toFixed(5)} |
||||
</> |
||||
); |
||||
} |
||||
}, |
||||
{ |
||||
dataIndex: 'bufferZone', |
||||
align: 'center', |
||||
width: '85px', |
||||
key: 'bufferZone' |
||||
}, |
||||
{ |
||||
dataIndex: 'fltElev', |
||||
align: 'center', |
||||
width: '85px', |
||||
key: 'fltElev' |
||||
}, |
||||
{ |
||||
dataIndex: 'approvalCd', |
||||
align: 'center', |
||||
key: 'approvalCd', |
||||
render: text => ( |
||||
<>{text === 'U' ? '비대상' : text === 'S' ? '승인' : '미승인'}</> |
||||
) |
||||
} |
||||
]; |
||||
|
||||
const data = []; |
||||
record.areaList.map((item, index) => { |
||||
if (index < 1) return; |
||||
data.push({ |
||||
key: `${record.applyNo}-${index}`, |
||||
applyNo: item.applyNo, |
||||
applyDt: item.applyDt, |
||||
zoneNo: item.zoneNo, |
||||
lat: item.lat, |
||||
lon: item.lon, |
||||
bufferZone: item.bufferZone, |
||||
fltElev: item.fltElev, |
||||
approvalCd: item.approvalCd |
||||
}); |
||||
}); |
||||
|
||||
return ( |
||||
<Table |
||||
rowClassName={record => { |
||||
let className = ''; |
||||
if (record.approvalCd === 'S') { |
||||
className += 'flight-approval-row'; |
||||
} else if (record.approvalCd === 'F') { |
||||
className += 'flight-not-approval-row'; |
||||
} else className; |
||||
|
||||
return className; |
||||
}} |
||||
size='small' |
||||
bordered |
||||
columns={childColumns} |
||||
dataSource={data} |
||||
pagination={false} |
||||
showHeader={false} |
||||
/> |
||||
); |
||||
}; |
||||
|
||||
// 모달 오픈 핸들러
|
||||
const handlerOpenModal = (approval, fltElev, fltElevMax) => { |
||||
if (approval === 'F') { |
||||
dispatch( |
||||
openModal({ |
||||
header: '미승인 사유', |
||||
body: `관제권 내 제한고도(신청고도${fltElev}m/허용고도${fltElevMax}m) 입니다.`, |
||||
type: 'error' |
||||
}) |
||||
); |
||||
} else if (approval === 'S') { |
||||
dispatch( |
||||
openModal({ |
||||
header: '승인 사유', |
||||
body: `관제권 내 허용고도(신청고도${fltElev}m/허용고도${fltElevMax}m) 입니다.`, |
||||
type: 'success' |
||||
}) |
||||
); |
||||
} else { |
||||
dispatch( |
||||
openModal({ |
||||
header: '비대상', |
||||
body: `해당 구역은 비 대상(신청고도${fltElev}m/허용고도${ |
||||
fltElevMax === undefined ? 150 : null |
||||
}m) 지역 입니다.`,
|
||||
type: 'error' |
||||
}) |
||||
); |
||||
} |
||||
}; |
||||
|
||||
// 테이블 내부 행 클릭 이벤트
|
||||
const handleInRowClick = row => { |
||||
console.log('>>', row); |
||||
|
||||
handlerOpenModal(row.approvalCd, row.fltElev, row.fltElevMax); |
||||
props.handlerDetail(row); |
||||
}; |
||||
|
||||
// 날짜 포맷 변경
|
||||
const formatDate = dateString => { |
||||
const date = new Date(dateString); |
||||
const year = date.getFullYear(); |
||||
const month = String(date.getMonth() + 1).padStart(2, '0'); |
||||
const day = String(date.getDate()).padStart(2, '0'); |
||||
return `${year} 년 ${month} 월 ${day} 일`; |
||||
}; |
||||
|
||||
// 승인, 미승인, 비대상 건수 계산
|
||||
const resApprovalCd = () => { |
||||
let approvalCdValue = { S: 0, F: 0, U: 0 }; |
||||
|
||||
laancAprvList?.map(item => { |
||||
item.areaList.map(area => { |
||||
if (area.approvalCd === 'S') { |
||||
approvalCdValue.S += 1; |
||||
} else if (area.approvalCd === 'F') { |
||||
approvalCdValue.F += 1; |
||||
} else { |
||||
approvalCdValue.U += 1; |
||||
} |
||||
}); |
||||
}); |
||||
|
||||
setApprovalCdValue({ |
||||
F: approvalCdValue.F, |
||||
S: approvalCdValue.S, |
||||
U: approvalCdValue.U |
||||
}); |
||||
}; |
||||
|
||||
const handleExpand = key => { |
||||
const expanded = expandedRowKeys.includes(key); |
||||
const keys = expanded |
||||
? expandedRowKeys.filter(k => k !== key) |
||||
: [...expandedRowKeys, key]; |
||||
setExpandedRowKeys(keys); |
||||
}; |
||||
|
||||
return ( |
||||
<div className='layer-content'> |
||||
<div className='layer-ti d-flex justify-content-between align-items-center'> |
||||
<h4>비행승인 신청 검토결과 목록</h4> |
||||
<span className='search-case'> |
||||
{formatDate(props.startDate)} |
||||
{props.endDate && props.startDate != props.endDate |
||||
? '~' + formatDate(props.endDate) + ' ' |
||||
: null} |
||||
총 {approvalCdValue.S + approvalCdValue.F + approvalCdValue.U} 건 |
||||
</span> |
||||
</div> |
||||
<div className='search-case-list'> |
||||
<div> |
||||
<ul> |
||||
<li className='approval' style={{ cursor: 'pointer' }}> |
||||
승인 {approvalCdValue.S}건 |
||||
</li> |
||||
<li className='not-approved' style={{ cursor: 'pointer' }}> |
||||
미승인 {approvalCdValue.F}건 |
||||
</li> |
||||
<li className='non-target' style={{ cursor: 'pointer' }}> |
||||
비대상 {approvalCdValue.U}건 |
||||
</li> |
||||
</ul> |
||||
</div> |
||||
</div> |
||||
<div className='invoice-list-wrapper'> |
||||
<Card> |
||||
<div |
||||
className='invoice-list-dataTable flight-approval' |
||||
style={{ width: '100%' }} |
||||
> |
||||
{laancAprvList?.length > 0 ? ( |
||||
<Table |
||||
dataSource={laancAprvList.map((item, index) => ({ |
||||
...item, |
||||
key: index |
||||
}))} |
||||
columns={columns} |
||||
size='small' |
||||
rowClassName={record => { |
||||
let className = ''; |
||||
if (record.areaList[0].approvalCd === 'S') { |
||||
className += 'flight-approval-row editable-row'; |
||||
} else if (record.areaList[0].approvalCd === 'F') { |
||||
className += 'flight-not-approval-row editable-row'; |
||||
} else className += 'editable-row'; |
||||
|
||||
return className; |
||||
}} |
||||
expandable={{ |
||||
expandedRowRender, |
||||
expandedRowKeys: expandedRowKeys, |
||||
onExpand: handleExpand, |
||||
rowExpandable: record => record.areaList.length > 1 // areaList가 1개 이상인 경우에만 확장 가능
|
||||
}} |
||||
tableLayout='auto' |
||||
rowHoverable={false} |
||||
expandIconColumnIndex={-1} // 기본 확장 아이콘을 숨김
|
||||
/> |
||||
) : ( |
||||
<div |
||||
className='d-flex justify-content-center align-items-center ' |
||||
style={{ height: '100px', color: '#000' }} |
||||
> |
||||
<p>비행승인 신청 건수가 없습니다.</p> |
||||
</div> |
||||
)} |
||||
</div> |
||||
</Card> |
||||
</div> |
||||
</div> |
||||
); |
||||
} |
@ -0,0 +1,207 @@
|
||||
import { useEffect, useRef, useState, lazy, Suspense } from 'react'; |
||||
import { useDispatch, useSelector } from '@src/redux/store'; |
||||
import NewFlightApprovalsReport from '../../components/flight/NewFlightApprovalsReport'; |
||||
import { |
||||
InitFeature, |
||||
handlerFitBounds, |
||||
handlerGetCircleCoord, |
||||
flightlayerWayPoint, |
||||
flightlayerPolyline, |
||||
flightlayerPolygon, |
||||
flightlayerBuffer |
||||
} from '../../utility/MapUtils'; |
||||
import { useHistory } from 'react-router-dom'; |
||||
import { clientSaveAreaCoordinateList } from '@src/redux/features/laanc/laancSlice'; |
||||
import { MapControl } from '../../components/map/MapControl'; |
||||
import { clientSetIsMapLoading } from '@src/redux/features/laanc/laancSlice'; |
||||
import { clientMapInit } from '@src/redux/features/control/map/mapSlice'; |
||||
import NewFlightApprovalsTable from '@src/components/flight/NewFlightApprovalsTable'; |
||||
import { getLaancAprvList } from '@src/redux/features/laanc/laancThunk'; |
||||
import dayjs from 'dayjs'; |
||||
import { setLogout } from '@src/redux/features/account/auth/authThunk'; |
||||
|
||||
export default function NewFlightApprovalsContainer() { |
||||
const dispatch = useDispatch(); |
||||
const history = useHistory(); |
||||
|
||||
const [selected, setSelected] = useState(null); |
||||
const [isMapLoading, setIsMapLoading] = useState(false); |
||||
// 비행구역 그리기
|
||||
|
||||
const [filter, setFilter] = useState(''); |
||||
// 지도
|
||||
const [mapObject, setMapObject] = useState(); |
||||
|
||||
const { areaCoordList, isOpenModal } = useSelector(state => state.laancState); |
||||
|
||||
//
|
||||
const [startDate, setStartDate] = useState(dayjs().format('YYYY-MM-DD')); |
||||
const [endDate, setEndDate] = useState(); |
||||
// 미니맵 레이어
|
||||
const [previewLayer, setPreviewLayer] = useState(); |
||||
|
||||
const { laancAprvList } = useSelector(state => state.laancState); |
||||
|
||||
const map = useSelector(state => state.mapState.map); |
||||
|
||||
const previewGeo2 = { |
||||
type: 'FeatureCollection', |
||||
features: [] |
||||
}; |
||||
|
||||
useEffect(() => { |
||||
const searchStDt = dayjs().format('YYYY-MM-DD'); |
||||
const searchEndDt = dayjs().format('YYYY-MM-DD'); |
||||
dispatch( |
||||
getLaancAprvList({ |
||||
searchStDt, |
||||
searchEndDt |
||||
}) |
||||
); |
||||
}, []); |
||||
|
||||
useEffect(() => { |
||||
if (areaCoordList.length != 0) { |
||||
handlerPreviewDraw(); |
||||
} |
||||
}, [areaCoordList]); |
||||
|
||||
useEffect(() => { |
||||
if (map) { |
||||
setMapObject(map); |
||||
} |
||||
}, [map]); |
||||
|
||||
useEffect(async () => { |
||||
if (areaCoordList.length === 0) return; |
||||
}, [areaCoordList]); |
||||
|
||||
const handlerSearch = (search, searchDate, filterArea) => { |
||||
setStartDate(searchDate.startDate); |
||||
setEndDate(searchDate.endDate); |
||||
|
||||
if ( |
||||
search != '' && |
||||
(search === '승인' || search === '미승인' || search === '비대상') |
||||
) { |
||||
dispatch( |
||||
getLaancAprvList({ |
||||
searchStDt: searchDate.startDate, |
||||
searchEndDt: searchDate.endDate, |
||||
selectZone: filterArea, |
||||
approvalCd: search === '승인' ? 'S' : search === '미승인' ? 'F' : 'U' |
||||
}) |
||||
); |
||||
} else if (search != '') { |
||||
dispatch( |
||||
getLaancAprvList({ |
||||
searchStDt: searchDate.startDate, |
||||
searchEndDt: searchDate.endDate, |
||||
selectZone: filterArea, |
||||
applyNo: search |
||||
}) |
||||
); |
||||
} else { |
||||
dispatch( |
||||
getLaancAprvList({ |
||||
searchStDt: searchDate.startDate, |
||||
searchEndDt: searchDate.endDate, |
||||
selectZone: filterArea |
||||
}) |
||||
); |
||||
} |
||||
// );
|
||||
setFilter(search); |
||||
}; |
||||
|
||||
const handlerDetail = area => { |
||||
setSelected(area.planAreaSno); |
||||
|
||||
dispatch(clientSaveAreaCoordinateList([area])); |
||||
|
||||
handlerMapInit(); |
||||
}; |
||||
|
||||
const handlerMapInit = () => { |
||||
if (map.getSource('preview')) { |
||||
} else { |
||||
map.addSource('preview', { |
||||
type: 'geojson', |
||||
data: previewGeo2 |
||||
}); |
||||
map.addLayer(flightlayerWayPoint('preview')); |
||||
map.addLayer(flightlayerBuffer('preview')); |
||||
map.addLayer(flightlayerPolygon('preview')); |
||||
map.addLayer(flightlayerPolyline('preview')); |
||||
} |
||||
|
||||
dispatch(clientSetIsMapLoading(true)); |
||||
const preview = map.getSource('preview'); |
||||
|
||||
if (preview) setPreviewLayer(preview); |
||||
|
||||
setIsMapLoading(true); |
||||
|
||||
setMapObject(map); |
||||
dispatch(clientMapInit(map)); |
||||
}; |
||||
const handlerPreviewDraw = () => { |
||||
if (areaCoordList.length > 0) { |
||||
const areas = areaCoordList[0]; |
||||
|
||||
previewGeo2.features = []; |
||||
|
||||
let fitZoomPaths = []; |
||||
const radius = areas.bufferZone; |
||||
const circleCoords = handlerGetCircleCoord( |
||||
[areas.lon, areas.lat], |
||||
radius |
||||
); |
||||
|
||||
const circle = InitFeature('Polygon', 'CIRCLE'); |
||||
circle.properties.center = [areas.lon, areas.lat]; |
||||
circle.geometry.coordinates = circleCoords; |
||||
|
||||
previewGeo2.features.push(circle); |
||||
|
||||
mapObject.setCenter(circle.properties.center); |
||||
|
||||
fitZoomPaths = circleCoords[0]; |
||||
|
||||
handlerFitBounds(mapObject, fitZoomPaths, 400, 'CIRCLE', 'flight'); |
||||
|
||||
// mapObject.setPaintProperty('waypoint', 'circle-radius', 10);
|
||||
mapObject.getSource('preview').setData(previewGeo2); |
||||
} |
||||
}; |
||||
|
||||
const handlerLogout = async () => { |
||||
const { payload } = await dispatch(setLogout()); |
||||
|
||||
if (payload === 'SUCCESS') { |
||||
history.replace('/account/login'); |
||||
} |
||||
}; |
||||
|
||||
return ( |
||||
<> |
||||
<div className='map' style={{ width: '100%' }}> |
||||
<MapControl /> |
||||
</div> |
||||
<div className='right-menu active'> |
||||
<div className='right-layer active flight-approval-layer'> |
||||
<div className='layer-content'> |
||||
<NewFlightApprovalsReport handlerSearch={handlerSearch} /> |
||||
<NewFlightApprovalsTable |
||||
filter={filter} |
||||
startDate={startDate} |
||||
endDate={endDate} |
||||
selected={selected} |
||||
handlerDetail={handlerDetail} |
||||
/> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</> |
||||
); |
||||
} |
@ -0,0 +1,15 @@
|
||||
import '@styles/react/libs/flatpickr/flatpickr.scss'; |
||||
import '@styles/react/libs/tables/react-dataTable-component.scss'; |
||||
import '../../assets/css/custom.css'; |
||||
import NewFlightApprovalsContainer from '../../containers/flight/NewFlightApprovalsContainer'; |
||||
|
||||
export default function NewFlightView() { |
||||
return ( |
||||
<div className='pal-container'> |
||||
{/* <Helmet> |
||||
<title>관제시스템</title> |
||||
</Helmet> */} |
||||
<NewFlightApprovalsContainer />; |
||||
</div> |
||||
); |
||||
} |
Loading…
Reference in new issue