wing-ops/frontend/src/tabs/hns/components/HNSRightPanel.tsx
htlee 3fc8f03238 refactor(css): 인라인 스타일 → Tailwind 유틸리티 클래스 변환 (Phase 2, ~990건)
Phase 2: 정적 인라인 스타일을 Tailwind className으로 변환
- common/: MapView, BacktrackReplayBar, LoginPage, LayerTree, ComboBox, SubMenuBar
- hns/: HNSSubstanceView, HNSScenarioView, HNSView, HNSLeftPanel 등 8파일
- prediction/: BoomDeploymentTheoryView, OilBoomSection, RecalcModal, RightPanel 등 8파일
- incidents/: IncidentsView, IncidentsLeftPanel, IncidentsRightPanel
- rescue/: RescueScenarioView
- aerial/: SatelliteRequest, AerialTheoryView
- assets/: ShipInsurance, AssetTheory, AssetManagement 등 5파일
- board/: BoardView
- reports/: ReportsView, OilSpillReportTemplate, ReportGenerator
- weather/: WeatherMapOverlay, WeatherView, WeatherRightPanel

변환 패턴: color/background/border/borderRadius/display/flex/gap/fontSize/fontWeight → Tailwind
동적 스타일(rgba, gradient, 삼항 조건부, 런타임 변수)은 style prop에 유지
JS 번들: 2,921KB → 2,897KB (-24KB)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 11:24:13 +09:00

144 lines
5.0 KiB
TypeScript
Executable File

interface HNSRightPanelProps {
dispersionResult: {
zones: Array<{
level: string
color: string
radius: number
angle: number
}>
timestamp: string
windDirection: number
substance: string
concentration: {
'AEGL-3': string
'AEGL-2': string
'AEGL-1': string
}
} | null
onOpenRecalc?: () => void
onOpenReport?: () => void
}
export function HNSRightPanel({ dispersionResult, onOpenRecalc, onOpenReport }: HNSRightPanelProps) {
if (!dispersionResult) {
return (
<div className="w-[300px] bg-bg-1 border-l border-border p-4 overflow-auto">
<div className="flex flex-col gap-3 items-center justify-center h-full text-text-3 text-xs">
<div style={{ fontSize: '32px', opacity: 0.3 }}>📊</div>
<div> </div>
</div>
</div>
)
}
return (
<div className="w-[300px] bg-bg-1 border-l border-border p-4 overflow-auto flex flex-col gap-4">
{/* Header */}
<div>
<div className="flex items-center gap-1.5 mb-2">
<div style={{
width: '6px',
height: '6px',
borderRadius: '50%',
background: 'var(--orange)',
animation: 'pulse 1.5s infinite'
}}></div>
<h3 className="text-[13px] font-bold m-0">
</h3>
</div>
<div className="text-[10px] text-text-3 font-mono">
{dispersionResult.substance} · ALOHA v5.4.7
</div>
</div>
{/* KPI Cards */}
<div className="flex flex-col gap-2">
<div className="p-3 bg-bg-3 border border-[rgba(6,182,212,0.2)] rounded-[var(--rS)]">
<div className="text-[10px] text-text-3 mb-1.5">
</div>
<div className="text-[20px] font-bold font-mono text-primary-cyan">
8.2 <span className="text-[10px] font-medium">km²</span>
</div>
</div>
<div className="p-3 bg-bg-3 border border-[rgba(249,115,22,0.2)] rounded-[var(--rS)]">
<div className="text-[10px] text-text-3 mb-1.5">
</div>
<div className="text-[20px] font-bold font-mono text-status-orange">
2
</div>
</div>
<div className="p-3 bg-bg-3 border border-border rounded-[var(--rS)]">
<div className="text-[10px] text-text-3 mb-1.5">
</div>
<div className="text-[20px] font-bold font-mono">
5.2 <span className="text-[10px] font-medium">m/s</span>
</div>
</div>
<div className="p-3 bg-bg-3 border border-border rounded-[var(--rS)]">
<div className="text-[10px] text-text-3 mb-1.5">
</div>
<div className="text-[20px] font-bold font-mono">
SW <span className="text-[10px] font-medium">225°</span>
</div>
</div>
</div>
{/* Zone Details */}
<div>
<h4 className="text-[11px] font-semibold text-text-2 mt-0 mb-2.5">
</h4>
<div className="flex flex-col gap-2">
{dispersionResult.zones.map((zone, idx) => (
<div
key={idx}
className="py-2.5 px-3 bg-bg-2 rounded-[var(--rS)]"
style={{
borderLeft: `3px solid ${zone.color.replace('0.4', '1').replace('0.3', '1').replace('0.25', '1')}`
}}
>
<div className="flex justify-between items-center mb-1">
<span className="text-[11px] font-semibold">
{zone.level}
</span>
<span className="text-[10px] font-mono text-text-3">
{zone.radius}m
</span>
</div>
<div className="text-[10px] text-text-3">
{dispersionResult.concentration[zone.level as keyof typeof dispersionResult.concentration]}
</div>
</div>
))}
</div>
</div>
{/* Timestamp */}
<div className="mt-auto pt-3 border-t border-border text-[10px] text-text-3 font-mono">
: {new Date(dispersionResult.timestamp).toLocaleString('ko-KR')}
</div>
{/* Bottom Action Buttons */}
<div className="flex gap-1.5 pt-3 border-t border-border">
<button className="flex-1 py-2 px-1 rounded text-[11px] font-semibold bg-gradient-to-r from-boom to-[#d97706] text-black font-korean">
💾
</button>
<button onClick={onOpenRecalc} className="flex-1 py-2 px-1 rounded text-[11px] font-semibold bg-[rgba(249,115,22,0.1)] border border-[rgba(249,115,22,0.3)] text-status-orange font-korean">
🔄
</button>
<button onClick={onOpenReport} className="flex-1 py-2 px-1 rounded text-[11px] font-semibold bg-gradient-to-r from-primary-cyan to-primary-blue text-white font-korean">
📄
</button>
</div>
</div>
)
}