guardia-cms/frontend/src/components/Header.tsx
2026-07-04 08:23:28 +09:00

44 lines
1.8 KiB
TypeScript

import { useEffect, useState } from 'react'
import { useNavigate, Link } from 'react-router-dom'
import { LogOut, UserCircle } from 'lucide-react'
import { getAiStatus } from '../api/client'
export default function Header() {
const nav = useNavigate()
const user = localStorage.getItem('cms_user') || 'admin'
const role = localStorage.getItem('cms_role') || ''
const [ollama, setOllama] = useState<boolean | null>(null)
useEffect(() => {
getAiStatus().then(d => setOllama(!!d?.ollamaAvailable)).catch(() => setOllama(false))
}, [])
const logout = () => {
localStorage.removeItem('cms_token')
localStorage.removeItem('cms_role')
localStorage.removeItem('cms_user')
nav('/login')
}
return (
<header className="h-16 bg-panel border-b border-edge flex items-center justify-between px-6">
<div className="text-sm text-slate-400">AI · CMS · Ollama </div>
<div className="flex items-center gap-4">
<span className={`flex items-center gap-1.5 text-xs px-2 py-1 rounded-md border ${
ollama ? 'text-accent border-accent/30 bg-accent/10' : 'text-slate-400 border-edge bg-card'
}`}>
<span className={`w-1.5 h-1.5 rounded-full ${ollama ? 'bg-accent' : 'bg-slate-500'}`} />
AI {ollama === null ? '확인 중' : ollama ? '온라인' : '폴백'}
</span>
<Link to="/mypage" className="flex items-center gap-1.5 text-sm text-slate-300 hover:text-brand" title="마이페이지">
<UserCircle size={18} /> {user}
{role && <span className="text-[11px] text-slate-500">({role})</span>}
</Link>
<button onClick={logout} className="flex items-center gap-1.5 text-sm text-slate-400 hover:text-brand">
<LogOut size={16} />
</button>
</div>
</header>
)
}