Merge branch 'dev' into main — 헤더 로그아웃

This commit is contained in:
2026-09-21 10:40:50 +09:00

View File

@@ -14,9 +14,10 @@
* [Main] — 페이지 컨텐츠 영역 * [Main] — 페이지 컨텐츠 영역
*/ */
import { Link, useLocation } from 'react-router-dom' import { Link, useLocation } from 'react-router-dom'
import { LayoutDashboard, History, Cpu, Activity, SlidersHorizontal, BarChart3, TrendingUp, KeyRound } from 'lucide-react' import { LayoutDashboard, History, Cpu, Activity, SlidersHorizontal, BarChart3, TrendingUp, KeyRound, LogOut, User as UserIcon } from 'lucide-react'
import { useQuery } from '@tanstack/react-query' import { useQuery } from '@tanstack/react-query'
import api from '../lib/api' import api from '../lib/api'
import { useTenantMode } from '../lib/tenant'
/** Layout Props 정의 */ /** Layout Props 정의 */
interface LayoutProps { interface LayoutProps {
@@ -59,6 +60,15 @@ const Layout = ({ children }: LayoutProps) => {
}) })
/** 네비게이션 메뉴 항목 (경로, 아이콘, 레이블) */ /** 네비게이션 메뉴 항목 (경로, 아이콘, 레이블) */
// 현재 로그인 주체(세션 사용자 or API 키) — 헤더 표시·로그아웃용
const { me } = useTenantMode()
/** 로그아웃: 저장된 세션 토큰/API 키 제거 후 로그인 화면으로 (App 이 localStorage 로 인증 판단) */
const handleLogout = () => {
localStorage.removeItem('api_key')
window.location.href = '/'
}
const navItems = [ const navItems = [
{ path: '/', icon: LayoutDashboard, label: '대시보드' }, { path: '/', icon: LayoutDashboard, label: '대시보드' },
{ path: '/analysis', icon: TrendingUp, label: '성과 분석' }, { path: '/analysis', icon: TrendingUp, label: '성과 분석' },
@@ -114,6 +124,33 @@ const Layout = ({ children }: LayoutProps) => {
<div className={`w-2 h-2 rounded-full ${mcpStatus?.status === 'connected' ? 'bg-blue-500 shadow-[0_0_8px_rgba(59,130,246,0.5)]' : 'bg-yellow-500'}`} /> <div className={`w-2 h-2 rounded-full ${mcpStatus?.status === 'connected' ? 'bg-blue-500 shadow-[0_0_8px_rgba(59,130,246,0.5)]' : 'bg-yellow-500'}`} />
<span className="text-xs text-gray-400">MCP: {mcpStatus?.status || 'Unknown'}</span> <span className="text-xs text-gray-400">MCP: {mcpStatus?.status || 'Unknown'}</span>
</div> </div>
{/* 사용자 · 로그아웃 */}
<div className="flex items-center gap-1 pl-3 border-l border-gray-800">
<Link
to="/account"
className="flex items-center gap-1.5 px-2 py-1.5 rounded-lg text-xs text-gray-300 hover:bg-gray-800/60 transition-colors"
title="내 계좌 설정"
>
<UserIcon size={14} className="text-gray-500" />
<span className="max-w-[120px] truncate">
{me ? (me.auth_type === 'api_key' ? '운영자 (API 키)' : me.username) : '…'}
</span>
{me?.is_admin && me.auth_type === 'session' && (
<span className="text-[10px] px-1.5 py-0.5 rounded bg-blue-500/15 text-blue-300">관리자</span>
)}
</Link>
<button
type="button"
onClick={handleLogout}
className="flex items-center gap-1.5 px-2 py-1.5 rounded-lg text-xs text-gray-400 hover:text-red-300 hover:bg-red-500/10 transition-colors"
title="로그아웃"
aria-label="로그아웃"
>
<LogOut size={14} />
<span className="hidden sm:inline">로그아웃</span>
</button>
</div>
</div> </div>
</header> </header>