feat: 헤더에 사용자 표시·로그아웃 버튼 추가
로그인 사용자명(관리자 배지, API 키면 '운영자') 표시 → /account 링크. 로그아웃은 localStorage api_key 제거 후 로그인 화면으로. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user