- SensorChart: 히스토리 1H/2H/3H/6H, 기압 SLP 보정, 데이터 범위 확장(y축 시작) - SensorChart Tooltip: KST 시간 포맷, 위치 상단 고정, 스타일 통일 - 지진 포인트 클릭 → 지도 flyTo + SeismicMarker 진도별 펄스 원형 표시 - SatelliteMap flyTo 지원 추가 - OilFacilityLayer: planned ring SVG 내부로 이동 (아이콘 중심 정렬 수정) - 밝은 테마 text-shadow CSS 변수 분리 (dark/light) - deploy.yml: SSH SCP+실행 각 3회 재시도 (kex_exchange 거부 대응) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
81 lines
2.3 KiB
TypeScript
81 lines
2.3 KiB
TypeScript
import { useTranslation } from 'react-i18next';
|
|
|
|
interface Props {
|
|
currentTime: number;
|
|
historyMinutes: number;
|
|
onHistoryChange: (minutes: number) => void;
|
|
aircraftCount: number;
|
|
shipCount: number;
|
|
satelliteCount: number;
|
|
timeZone: 'KST' | 'UTC';
|
|
onTimeZoneChange: (tz: 'KST' | 'UTC') => void;
|
|
}
|
|
|
|
const HISTORY_PRESETS = [
|
|
{ label: '1H', minutes: 60 },
|
|
{ label: '2H', minutes: 120 },
|
|
{ label: '3H', minutes: 180 },
|
|
{ label: '6H', minutes: 360 },
|
|
];
|
|
|
|
function formatTime(epoch: number, tz: 'KST' | 'UTC'): string {
|
|
const d = new Date(epoch);
|
|
const pad = (n: number) => String(n).padStart(2, '0');
|
|
if (tz === 'UTC') {
|
|
return `${d.getUTCFullYear()}-${pad(d.getUTCMonth() + 1)}-${pad(d.getUTCDate())} ${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}:${pad(d.getUTCSeconds())}`;
|
|
}
|
|
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
|
|
}
|
|
|
|
export function LiveControls({
|
|
currentTime,
|
|
historyMinutes,
|
|
onHistoryChange,
|
|
timeZone,
|
|
onTimeZoneChange,
|
|
}: Props) {
|
|
const { t } = useTranslation();
|
|
|
|
return (
|
|
<div className="live-controls">
|
|
<div className="live-indicator">
|
|
<span className="live-dot" />
|
|
<span className="live-label">{t('header.live')}</span>
|
|
</div>
|
|
|
|
<div className="live-clock" style={{ display: 'flex', alignItems: 'center', gap: '6px' }}>
|
|
<span>{formatTime(currentTime, timeZone)}</span>
|
|
<div className="tz-radio-group">
|
|
{(['KST', 'UTC'] as const).map(tz => (
|
|
<button
|
|
key={tz}
|
|
type="button"
|
|
className={`tz-radio-btn ${timeZone === tz ? 'active' : ''}`}
|
|
onClick={() => onTimeZoneChange(tz)}
|
|
>
|
|
{tz}
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex-1" />
|
|
|
|
<div className="history-controls">
|
|
<span className="history-label">{t('time.history')}</span>
|
|
<div className="history-presets">
|
|
{HISTORY_PRESETS.map(p => (
|
|
<button
|
|
key={p.label}
|
|
className={`history-btn ${historyMinutes === p.minutes ? 'active' : ''}`}
|
|
onClick={() => onHistoryChange(p.minutes)}
|
|
>
|
|
{p.label}
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|