import { useState, useEffect, useCallback } from 'react' import type { Dispatch, SetStateAction } from 'react' import { fetchHnsAnalyses, type HnsAnalysisItem } from '../services/hnsApi' interface HNSAnalysisListTableProps { onTabChange: Dispatch> } const RISK_LABEL: Record = { CRITICAL: '심각', HIGH: '위험', MEDIUM: '경고', LOW: '관찰', } const RISK_STYLE: Record = { CRITICAL: { bg: 'rgba(239,68,68,0.2)', color: 'var(--red)' }, HIGH: { bg: 'rgba(239,68,68,0.15)', color: 'var(--red)' }, MEDIUM: { bg: 'rgba(249,115,22,0.15)', color: 'var(--orange)' }, LOW: { bg: 'rgba(34,197,94,0.15)', color: 'var(--green)' }, } function formatDate(dtm: string | null, mode: 'full' | 'date') { if (!dtm) return '—' const d = new Date(dtm) if (mode === 'date') return d.toISOString().slice(0, 10) return d.toISOString().slice(0, 16).replace('T', ' ') } function substanceTag(sbstNm: string | null): string { if (!sbstNm) return '—' const match = sbstNm.match(/\(([^)]+)\)/) if (match) return match[1] return sbstNm.length > 6 ? sbstNm.slice(0, 6) : sbstNm } export function HNSAnalysisListTable({ onTabChange }: HNSAnalysisListTableProps) { const [analyses, setAnalyses] = useState([]) const [loading, setLoading] = useState(true) const loadData = useCallback(async () => { setLoading(true) try { const items = await fetchHnsAnalyses() setAnalyses(items) } catch (err) { console.error('[hns] 분석 목록 조회 실패:', err) } finally { setLoading(false) } }, []) useEffect(() => { loadData() }, [loadData]) return (
{/* Header */}
📋 HNS 대기확산 분석 목록
총 {analyses.length}건
{/* Table */}
{loading ? (
로딩 중...
) : ( {analyses.map((item, index) => { const rslt = item.rsltData as Record | null const riskLabel = RISK_LABEL[item.riskCd || ''] || item.riskCd || '—' const riskStyle = RISK_STYLE[item.riskCd || ''] || { bg: 'rgba(100,100,100,0.1)', color: 'var(--t3)' } const aegl3 = rslt?.aegl3 as boolean | undefined const aegl2 = rslt?.aegl2 as boolean | undefined const aegl1 = rslt?.aegl1 as boolean | undefined const damageRadius = (rslt?.damageRadius as string) || '—' const amount = item.spilQty != null ? `${item.spilQty} ${item.spilUnitCd || 'KL'}` : '—' return ( e.currentTarget.style.background = 'var(--bg2)'} onMouseLeave={(e) => e.currentTarget.style.background = index % 2 === 0 ? 'transparent' : 'rgba(255,255,255,0.01)'} > ) })}
번호 분석명 물질 사고일시 분석날짜 사고지점 유출량 알고리즘 예측시간
AEGL-3 생명위협
AEGL-2 건강피해
AEGL-1 불쾌감
위험등급 피해반경 분석자
{item.hnsAnlysSn} {item.anlysNm} {substanceTag(item.sbstNm)} {formatDate(item.acdntDtm, 'full')} {formatDate(item.regDtm, 'date')} {item.locNm || '—'} {amount} {item.algoCd || '—'} {item.fcstHr ? `${item.fcstHr}H` : '—'}
{riskLabel} {damageRadius} {item.analystNm || '—'}
)} {!loading && analyses.length === 0 && (
분석 데이터가 없습니다.
)}
) }