wing-ops/frontend/src/tabs/weather/components/OceanForecastOverlay.tsx
htlee f099ff29b1 refactor(frontend): 탭 단위 패키지 구조 전환 (tabs/)
- 11개 탭 디렉토리 생성: tabs/{prediction,hns,rescue,weather,incidents,aerial,board,reports,assets,scat,admin}/
- 51개 컴포넌트를 역할 기반(views/, analysis/, layout/) → 탭 기반(tabs/) 구조로 이동
- weather 탭에 전용 hooks/, services/ 포함
- incidents 탭에 전용 services/ 포함
- 공통 지도 컴포넌트(MapView, BacktrackReplay)를 common/components/map/으로 이동
- 각 탭에 index.ts 생성하여 View 컴포넌트 re-export
- App.tsx import를 @tabs/ alias 사용으로 변경
- 전체 import 경로 수정 (탭 내부 상대경로, 외부 @common/ alias)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 14:08:34 +09:00

57 lines
1.6 KiB
TypeScript
Executable File

import { ImageOverlay, useMap } from 'react-leaflet'
import { LatLngBounds } from 'leaflet'
import { useEffect, useState } from 'react'
import type { OceanForecastData } from '../services/khoaApi'
interface OceanForecastOverlayProps {
forecast: OceanForecastData | null
opacity?: number
visible?: boolean
}
// 한국 해역 범위 (대략적인 경계)
const KOREA_BOUNDS = new LatLngBounds(
[33.0, 124.5], // 남서쪽 (제주 남쪽)
[38.5, 132.0] // 북동쪽 (동해 북쪽)
)
export function OceanForecastOverlay({
forecast,
opacity = 0.6,
visible = true
}: OceanForecastOverlayProps) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const map = useMap()
const [imageLoaded, setImageLoaded] = useState(false)
useEffect(() => {
if (forecast?.filePath) {
// 이미지 미리 로드
const img = new Image()
img.onload = () => setImageLoaded(true)
img.onerror = () => setImageLoaded(false)
img.src = forecast.filePath
} else {
// eslint-disable-next-line react-hooks/set-state-in-effect
setImageLoaded(false)
}
}, [forecast?.filePath])
if (!visible || !forecast || !imageLoaded) {
return null
}
return (
<ImageOverlay
url={forecast.filePath}
bounds={KOREA_BOUNDS}
opacity={opacity}
zIndex={400} // 지도 위에 표시되지만 마커보다는 아래
eventHandlers={{
load: () => console.log('해황예보도 이미지 로드 완료'),
error: () => console.error('해황예보도 이미지 로드 실패')
}}
/>
)
}