feat(electron): add Electron UI components and layout integration

This commit is contained in:
DrSmoothl
2026-03-03 00:54:24 +08:00
parent fc394f4412
commit 65774f3afc
8 changed files with 708 additions and 4 deletions

View File

@@ -1,10 +1,13 @@
import { BookOpen, ChevronLeft, LogOut, Menu, Moon, PieChart, Search, Sun } from 'lucide-react'
import { BookOpen, ChevronLeft, LogOut, Menu, Moon, PieChart, Search, Server, Sun } from 'lucide-react'
import { Link } from '@tanstack/react-router'
import { BackgroundLayer } from '@/components/background-layer'
import { Button } from '@/components/ui/button'
import { Kbd } from '@/components/ui/kbd'
import { SearchDialog } from '@/components/search-dialog'
import { useEffect, useState } from 'react'
import { BackendManager } from '@/components/electron/BackendManager'
import { isElectron } from '@/lib/runtime'
import { cn } from '@/lib/utils'
import { useBackground } from '@/hooks/use-background'
import { logout } from '@/lib/fetch-with-auth'
@@ -32,6 +35,15 @@ export function Header({
onThemeChange,
}: HeaderProps) {
const headerBg = useBackground('header')
const [backendManagerOpen, setBackendManagerOpen] = useState(false)
const [activeBackendName, setActiveBackendName] = useState<string>('')
useEffect(() => {
if (!isElectron()) return
window.electronAPI!.getActiveBackend().then((b) => {
setActiveBackendName(b?.name ?? '未连接')
})
}, [])
const handleLogout = async () => {
await logout()
@@ -62,6 +74,25 @@ export function Header({
</div>
<div className="flex items-center gap-2">
{/* 后端切换按钮(仅 Electron */}
{isElectron() && (
<>
<Button
variant="ghost"
size="sm"
className="gap-2"
onClick={() => setBackendManagerOpen(true)}
title="切换后端连接"
>
<Server className="h-4 w-4" />
<span className="hidden sm:inline text-xs text-muted-foreground truncate max-w-[100px]">
{activeBackendName}
</span>
</Button>
<BackendManager open={backendManagerOpen} onOpenChange={setBackendManagerOpen} />
<div className="h-6 w-px bg-border" />
</>
)}
{/* 年度总结入口 */}
<Link to="/annual-report">
<Button

View File

@@ -8,6 +8,9 @@ import { useTheme } from '@/components/use-theme'
import { useAuthGuard } from '@/hooks/use-auth'
import { useBackground } from '@/hooks/use-background'
import { TitleBar } from '@/components/electron/TitleBar'
import { isElectron } from '@/lib/runtime'
import { cn } from '@/lib/utils'
import { Header } from './Header'
import { Sidebar } from './Sidebar'
import type { LayoutProps } from './types'
@@ -70,7 +73,8 @@ export function Layout({ children }: LayoutProps) {
return (
<TooltipProvider delayDuration={300}>
<div className="flex h-screen overflow-hidden">
{isElectron() && <TitleBar />}
<div className={cn('flex h-screen overflow-hidden', isElectron() && 'pt-8')}>
{/* Sidebar */}
<Sidebar
sidebarOpen={sidebarOpen}
@@ -113,7 +117,7 @@ export function Layout({ children }: LayoutProps) {
{/* Back to Top Button */}
<BackToTop />
</div>
</div>
</div>
</TooltipProvider>
)
}