release: Phase 1~5 리팩토링 통합 릴리즈 #26

병합
htlee develop 에서 main 로 14 commits 를 머지했습니다 2026-02-28 18:44:26 +09:00
62개의 변경된 파일67개의 추가작업 그리고 57개의 파일을 삭제
Showing only changes of commit f099ff29b1 - Show all commits

파일 보기

@ -6,17 +6,17 @@ import { LoginPage } from '@common/components/auth/LoginPage'
import { registerMainTabSwitcher } from '@common/hooks/useSubMenu'
import { useAuthStore } from '@common/store/authStore'
import { useMenuStore } from '@common/store/menuStore'
import { OilSpillView } from './components/views/OilSpillView'
import { ReportsView } from './components/views/ReportsView'
import { HNSView } from './components/views/HNSView'
import { AerialView } from './components/views/AerialView'
import { AssetsView } from './components/views/AssetsView'
import { BoardView } from './components/views/BoardView'
import { WeatherView } from './components/views/WeatherView'
import { IncidentsView } from './components/views/IncidentsView'
import { AdminView } from './components/views/AdminView'
import { PreScatView } from './components/views/PreScatView'
import { RescueView } from './components/views/RescueView'
import { OilSpillView } from '@tabs/prediction'
import { ReportsView } from '@tabs/reports'
import { HNSView } from '@tabs/hns'
import { AerialView } from '@tabs/aerial'
import { AssetsView } from '@tabs/assets'
import { BoardView } from '@tabs/board'
import { WeatherView } from '@tabs/weather'
import { IncidentsView } from '@tabs/incidents'
import { AdminView } from '@tabs/admin'
import { PreScatView } from '@tabs/scat'
import { RescueView } from '@tabs/rescue'
const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID || ''

파일 보기

@ -2,9 +2,9 @@ import { useState, useMemo, useEffect } from 'react'
import { MapContainer, TileLayer, Marker, Popup, useMap, useMapEvents, CircleMarker, Circle, Polyline } from 'react-leaflet'
import 'leaflet/dist/leaflet.css'
import L from 'leaflet'
import { layerDatabase } from '../../data/layerDatabase'
import { layerDatabase } from '../../../data/layerDatabase'
import { decimalToDMS } from '@common/utils/coordinates'
import type { PredictionModel } from '../views/OilSpillView'
import type { PredictionModel } from '@tabs/prediction/components/OilSpillView'
import type { BoomLine, BoomLineCoord } from '@common/types/boomLine'
import type { ReplayShip, CollisionEvent } from '@common/types/backtrack'
import { BacktrackReplayOverlay } from './BacktrackReplayOverlay'

파일 보기

@ -0,0 +1 @@
export { AdminView } from './components/AdminView'

파일 보기

@ -1,6 +1,6 @@
import { useState, useRef, useEffect } from 'react'
import { useSubMenu } from '@common/hooks/useSubMenu'
import { AerialTheoryView } from '../analysis/AerialTheoryView'
import { AerialTheoryView } from './AerialTheoryView'
type AerialTab = 'media' | 'analysis' | 'realtime' | 'sensor'

파일 보기

@ -0,0 +1 @@
export { AerialView } from './components/AerialView'

파일 보기

@ -0,0 +1 @@
export { AssetsView } from './components/AssetsView'

파일 보기

@ -1,7 +1,7 @@
import { useState } from 'react'
import { useSubMenu } from '@common/hooks/useSubMenu'
import { BoardWriteForm } from '../board/BoardWriteForm'
import { BoardDetailView } from '../board/BoardDetailView'
import { BoardWriteForm } from './BoardWriteForm'
import { BoardDetailView } from './BoardDetailView'
interface BoardPost {
id: number

파일 보기

@ -0,0 +1 @@
export { BoardView } from './components/BoardView'

파일 보기

@ -1,6 +1,6 @@
import React, { useState, useRef, useMemo } from 'react'
import { sanitizeHtml } from '@common/utils/sanitize'
import { HNS_SEARCH_DB, type HNSSearchSubstance } from '../../data/hnsSubstanceSearchData'
import { HNS_SEARCH_DB, type HNSSearchSubstance } from '../../../data/hnsSubstanceSearchData'
/* ═══ HNS 물질 데이터베이스 ═══ */
interface HNSSubstance {

파일 보기

@ -1,12 +1,12 @@
import { useState } from 'react'
import { HNSLeftPanel } from '../layout/HNSLeftPanel'
import { HNSRightPanel } from '../layout/HNSRightPanel'
import { MapView } from '../map/MapView'
import { HNSAnalysisListTable } from '../analysis/HNSAnalysisListTable'
import { HNSTheoryView } from '../analysis/HNSTheoryView'
import { HNSSubstanceView } from '../analysis/HNSSubstanceView'
import { HNSScenarioView } from '../analysis/HNSScenarioView'
import { HNSRecalcModal } from '../analysis/HNSRecalcModal'
import { HNSLeftPanel } from './HNSLeftPanel'
import { HNSRightPanel } from './HNSRightPanel'
import { MapView } from '@common/components/map/MapView'
import { HNSAnalysisListTable } from './HNSAnalysisListTable'
import { HNSTheoryView } from './HNSTheoryView'
import { HNSSubstanceView } from './HNSSubstanceView'
import { HNSScenarioView } from './HNSScenarioView'
import { HNSRecalcModal } from './HNSRecalcModal'
import { useSubMenu, navigateToTab, setReportGenCategory } from '@common/hooks/useSubMenu'
/* ─── HNS 매뉴얼 뷰어 컴포넌트 ─── */

파일 보기

@ -0,0 +1 @@
export { HNSView } from './components/HNSView'

파일 보기

@ -3,9 +3,9 @@ import { MapContainer, TileLayer, CircleMarker, Popup, Marker } from 'react-leaf
import L from 'leaflet'
import type { LatLngExpression } from 'leaflet'
import 'leaflet/dist/leaflet.css'
import { IncidentsLeftPanel, type Incident } from '../incidents/IncidentsLeftPanel'
import { IncidentsRightPanel, type ViewMode, type AnalysisSection } from '../incidents/IncidentsRightPanel'
import { mockVessels, VESSEL_LEGEND, type Vessel } from '../../data/vesselMockData'
import { IncidentsLeftPanel, type Incident } from './IncidentsLeftPanel'
import { IncidentsRightPanel, type ViewMode, type AnalysisSection } from './IncidentsRightPanel'
import { mockVessels, VESSEL_LEGEND, type Vessel } from '../../../data/vesselMockData'
// Mock incident data (HTML 참고 6건)
const mockIncidents: Incident[] = [

파일 보기

@ -0,0 +1 @@
export { IncidentsView } from './components/IncidentsView'

파일 보기

@ -1,16 +1,16 @@
import { useState, useMemo } from 'react'
import { LayerTree } from '@common/components/layer/LayerTree'
import { useLayerTree } from '@common/hooks/useLayers'
import { layerData } from '../../data/layerData'
import type { LayerNode } from '../../data/layerData'
import type { Layer } from '../../data/layerDatabase'
import { layerData } from '../../../data/layerData'
import type { LayerNode } from '../../../data/layerData'
import type { Layer } from '../../../data/layerDatabase'
import { decimalToDMS } from '@common/utils/coordinates'
import { ComboBox } from '@common/components/ui/ComboBox'
import { ALL_MODELS } from '../views/OilSpillView'
import type { PredictionModel } from '../views/OilSpillView'
import { ALL_MODELS } from './OilSpillView'
import type { PredictionModel } from './OilSpillView'
import type { BoomLine, BoomLineCoord, AlgorithmSettings, ContainmentResult } from '@common/types/boomLine'
import { generateAIBoomLines, runContainmentAnalysis, computePolylineLength, computeBearing } from '@common/utils/geo'
import type { Analysis } from '../analysis/AnalysisListTable'
import type { Analysis } from './AnalysisListTable'
interface LeftPanelProps {
selectedAnalysis?: Analysis | null

파일 보기

@ -1,18 +1,18 @@
import { useState, useEffect } from 'react'
import { LeftPanel } from '../layout/LeftPanel'
import { RightPanel } from '../layout/RightPanel'
import { MapView } from '../map/MapView'
import { AnalysisListTable, type Analysis } from '../analysis/AnalysisListTable'
import { OilSpillTheoryView } from '../analysis/OilSpillTheoryView'
import { BoomDeploymentTheoryView } from '../analysis/BoomDeploymentTheoryView'
import { BacktrackModal } from '../analysis/BacktrackModal'
import { RecalcModal } from '../analysis/RecalcModal'
import { BacktrackReplayBar } from '../map/BacktrackReplayBar'
import { LeftPanel } from './LeftPanel'
import { RightPanel } from './RightPanel'
import { MapView } from '@common/components/map/MapView'
import { AnalysisListTable, type Analysis } from './AnalysisListTable'
import { OilSpillTheoryView } from './OilSpillTheoryView'
import { BoomDeploymentTheoryView } from './BoomDeploymentTheoryView'
import { BacktrackModal } from './BacktrackModal'
import { RecalcModal } from './RecalcModal'
import { BacktrackReplayBar } from '@common/components/map/BacktrackReplayBar'
import { useSubMenu, navigateToTab, setReportGenCategory } from '@common/hooks/useSubMenu'
import type { BoomLine, AlgorithmSettings, ContainmentResult, BoomLineCoord } from '@common/types/boomLine'
import type { BacktrackPhase, BacktrackVessel } from '@common/types/backtrack'
import { TOTAL_REPLAY_FRAMES } from '@common/types/backtrack'
import { MOCK_CONDITIONS, MOCK_VESSELS, MOCK_REPLAY_SHIPS, MOCK_COLLISION } from '../../data/backtrackMockData'
import { MOCK_CONDITIONS, MOCK_VESSELS, MOCK_REPLAY_SHIPS, MOCK_COLLISION } from '../../../data/backtrackMockData'
export type PredictionModel = 'KOSPS' | 'POSEIDON' | 'OpenDrift'
// eslint-disable-next-line react-refresh/only-export-components

파일 보기

@ -1,5 +1,5 @@
import { useState, useRef, useEffect } from 'react'
import type { PredictionModel } from '../views/OilSpillView'
import type { PredictionModel } from './OilSpillView'
interface RecalcModalProps {
isOpen: boolean

파일 보기

@ -0,0 +1 @@
export { OilSpillView } from './components/OilSpillView'

파일 보기

@ -8,7 +8,7 @@ import {
type OilSpillReportData,
type ReportType,
type Jurisdiction,
} from '../reports/OilSpillReportTemplate'
} from './OilSpillReportTemplate'
import { sanitizeHtml } from '@common/utils/sanitize'
import { useSubMenu, consumeReportGenCategory } from '@common/hooks/useSubMenu'

파일 보기

@ -0,0 +1 @@
export { ReportsView } from './components/ReportsView'

파일 보기

@ -1,7 +1,7 @@
import { useState, useEffect } from 'react'
import { useSubMenu } from '@common/hooks/useSubMenu'
import { RescueTheoryView } from '../analysis/RescueTheoryView'
import { RescueScenarioView } from '../analysis/RescueScenarioView'
import { RescueTheoryView } from './RescueTheoryView'
import { RescueScenarioView } from './RescueScenarioView'
/* ─── Types ─── */
type AccidentType = 'collision' | 'grounding' | 'turning' | 'capsizing' | 'sharpTurn' | 'flooding' | 'sinking'

파일 보기

@ -0,0 +1 @@
export { RescueView } from './components/RescueView'

파일 보기

@ -1,7 +1,7 @@
import { ImageOverlay, useMap } from 'react-leaflet'
import { LatLngBounds } from 'leaflet'
import { useEffect, useState } from 'react'
import type { OceanForecastData } from '../../services/khoaApi'
import type { OceanForecastData } from '../services/khoaApi'
interface OceanForecastOverlayProps {
forecast: OceanForecastData | null

파일 보기

@ -2,14 +2,14 @@ import { useState, useEffect } from 'react'
import { MapContainer, TileLayer, useMapEvents } from 'react-leaflet'
import type { LatLngExpression } from 'leaflet'
import 'leaflet/dist/leaflet.css'
import { WeatherRightPanel } from '../weather/WeatherRightPanel'
import { WeatherMapOverlay } from '../weather/WeatherMapOverlay'
import { OceanForecastOverlay } from '../weather/OceanForecastOverlay'
import { OceanCurrentLayer } from '../weather/OceanCurrentLayer'
import { WaterTemperatureLayer } from '../weather/WaterTemperatureLayer'
import { WindParticleLayer } from '../weather/WindParticleLayer'
import { useWeatherData } from '../../hooks/useWeatherData'
import { useOceanForecast } from '../../hooks/useOceanForecast'
import { WeatherRightPanel } from './WeatherRightPanel'
import { WeatherMapOverlay } from './WeatherMapOverlay'
import { OceanForecastOverlay } from './OceanForecastOverlay'
import { OceanCurrentLayer } from './OceanCurrentLayer'
import { WaterTemperatureLayer } from './WaterTemperatureLayer'
import { WindParticleLayer } from './WindParticleLayer'
import { useWeatherData } from '../hooks/useWeatherData'
import { useOceanForecast } from '../hooks/useOceanForecast'
type TimeOffset = '0' | '3' | '6' | '9'

파일 보기

@ -0,0 +1 @@
export { WeatherView } from './components/WeatherView'