추가 수정사항 반영
1. 페이지네이션, 스크롤, 날짜 선택 ui 추가 2. 공통코드 조회 api 적용 (위성 조회, 등록 팝업 등) 3. 필수값 입력 메세지 추가
This commit is contained in:
부모
1c991d8229
커밋
81255c4839
@ -71,6 +71,8 @@
|
||||
.schInput{height: 3.5rem; font-family: 'NanumSquare', sans-serif;font-size: var(--fs-m); color: var(--white);background-color: var(--tertiary1);padding: 0 1.2rem; border: 0;}
|
||||
.schInput::placeholder { color:rgba(var(--white-rgb),.3); }
|
||||
.dateInput {background:url(../images/ico_input_cal.svg) no-repeat center right .5rem/2.4rem; padding-right: 3rem; cursor: pointer;}
|
||||
.dateInput { position: relative; }
|
||||
.dateInput::-webkit-calendar-picker-indicator { opacity: 0; position: absolute; right: 0; width: 3rem; height: 100%;cursor: pointer; }
|
||||
.dateInput::placeholder { color:var(--white); }
|
||||
|
||||
/* =========================
|
||||
@ -107,6 +109,15 @@
|
||||
.colList.lineSB li a .title {font-size: var(--fs-m); font-weight: var(--fw-bold);}
|
||||
.colList.lineSB li a .meta {font-size: var(--fs-s); font-weight: var(--fw-regular); color:rgba(var(--white-rgb),.5);}
|
||||
|
||||
/* 페이지네이션 */
|
||||
.pagination {display: flex; align-items: center; justify-content: center; gap: .5rem; padding: 1.4rem 0;}
|
||||
.pagination button {min-width: 2.8rem; height: 2.8rem; padding: 0 .6rem; border-radius: .4rem; background-color: var(--secondary1); color: var(--white); font-size: var(--fs-m); font-weight: var(--fw-bold); border: 1px solid var(--secondary3); cursor: pointer; transition: background-color .15s ease, border-color .15s ease;}
|
||||
.pagination button:hover {background-color: var(--secondary3); border-color: var(--secondary4);}
|
||||
.pagination button.on {background-color: var(--primary1); border-color: var(--primary1);}
|
||||
.pagination button.on:hover {background-color: var(--primary2); border-color: var(--primary2);}
|
||||
.pagination button.disabled {opacity: 0.4; cursor: default; pointer-events: none;}
|
||||
.pagination .ellipsis {color: rgba(var(--white-rgb), .4); font-size: var(--fs-m); padding: 0 .2rem; user-select: none;}
|
||||
|
||||
/* 아코디언리스트 */
|
||||
.accordionWrap {display: flex;flex-direction: column;transition: max-height 0.3s ease;}
|
||||
.accordionWrap .acdHeader {display: flex; justify-content: space-between; align-items: center; height: 4rem; background-color: var(--secondary1); padding: 1rem; border-bottom: .1rem solid var(--secondary3);}
|
||||
@ -292,7 +303,7 @@
|
||||
align-items: center;
|
||||
z-index: 999;
|
||||
}
|
||||
.popupUtillWrap { position: absolute;top: 50%; left: 50%;transform: translate(-50%, -50%);z-index :85;}
|
||||
.popupUtillWrap { position: fixed;top: 50%; left: 50%;transform: translate(-50%, -50%);z-index :100;}
|
||||
.popupUtill {display: flex; flex-direction: column; width: 52.5rem; height:auto;max-height: 80vh;overflow: hidden; background-color: var(--secondary2); border: .1rem solid var(--secondary3); padding:2.5rem 3rem;}
|
||||
.popupUtill > .puHeader {display: flex; justify-content: space-between; align-items: center; padding-bottom: 2rem;}
|
||||
.popupUtill > .puHeader > .title {font-weight: var(--fw-bold); font-size: var(--fs-xl);}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { useState, useCallback } from 'react';
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { fetchCommonCodeList } from '@/api/commonApi';
|
||||
import { fetchSatelliteVideoList, fetchSatelliteCsvFeatures } from '@/api/satelliteApi';
|
||||
import { useSatelliteStore } from '@/stores/satelliteStore';
|
||||
import { useMapStore } from '@/stores/mapStore';
|
||||
@ -11,6 +12,12 @@ const LIMIT = 10;
|
||||
export default function SatelliteImageManage() {
|
||||
const [isAccordionOpen, setIsAccordionOpen] = useState(false);
|
||||
|
||||
// 공통코드 옵션
|
||||
const [videoKindOptions, setVideoKindOptions] = useState([]);
|
||||
const [videoOriginOptions, setVideoOriginOptions] = useState([]);
|
||||
const [videoOrbitOptions, setVideoOrbitOptions] = useState([]);
|
||||
const [videoCycleOptions, setVideoCycleOptions] = useState([]);
|
||||
|
||||
// 폼 필터 state
|
||||
const [startDate, setStartDate] = useState('');
|
||||
const [endDate, setEndDate] = useState('');
|
||||
@ -42,6 +49,14 @@ export default function SatelliteImageManage() {
|
||||
const setOpacity = useSatelliteStore((s) => s.setOpacity);
|
||||
const setBrightness = useSatelliteStore((s) => s.setBrightness);
|
||||
|
||||
// 마운트 시 공통코드 로드
|
||||
useEffect(() => {
|
||||
fetchCommonCodeList('000109').then(setVideoKindOptions).catch(() => setVideoKindOptions([]));
|
||||
fetchCommonCodeList('000111').then(setVideoOriginOptions).catch(() => setVideoOriginOptions([]));
|
||||
fetchCommonCodeList('000110').then(setVideoOrbitOptions).catch(() => setVideoOrbitOptions([]));
|
||||
fetchCommonCodeList('000108').then(setVideoCycleOptions).catch(() => setVideoCycleOptions([]));
|
||||
}, []);
|
||||
|
||||
const toggleAccordion = () => setIsAccordionOpen((prev) => !prev);
|
||||
|
||||
const search = useCallback(async (targetPage) => {
|
||||
@ -162,11 +177,11 @@ export default function SatelliteImageManage() {
|
||||
onChange={(e) => setSatelliteVideoKind(e.target.value)}
|
||||
>
|
||||
<option value="">전체</option>
|
||||
<option value="VIRS">VIIRS</option>
|
||||
<option value="ICEYE_SAR">ICEYE_SAR</option>
|
||||
<option value="광학">광학</option>
|
||||
<option value="예약">예약</option>
|
||||
<option value="RF">RF</option>
|
||||
{videoKindOptions.map((opt) => (
|
||||
<option key={opt.commonCodeTypeNumber} value={opt.commonCodeTypeNumber}>
|
||||
{opt.commonCodeTypeName}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
@ -176,10 +191,11 @@ export default function SatelliteImageManage() {
|
||||
onChange={(e) => setSatelliteVideoOrigin(e.target.value)}
|
||||
>
|
||||
<option value="">전체</option>
|
||||
<option value="국내/자동">국내/자동</option>
|
||||
<option value="국내/수동">국내/수동</option>
|
||||
<option value="국외/수동">국외/수동</option>
|
||||
<option value="기타">기타</option>
|
||||
{videoOriginOptions.map((opt) => (
|
||||
<option key={opt.commonCodeTypeNumber} value={opt.commonCodeTypeNumber}>
|
||||
{opt.commonCodeTypeName}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
</li>
|
||||
@ -191,10 +207,11 @@ export default function SatelliteImageManage() {
|
||||
onChange={(e) => setSatelliteVideoOrbit(e.target.value)}
|
||||
>
|
||||
<option value="">전체</option>
|
||||
<option value="저궤도">저궤도</option>
|
||||
<option value="중궤도">중궤도</option>
|
||||
<option value="정지궤도">정지궤도</option>
|
||||
<option value="기타">기타</option>
|
||||
{videoOrbitOptions.map((opt) => (
|
||||
<option key={opt.commonCodeTypeNumber} value={opt.commonCodeTypeNumber}>
|
||||
{opt.commonCodeTypeName}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
@ -204,10 +221,11 @@ export default function SatelliteImageManage() {
|
||||
onChange={(e) => setSatelliteVideoTransmissionCycle(e.target.value)}
|
||||
>
|
||||
<option value="">전체</option>
|
||||
<option value="0">0</option>
|
||||
<option value="10">10</option>
|
||||
<option value="30">30</option>
|
||||
<option value="60">60</option>
|
||||
{videoCycleOptions.map((opt) => (
|
||||
<option key={opt.commonCodeTypeNumber} value={opt.commonCodeTypeNumber}>
|
||||
{opt.commonCodeTypeName}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
</li>
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import {createPortal} from "react-dom";
|
||||
import { showToast } from '@/components/common/Toast';
|
||||
import { fetchCommonCodeList } from '@/api/commonApi';
|
||||
import {
|
||||
fetchSatelliteCompanyList,
|
||||
saveSatelliteManage,
|
||||
fetchSatelliteManageDetail,
|
||||
updateSatelliteManage,
|
||||
@ -16,6 +19,7 @@ export default function SatelliteManageRegisterPopup({ satelliteManageId, onClos
|
||||
const isEditMode = !!satelliteManageId;
|
||||
|
||||
const [sensorTypeOptions, setSensorTypeOptions] = useState([]);
|
||||
const [companyOptions, setCompanyOptions] = useState([]);
|
||||
|
||||
const [companyNo, setCompanyNo] = useState('');
|
||||
const [satelliteName, setSatelliteName] = useState('');
|
||||
@ -38,9 +42,13 @@ export default function SatelliteManageRegisterPopup({ satelliteManageId, onClos
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const codeList = await fetchCommonCodeList('000092');
|
||||
const [codeList, companyList] = await Promise.all([
|
||||
fetchCommonCodeList('000092'),
|
||||
fetchSatelliteCompanyList(),
|
||||
]);
|
||||
if (cancelled) return;
|
||||
setSensorTypeOptions(codeList);
|
||||
setCompanyOptions(companyList);
|
||||
|
||||
if (satelliteManageId) {
|
||||
const data = await fetchSatelliteManageDetail(satelliteManageId);
|
||||
@ -65,6 +73,15 @@ export default function SatelliteManageRegisterPopup({ satelliteManageId, onClos
|
||||
}, [satelliteManageId]);
|
||||
|
||||
const handleSave = async () => {
|
||||
if (!companyNo) {
|
||||
showToast('사업자명을 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
if (!satelliteName.trim()) {
|
||||
showToast('위성명을 입력해주세요.');
|
||||
return;
|
||||
}
|
||||
|
||||
setIsSaving(true);
|
||||
setError(null);
|
||||
|
||||
@ -98,7 +115,7 @@ export default function SatelliteManageRegisterPopup({ satelliteManageId, onClos
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
return createPortal(
|
||||
<div className="popupUtillWrap" style={{ transform: `translate(calc(-50% + ${position.x}px), calc(-50% + ${position.y}px))` }}>
|
||||
<div className="popupUtill">
|
||||
<div className="puHeader" onMouseDown={handleMouseDown} style={{ cursor: 'grab' }}>
|
||||
@ -128,13 +145,18 @@ export default function SatelliteManageRegisterPopup({ satelliteManageId, onClos
|
||||
<tr>
|
||||
<th scope="row">사업자명 <span className="required">*</span></th>
|
||||
<td>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="사업자명"
|
||||
<select
|
||||
aria-label="사업자명"
|
||||
value={companyNo}
|
||||
onChange={(e) => setCompanyNo(e.target.value)}
|
||||
/>
|
||||
>
|
||||
<option value="">선택</option>
|
||||
{companyOptions.map((opt) => (
|
||||
<option key={opt.companyNo} value={opt.companyNo}>
|
||||
{opt.companyName}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -226,6 +248,7 @@ export default function SatelliteManageRegisterPopup({ satelliteManageId, onClos
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
document.body
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import {createPortal} from "react-dom";
|
||||
import { showToast } from '@/components/common/Toast';
|
||||
import { fetchCommonCodeList } from '@/api/commonApi';
|
||||
import {
|
||||
saveSatelliteCompany,
|
||||
@ -82,6 +84,19 @@ export default function SatelliteProviderRegisterPopup({ companyNo, onClose, onS
|
||||
}, [companyNo]);
|
||||
|
||||
const handleSave = async () => {
|
||||
if (!companyTypeCode) {
|
||||
showToast('사업자 분류를 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
if (!companyName.trim()) {
|
||||
showToast('사업자명을 입력해주세요.');
|
||||
return;
|
||||
}
|
||||
if (!nationalCode) {
|
||||
showToast('국가를 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
|
||||
setIsSaving(true);
|
||||
setError(null);
|
||||
|
||||
@ -113,7 +128,7 @@ export default function SatelliteProviderRegisterPopup({ companyNo, onClose, onS
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
return createPortal(
|
||||
<div className="popupUtillWrap" style={{ transform: `translate(calc(-50% + ${position.x}px), calc(-50% + ${position.y}px))` }}>
|
||||
<div className="popupUtill">
|
||||
<div className="puHeader" onMouseDown={handleMouseDown} style={{ cursor: 'grab' }}>
|
||||
@ -236,6 +251,7 @@ export default function SatelliteProviderRegisterPopup({ companyNo, onClose, onS
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
document.body
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import {createPortal} from "react-dom";
|
||||
import { showToast } from '@/components/common/Toast';
|
||||
import {
|
||||
fetchSatelliteCompanyList,
|
||||
fetchSatelliteManageList,
|
||||
@ -120,6 +122,23 @@ export default function SatelliteRegisterPopup({ satelliteId, onClose, onSaved }
|
||||
}, [companyNo, isEditMode]);
|
||||
|
||||
const handleSave = async () => {
|
||||
if (!isEditMode && !satelliteManageId) {
|
||||
showToast('사업자명/위성명을 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
if (!photographDate) {
|
||||
showToast('영상 촬영일을 입력해주세요.');
|
||||
return;
|
||||
}
|
||||
if (!isEditMode && !tifFile) {
|
||||
showToast('위성영상파일을 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
if (!satelliteVideoName.trim()) {
|
||||
showToast('위성영상명을 입력해주세요.');
|
||||
return;
|
||||
}
|
||||
|
||||
setIsSaving(true);
|
||||
setError(null);
|
||||
|
||||
@ -172,7 +191,7 @@ export default function SatelliteRegisterPopup({ satelliteId, onClose, onSaved }
|
||||
// setPhotographDate(changedFormat);
|
||||
// }
|
||||
|
||||
return (
|
||||
return createPortal(
|
||||
<div className="popupUtillWrap" style={{ transform: `translate(calc(-50% + ${position.x}px), calc(-50% + ${position.y}px))` }}>
|
||||
<div className="popupUtill w61r">
|
||||
<div className="puHeader" onMouseDown={handleMouseDown} style={{ cursor: 'grab' }}>
|
||||
@ -478,6 +497,7 @@ export default function SatelliteRegisterPopup({ satelliteId, onClose, onSaved }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
document.body
|
||||
);
|
||||
}
|
||||
|
||||
@ -416,6 +416,30 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 위성/기상 메뉴 스크롤바 다크 테마
|
||||
.tabBtm,
|
||||
.tabBtmCnt {
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: rgba(var(--white-rgb), 0.3);
|
||||
border-radius: 3px;
|
||||
|
||||
&:hover {
|
||||
background: rgba(var(--white-rgb), 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: rgba(255, 255, 255, 0.3) transparent;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.toogle {
|
||||
|
||||
불러오는 중...
Reference in New Issue
Block a user