import { useMemo, useState } from 'react'; import { Marker, Popup } from 'react-map-gl/maplibre'; import { damagedShips } from '../data/damagedShips'; import type { DamagedShip } from '../data/damagedShips'; interface Props { currentTime: number; } const FLAG_EMOJI: Record = { GR: '\u{1F1EC}\u{1F1F7}', JP: '\u{1F1EF}\u{1F1F5}', KR: '\u{1F1F0}\u{1F1F7}', IR: '\u{1F1EE}\u{1F1F7}', US: '\u{1F1FA}\u{1F1F8}', UK: '\u{1F1EC}\u{1F1E7}', PA: '\u{1F1F5}\u{1F1E6}', LR: '\u{1F1F1}\u{1F1F7}', CN: '\u{1F1E8}\u{1F1F3}', }; const DAMAGE_COLORS: Record = { sunk: '#ff0000', severe: '#ef4444', moderate: '#f97316', minor: '#eab308', }; const DAMAGE_LABELS: Record = { sunk: '침몰', severe: '중파', moderate: '중손', minor: '경미', }; const KST_OFFSET = 9 * 3600_000; function formatKST(ts: number): string { const d = new Date(ts + KST_OFFSET); return `${d.getUTCMonth() + 1}/${d.getUTCDate()} ${String(d.getUTCHours()).padStart(2, '0')}:${String(d.getUTCMinutes()).padStart(2, '0')} KST`; } export function DamagedShipLayer({ currentTime }: Props) { const [selectedId, setSelectedId] = useState(null); const visible = useMemo( () => damagedShips.filter(s => currentTime >= s.damagedAt), [currentTime], ); const selected = selectedId ? visible.find(s => s.id === selectedId) ?? null : null; return ( <> {visible.map(ship => { const color = DAMAGE_COLORS[ship.damage]; const isSunk = ship.damage === 'sunk'; const ageH = (currentTime - ship.damagedAt) / 3600_000; const isRecent = ageH <= 24; const size = isRecent ? 28 : 22; const c = size / 2; return (
{ e.stopPropagation(); setSelectedId(ship.id); }} > {/* outer ring */} {/* ship icon (simplified) */} {/* X mark for damage */} {/* inner X in color */} {/* label */}
{isRecent && NEW} {ship.name}
{/* pulse for recent */} {isRecent && (
)}
); })} {selected && ( setSelectedId(null)} closeOnClick={false} anchor="bottom" maxWidth="320px" className="gl-popup">
{FLAG_EMOJI[selected.flag] && {FLAG_EMOJI[selected.flag]}} {selected.name} {DAMAGE_LABELS[selected.damage]}
선종 : {selected.type}
국적 : {selected.flag}
원인 : {selected.cause}
피격 : {formatKST(selected.damagedAt)}
{selected.description}
)} ); }