import { useState } from 'react'
import type { PredictionDetail, SimulationSummary } from '../services/predictionApi'
export function RightPanel({ onOpenBacktrack, onOpenRecalc, onOpenReport, detail, summary }: { onOpenBacktrack?: () => void; onOpenRecalc?: () => void; onOpenReport?: () => void; detail?: PredictionDetail | null; summary?: SimulationSummary | null }) {
const vessel = detail?.vessels?.[0]
const vessel2 = detail?.vessels?.[1]
const spill = detail?.spill
const insurance = vessel?.insuranceData as Array<{ type: string; insurer: string; value: string; currency: string }> | null
const [shipExpanded, setShipExpanded] = useState(false)
const [insuranceExpanded, setInsuranceExpanded] = useState(false)
return (
{/* Tab Header */}
{/* Scrollable Content */}
{/* 표시 정보 제어 */}
유향/유속
풍향/풍속
해안부착
민감자원
시간 표시
날짜시간
{/* 오염분석 */}
{/* 오염 종합 상황 */}
{/* 확산 예측 요약 */}
{/* 유출유 풍화 상태 */}
{/* 사고 선박 제원 */}
setShipExpanded(!shipExpanded)}
>
{/* 선박 카드 */}
🚢
{vessel?.vesselNm || '—'}
IMO {vessel?.imoNo || '—'} · {vessel?.vesselTp || '—'}
사고
{/* 제원 */}
{/* 충돌 상대 */}
{vessel2 && (
⚠ 충돌 상대: {vessel2.vesselNm}
{vessel2.flagCd} {vessel2.vesselTp} {vessel2.gt ? `${vessel2.gt.toLocaleString()}GT` : ''}
)}
{/* 선주 / 보험 */}
setInsuranceExpanded(!insuranceExpanded)}
>
{insurance && insurance.length > 0 ? (
<>
{insurance.filter(ins => ins.type === 'P&I').map((ins, i) => (
))}
{insurance.filter(ins => ins.type === 'H&M').map((ins, i) => (
))}
{insurance.filter(ins => ins.type === 'CLC').map((ins, i) => (
))}
>
) : (
보험 정보가 없습니다.
)}
{/* Bottom Action Buttons */}
)
}
// Helper Components
function Section({
title,
badge,
badgeColor,
children
}: {
title: string
badge?: string
badgeColor?: 'red' | 'green'
children: React.ReactNode
}) {
return (
{title}
{badge && (
{badge}
)}
{children}
)
}
function CheckboxLabel({ checked, children }: { checked?: boolean; children: string }) {
return (
)
}
function StatBox({
label,
value,
unit,
color
}: {
label: string
value: string
unit: string
color: string
}) {
return (
{label}
{value} {unit}
)
}
function PredictionCard({ value, label, color }: { value: string; label: string; color: string }) {
return (
)
}
function ProgressBar({ label, value, color }: { label: string; value: number; color: string }) {
return (
)
}
function CollapsibleSection({
title,
expanded,
onToggle,
children
}: {
title: string
expanded: boolean
onToggle: () => void
children: React.ReactNode
}) {
return (
{title}
{expanded ? '▾' : '▸'}
{expanded && children}
)
}
function SpecCard({ value, label, color }: { value: string; label: string; color: string }) {
return (
)
}
function InfoRow({
label,
value,
mono,
valueColor
}: {
label: string
value: string
mono?: boolean
valueColor?: string
}) {
return (
{label}
{value}
)
}
function InsuranceCard({
title,
color,
items
}: {
title: string
color: 'cyan' | 'purple' | 'red'
items: Array<{ label: string; value: string; mono?: boolean; valueColor?: string }>
}) {
const colorMap = {
cyan: {
border: 'rgba(6,182,212,0.15)',
bg: 'rgba(6,182,212,0.02)',
text: 'var(--cyan)'
},
purple: {
border: 'rgba(168,85,247,0.15)',
bg: 'rgba(168,85,247,0.02)',
text: 'var(--purple)'
},
red: {
border: 'rgba(239,68,68,0.15)',
bg: 'rgba(239,68,68,0.02)',
text: 'var(--red)'
}
}
const colors = colorMap[color]
return (
{title}
{items.map((item, i) => (
{item.label}
{item.value}
))}
)
}