import { useState, useEffect } from 'react' import { typeTagCls } from './assetTypes' import { fetchOrganizations, fetchOrganizationDetail } from '../services/assetsApi' import type { AssetOrgCompat } from '../services/assetsApi' import AssetMap from './AssetMap' function AssetManagement() { const [viewMode, setViewMode] = useState<'list' | 'map'>('list') const [organizations, setOrganizations] = useState([]) const [selectedOrg, setSelectedOrg] = useState(null) const [detailTab, setDetailTab] = useState<'equip' | 'material' | 'contact'>('equip') const [regionFilter, setRegionFilter] = useState('all') const [searchTerm, setSearchTerm] = useState('') const [typeFilterVal, setTypeFilterVal] = useState('all') const [currentPage, setCurrentPage] = useState(1) const [loading, setLoading] = useState(true) const pageSize = 15 // API에서 기관 목록 로드 useEffect(() => { let cancelled = false fetchOrganizations() .then(data => { if (cancelled) return setOrganizations(data) if (data.length > 0) setSelectedOrg(data[0]) }) .catch(err => console.error('[assets] 기관 목록 로드 실패:', err)) .finally(() => { if (!cancelled) setLoading(false) }) return () => { cancelled = true } }, []) // 기관 선택 시 상세 조회 (장비/담당자) const handleSelectOrg = async (org: AssetOrgCompat) => { setSelectedOrg(org) try { const detail = await fetchOrganizationDetail(org.id) setSelectedOrg(detail) } catch { // 상세 조회 실패 시 기본 정보 유지 } } const filtered = organizations.filter(o => { if (regionFilter !== 'all' && !o.jurisdiction.includes(regionFilter)) return false if (typeFilterVal !== 'all' && o.type !== typeFilterVal) return false if (searchTerm && !o.name.includes(searchTerm) && !o.address.includes(searchTerm)) return false return true }) const totalPages = Math.max(1, Math.ceil(filtered.length / pageSize)) const safePage = Math.min(currentPage, totalPages) const paged = filtered.slice((safePage - 1) * pageSize, safePage * pageSize) // 필터 변경 시 첫 페이지로 // eslint-disable-next-line react-hooks/set-state-in-effect useEffect(() => { setCurrentPage(1) }, [regionFilter, typeFilterVal, searchTerm]) const regionShort = (j: string) => { if (j.includes('중부')) return '중부청' if (j.includes('서해')) return '서해청' if (j.includes('남해')) return '남해청' if (j.includes('동해')) return '동해청' if (j.includes('중앙')) return '중특단' return '제주청' } if (loading) { return (
방제자산 데이터를 불러오는 중...
) } return (
{/* View Switcher & Filters */}
setSearchTerm(e.target.value)} className="prd-i w-40 py-1.5 px-2.5" />
{viewMode === 'list' ? ( /* ── LIST VIEW ── */
{['번호', '유형', '관할청', '기관명', '주소', '방제선', '유회수기', '이송펌프', '방제차량', '살포장치', '총자산'].map((h, i) => ( ))} {paged.map((org, idx) => ( { handleSelectOrg(org); setViewMode('map') }} > ))}
{h}
{(safePage - 1) * pageSize + idx + 1} {org.type} {regionShort(org.jurisdiction)} {org.name} {org.address} {org.vessel}척 {org.skimmer}대 {org.pump}대 {org.vehicle}대 {org.sprayer}대 {org.totalAssets}
{/* Pagination */}
전체 {filtered.length}건 중{' '} {(safePage - 1) * pageSize + 1}-{Math.min(safePage * pageSize, filtered.length)}
{Array.from({ length: totalPages }, (_, i) => i + 1).map(p => ( ))}
) : ( /* ── MAP VIEW ── */
{/* Map */}
{/* Right Detail Panel */} {selectedOrg && ( )}
)}
) } export default AssetManagement