import { useState, useEffect, useCallback } from 'react'; import { useReplay } from './hooks/useReplay'; import { useMonitor } from './hooks/useMonitor'; import { useLocalStorage } from './hooks/useLocalStorage'; import type { AppMode } from './types'; import { useTheme } from './hooks/useTheme'; import { useAuth } from './hooks/useAuth'; import { useTranslation } from 'react-i18next'; import LoginPage from './components/auth/LoginPage'; import CollectorMonitor from './components/common/CollectorMonitor'; import { SharedFilterProvider } from './contexts/SharedFilterContext'; import { FontScaleProvider } from './contexts/FontScaleContext'; import { SymbolScaleProvider } from './contexts/SymbolScaleContext'; import { IranDashboard } from './components/iran/IranDashboard'; import { KoreaDashboard } from './components/korea/KoreaDashboard'; import './App.css'; function App() { const { user, isLoading: authLoading, isAuthenticated, login, devLogin, logout } = useAuth(); if (authLoading) { return (
Loading...
); } if (!isAuthenticated) { return ; } return ; } interface AuthenticatedAppProps { user: { email: string; name: string; picture?: string } | null; onLogout: () => Promise; } function AuthenticatedApp({ user, onLogout }: AuthenticatedAppProps) { const [appMode, setAppMode] = useState('live'); const [dashboardTab, setDashboardTab] = useLocalStorage<'iran' | 'korea'>('dashboardTab', 'iran'); const [showCollectorMonitor, setShowCollectorMonitor] = useState(false); const [timeZone, setTimeZone] = useState<'KST' | 'UTC'>('KST'); // 1시간마다 전체 데이터 강제 리프레시 const [refreshKey, setRefreshKey] = useState(0); useEffect(() => { const HOUR_MS = 3600_000; const interval = setInterval(() => setRefreshKey(k => k + 1), HOUR_MS); return () => clearInterval(interval); }, []); const replay = useReplay(); const monitor = useMonitor(); const { theme, toggleTheme } = useTheme(); const { t, i18n } = useTranslation(); const toggleLang = useCallback(() => { i18n.changeLanguage(i18n.language === 'ko' ? 'en' : 'ko'); }, [i18n]); const isLive = appMode === 'live'; const currentTime = isLive ? monitor.state.currentTime : replay.state.currentTime; return (
{/* Dashboard Tabs */}
{/* 탭별 모드/필터 영역 — 각 대시보드가 headerSlot으로 렌더링 */}
FLOW
{isLive ? t('header.live') : replay.state.isPlaying ? t('header.replaying') : t('header.paused')}
{user && (
{user.picture && ( )} {user.name}
)}
{dashboardTab === 'iran' && ( )} {dashboardTab === 'korea' && ( )} {showCollectorMonitor && ( setShowCollectorMonitor(false)} /> )}
); } export default App;