import { useState, useCallback, useEffect } from 'react'; import type { ScatSegment, ScatDetail } from './scatTypes'; import { fetchOffices, fetchSections, fetchSectionDetail, fetchZones, fetchJurisdictions, } from '../services/scatApi'; import type { ApiZoneItem } from '../services/scatApi'; import ScatLeftPanel from './ScatLeftPanel'; import ScatMap from './ScatMap'; import ScatPopup from './ScatPopup'; import ScatRightPanel from './ScatRightPanel'; // ═══ Main PreScatView ═══ export function PreScatView() { const [leftCollapsed, setLeftCollapsed] = useState(false); const [rightCollapsed, setRightCollapsed] = useState(false); const [segments, setSegments] = useState([]); const [zones, setZones] = useState([]); const [jurisdictions, setJurisdictions] = useState([]); const [offices, setOffices] = useState([]); const [selectedOffice, setSelectedOffice] = useState(''); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [selectedSeg, setSelectedSeg] = useState(null); const [jurisdictionFilter, setJurisdictionFilter] = useState(''); const [areaFilter, setAreaFilter] = useState(''); const [phaseFilter, setPhaseFilter] = useState('Pre-SCAT (사전조사)'); const [statusFilter, setStatusFilter] = useState('전체'); const [searchTerm, setSearchTerm] = useState(''); const [popupData, setPopupData] = useState(null); const [panelDetail, setPanelDetail] = useState(null); const [panelLoading, setPanelLoading] = useState(false); // eslint-disable-next-line @typescript-eslint/no-unused-vars const [timelineIdx, setTimelineIdx] = useState(6); // 초기 관할청 목록 로딩 useEffect(() => { let cancelled = false; async function loadInit() { try { setLoading(true); const officeList = await fetchOffices(); if (cancelled) return; setOffices(officeList); const defaultOffice = officeList.includes('제주청') ? '제주청' : officeList[0] || ''; setSelectedOffice(defaultOffice); const jrsdList = await fetchJurisdictions(defaultOffice); if (cancelled) return; setJurisdictions(jrsdList); setJurisdictionFilter(''); const [zonesData, sectionsData] = await Promise.all([ fetchZones(undefined, defaultOffice), fetchSections({ officeCd: defaultOffice }), ]); if (cancelled) return; setZones(zonesData); setSegments(sectionsData); if (sectionsData.length > 0) setSelectedSeg(sectionsData[0]); } catch (err) { console.error('[SCAT] 데이터 로딩 오류:', err); if (!cancelled) setError('데이터를 불러오지 못했습니다.'); } finally { if (!cancelled) setLoading(false); } } loadInit(); return () => { cancelled = true; }; }, []); // 관할청 변경 시 관할구역 + zones + sections 재로딩 useEffect(() => { if (offices.length === 0 || !selectedOffice) return; let cancelled = false; async function reload() { try { setLoading(true); const jrsdList = await fetchJurisdictions(selectedOffice); if (cancelled) return; setJurisdictions(jrsdList); setJurisdictionFilter(''); const [zonesData, sectionsData] = await Promise.all([ fetchZones(undefined, selectedOffice), fetchSections({ officeCd: selectedOffice }), ]); if (cancelled) return; setZones(zonesData); setSegments(sectionsData); setAreaFilter(''); if (sectionsData.length > 0) setSelectedSeg(sectionsData[0]); else setSelectedSeg(null); } catch (err) { console.error('[SCAT] 관할청 변경 오류:', err); } finally { if (!cancelled) setLoading(false); } } reload(); return () => { cancelled = true; }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [selectedOffice]); // 관할구역 필터 변경 시 zones + sections 재로딩 (선택된 관할청 내에서 필터링) useEffect(() => { if (!selectedOffice || !jurisdictionFilter) return; let cancelled = false; async function reload() { try { setLoading(true); const [zonesData, sectionsData] = await Promise.all([ fetchZones(jurisdictionFilter, selectedOffice), fetchSections({ jurisdiction: jurisdictionFilter, officeCd: selectedOffice }), ]); if (cancelled) return; setZones(zonesData); setSegments(sectionsData); setAreaFilter(''); if (sectionsData.length > 0) setSelectedSeg(sectionsData[0]); else setSelectedSeg(null); } catch (err) { console.error('[SCAT] 관할구역 변경 오류:', err); } finally { if (!cancelled) setLoading(false); } } reload(); return () => { cancelled = true; }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [jurisdictionFilter]); // 선택 구간 변경 시 우측 패널 상세 로딩 useEffect(() => { if (!selectedSeg) { setPanelDetail(null); return; } let cancelled = false; setPanelLoading(true); fetchSectionDetail(selectedSeg.id) .then((detail) => { if (!cancelled) setPanelDetail(detail); }) .catch((err) => console.error('[SCAT] 패널 상세 로딩 오류:', err)) .finally(() => { if (!cancelled) setPanelLoading(false); }); return () => { cancelled = true; }; }, [selectedSeg]); const handleOpenPopup = useCallback(async (sn: number) => { try { const detail = await fetchSectionDetail(sn); setPopupData(detail); } catch (err) { console.error('[SCAT] 상세 데이터 로딩 오류:', err); } }, []); const handleClosePopup = useCallback(() => { setPopupData(null); }, []); if (error) { return (
{error}
); } if (loading || !selectedSeg) { return (
SCAT 데이터 로딩 중...
); } return (
{/* Left Panel */}
{/* Left panel toggle button */} {/* Right panel toggle button */} {/* */}
{/* Right Panel */}
{popupData && ( )}
); }