import { useState } from 'react' import type { LeftPanelProps, ExpandedSections } from './leftPanelTypes' import PredictionInputSection from './PredictionInputSection' import InfoLayerSection from './InfoLayerSection' import OilBoomSection from './OilBoomSection' export type { LeftPanelProps } export function LeftPanel({ selectedAnalysis, enabledLayers, onToggleLayer, accidentTime, onAccidentTimeChange, incidentCoord, onCoordChange, isSelectingLocation, onMapSelectClick, onRunSimulation, isRunningSimulation, selectedModels, onModelsChange, visibleModels, onVisibleModelsChange, hasResults, predictionTime, onPredictionTimeChange, spillType, onSpillTypeChange, oilType, onOilTypeChange, spillAmount, onSpillAmountChange, incidentName, onIncidentNameChange, spillUnit, onSpillUnitChange, boomLines, onBoomLinesChange, oilTrajectory, algorithmSettings, onAlgorithmSettingsChange, isDrawingBoom, onDrawingBoomChange, drawingPoints, onDrawingPointsChange, containmentResult, onContainmentResultChange, layerOpacity, onLayerOpacityChange, layerBrightness, onLayerBrightnessChange, sensitiveResources = [], onImageAnalysisResult, }: LeftPanelProps) { const [expandedSections, setExpandedSections] = useState({ predictionInput: true, incident: false, impactResources: false, infoLayer: false, oilBoom: false, }) const toggleSection = (section: keyof ExpandedSections) => { setExpandedSections(prev => ({ ...prev, [section]: !prev[section] })) } return (
{/* Scrollable Content */}
{/* Prediction Input Section */} toggleSection('predictionInput')} accidentTime={accidentTime} onAccidentTimeChange={onAccidentTimeChange} incidentCoord={incidentCoord} onCoordChange={onCoordChange} isSelectingLocation={isSelectingLocation} onMapSelectClick={onMapSelectClick} onRunSimulation={onRunSimulation} isRunningSimulation={isRunningSimulation} selectedModels={selectedModels} onModelsChange={onModelsChange} visibleModels={visibleModels} onVisibleModelsChange={onVisibleModelsChange} hasResults={hasResults} predictionTime={predictionTime} onPredictionTimeChange={onPredictionTimeChange} spillType={spillType} onSpillTypeChange={onSpillTypeChange} oilType={oilType} onOilTypeChange={onOilTypeChange} spillAmount={spillAmount} onSpillAmountChange={onSpillAmountChange} incidentName={incidentName} onIncidentNameChange={onIncidentNameChange} spillUnit={spillUnit} onSpillUnitChange={onSpillUnitChange} onImageAnalysisResult={onImageAnalysisResult} /> {/* Incident Section */}
toggleSection('incident')} className="flex items-center justify-between p-4 cursor-pointer hover:bg-[rgba(255,255,255,0.02)]" >

사고정보

{expandedSections.incident ? '▼' : '▶'}
{expandedSections.incident && ( selectedAnalysis ? (
{/* Status Badge */} {(() => { const statusMap: Record = { ACTIVE: { label: '진행중', style: 'bg-[rgba(239,68,68,0.15)] text-status-red border border-[rgba(239,68,68,0.3)]', dot: 'bg-status-red animate-pulse', }, INVESTIGATING: { label: '조사중', style: 'bg-[rgba(249,115,22,0.15)] text-status-orange border border-[rgba(249,115,22,0.3)]', dot: 'bg-status-orange animate-pulse', }, CLOSED: { label: '종료', style: 'bg-[rgba(100,116,139,0.15)] text-text-3 border border-[rgba(100,116,139,0.3)]', dot: 'bg-text-3', }, } const s = statusMap[selectedAnalysis.acdntSttsCd] ?? statusMap['ACTIVE'] return (
{s.label}
) })()} {/* Info Grid */}
사고코드 {selectedAnalysis.acdntSn}
사고명 {selectedAnalysis.acdntNm || '—'}
사고일시 {selectedAnalysis.occurredAt ? selectedAnalysis.occurredAt.slice(0, 16).replace(' ', 'T') : '—'}
유종 {selectedAnalysis.oilType || '—'}
유출량 {selectedAnalysis.volume != null ? `${selectedAnalysis.volume.toFixed(2)} kl` : '—'}
담당자 {selectedAnalysis.analyst || '—'}
위치 {selectedAnalysis.location || '—'}
) : (

선택된 사고정보가 없습니다.

) )}
{/* Impact Resources Section */}
toggleSection('impactResources')} className="flex items-center justify-between p-4 cursor-pointer hover:bg-[rgba(255,255,255,0.02)]" >

영향 민감자원

{expandedSections.impactResources ? '▼' : '▶'}
{expandedSections.impactResources && (
{sensitiveResources.length === 0 ? (

영향받는 민감자원 목록

) : (
{sensitiveResources.map(({ category, count }) => (
{category} {count}개
))}
)}
)}
{/* Info Layer Section */} toggleSection('infoLayer')} enabledLayers={enabledLayers} onToggleLayer={onToggleLayer} layerOpacity={layerOpacity} onLayerOpacityChange={onLayerOpacityChange} layerBrightness={layerBrightness} onLayerBrightnessChange={onLayerBrightnessChange} /> {/* Oil Boom Placement Guide Section */} toggleSection('oilBoom')} boomLines={boomLines} onBoomLinesChange={onBoomLinesChange} oilTrajectory={oilTrajectory} incidentCoord={incidentCoord ?? { lat: 0, lon: 0 }} algorithmSettings={algorithmSettings} onAlgorithmSettingsChange={onAlgorithmSettingsChange} isDrawingBoom={isDrawingBoom} onDrawingBoomChange={onDrawingBoomChange} drawingPoints={drawingPoints} onDrawingPointsChange={onDrawingPointsChange} containmentResult={containmentResult} onContainmentResultChange={onContainmentResultChange} />
) }