snp-sync-batch/frontend/src/components/Navbar.tsx
HYOJIN 2f64eae925 perf: 동기화 현황 데이터 로딩 속도 개선 (#9)
- SyncStatusService: 테이블당 2쿼리 → 1쿼리로 합침 (94→47 쿼리)
- ORDER BY 기준 mdfcn_dt → crt_dt 변경
- Caffeine 캐시 적용 (TTL 10분): syncStatus, syncDataPreview, syncStuckRecords
- 새로고침 버튼 시 전체 캐시 무효화 + DB 재조회
- 30초 폴링 제거 → 페이지 진입 1회 조회 + 수동 새로고침
- 네비게이션바 순서 변경: 대시보드 → 동기화 현황
- docs/create-sync-indexes.sql: std_snp_data + std_snp_svc 인덱스 DDL

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 15:01:48 +09:00

56 lines
2.1 KiB
TypeScript

import { Link, useLocation } from 'react-router-dom';
import { useThemeContext } from '../contexts/ThemeContext';
const navItems = [
{ path: '/', label: '대시보드', icon: '📊' },
{ path: '/sync-status', label: '동기화 현황', icon: '🔄' },
{ path: '/executions', label: '실행 이력', icon: '📋' },
{ path: '/jobs', label: '작업', icon: '⚙️' },
{ path: '/schedules', label: '스케줄', icon: '🕐' },
{ path: '/schedule-timeline', label: '타임라인', icon: '📅' },
];
export default function Navbar() {
const location = useLocation();
const { theme, toggle } = useThemeContext();
const isActive = (path: string) => {
if (path === '/') return location.pathname === '/';
return location.pathname.startsWith(path);
};
return (
<nav className="bg-wing-glass-dense backdrop-blur-sm shadow-md rounded-xl mb-6 px-4 py-3 border border-wing-border">
<div className="flex items-center justify-between flex-wrap gap-2">
<Link to="/" className="text-lg font-bold text-wing-accent no-underline">
S&P
</Link>
<div className="flex gap-1 flex-wrap items-center">
{navItems.map((item) => (
<Link
key={item.path}
to={item.path}
className={`px-3 py-1.5 rounded-lg text-sm font-medium no-underline transition-colors
${isActive(item.path)
? 'bg-wing-accent text-white'
: 'text-wing-muted hover:bg-wing-hover hover:text-wing-accent'
}`}
>
<span className="mr-1">{item.icon}</span>
{item.label}
</Link>
))}
<button
onClick={toggle}
className="ml-2 px-2.5 py-1.5 rounded-lg text-sm bg-wing-card text-wing-muted
hover:text-wing-text border border-wing-border transition-colors"
title={theme === 'dark' ? '라이트 모드' : '다크 모드'}
>
{theme === 'dark' ? '☀️' : '🌙'}
</button>
</div>
</div>
</nav>
);
}