feat(header): Display active S2A profile information in header
- Add Server icon import from lucide-react for profile display - Import useConfig hook and S2AProfile type for configuration access - Implement activeProfile state to track currently selected S2A profile - Add useEffect hook to fetch and match S2A profiles against current API base configuration - Replace spacer div with active profile information display component - Show profile name and API base URL when profile is matched - Display API base URL directly when configured but profile not found - Add responsive styling with dark mode support for profile info badge - Use truncation and flex-shrink to prevent layout overflow on smaller screens - Provides users with clear visibility of which S2A profile is currently active
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import { Menu, Moon, Sun, Database, UserPlus } from 'lucide-react'
|
||||
import { Menu, Moon, Sun, Database, UserPlus, Server } from 'lucide-react'
|
||||
import { useState, useEffect } from 'react'
|
||||
import { useTeamStatus } from '../../hooks/useTeamStatus'
|
||||
import { useConfig } from '../../hooks/useConfig'
|
||||
import type { S2AProfile } from '../../types'
|
||||
|
||||
interface HeaderProps {
|
||||
onMenuClick: () => void
|
||||
@@ -10,6 +12,25 @@ interface HeaderProps {
|
||||
export default function Header({ onMenuClick, isConnected = false }: HeaderProps) {
|
||||
const [isDark, setIsDark] = useState(false)
|
||||
const teamStatus = useTeamStatus()
|
||||
const { config } = useConfig()
|
||||
const [activeProfile, setActiveProfile] = useState<S2AProfile | null>(null)
|
||||
|
||||
// 匹配当前活动配置对应的 profile 名称
|
||||
useEffect(() => {
|
||||
if (!config.s2a.apiBase) {
|
||||
setActiveProfile(null)
|
||||
return
|
||||
}
|
||||
fetch('/api/s2a/profiles')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if (data.code === 0 && data.data) {
|
||||
const match = (data.data as S2AProfile[]).find(p => p.api_base === config.s2a.apiBase)
|
||||
setActiveProfile(match || null)
|
||||
}
|
||||
})
|
||||
.catch(() => setActiveProfile(null))
|
||||
}, [config.s2a.apiBase])
|
||||
|
||||
useEffect(() => {
|
||||
// Check for saved theme preference or system preference
|
||||
@@ -54,8 +75,21 @@ export default function Header({ onMenuClick, isConnected = false }: HeaderProps
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Spacer */}
|
||||
<div className="flex-1" />
|
||||
{/* Active S2A Profile Info */}
|
||||
<div className="flex-1 flex items-center justify-start min-w-0">
|
||||
{activeProfile ? (
|
||||
<div className="flex items-center gap-2 min-w-0 px-2.5 py-1 rounded-lg bg-slate-50 dark:bg-slate-800/50 border border-slate-200/50 dark:border-slate-700/50">
|
||||
<Server className="h-3.5 w-3.5 text-blue-500 flex-shrink-0" />
|
||||
<span className="text-sm font-medium text-slate-700 dark:text-slate-300 truncate">{activeProfile.name}</span>
|
||||
<span className="hidden md:inline text-xs text-slate-400 dark:text-slate-500 truncate">{activeProfile.api_base}</span>
|
||||
</div>
|
||||
) : config.s2a.apiBase ? (
|
||||
<div className="flex items-center gap-2 min-w-0 px-2.5 py-1 rounded-lg bg-slate-50 dark:bg-slate-800/50 border border-slate-200/50 dark:border-slate-700/50">
|
||||
<Server className="h-3.5 w-3.5 text-slate-400 flex-shrink-0" />
|
||||
<span className="hidden md:inline text-xs text-slate-400 dark:text-slate-500 truncate">{config.s2a.apiBase}</span>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
{/* Team Status Indicators */}
|
||||
{teamStatus.isProcessing && (
|
||||
|
||||
Reference in New Issue
Block a user