Files
zmb-webui/frontend/components/Header.tsx
T

268 lines
9.3 KiB
TypeScript

"use client"
import Link from "next/link"
import { usePathname, useRouter } from "next/navigation"
import { Button } from "@/components/ui/button"
import { HardDrive, Menu, LogOut } from "lucide-react"
import { useState, useEffect } from "react"
import { api } from "@/lib/api"
export function Header() {
const pathname = usePathname()
const router = useRouter()
const [isMenuOpen, setIsMenuOpen] = useState(false)
const [zfsAvailable, setZfsAvailable] = useState(false)
useEffect(() => {
const checkZfsAvailability = async () => {
const status = await api.getSystemStatus()
setZfsAvailable(status.zfs_available)
}
checkZfsAvailability()
}, [])
const handleLogout = async () => {
await api.logout()
router.push("/login")
}
const isActive = (path: string) => pathname === path
return (
<header className="sticky top-0 z-50 w-full border-b border-border bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex items-center justify-between h-16">
{/* Logo */}
<Link href="/" className="flex items-center gap-2 font-bold text-lg">
<HardDrive className="w-6 h-6" />
<span>ZMB Webui</span>
</Link>
{/* Desktop Navigation */}
<nav className="hidden md:flex items-center gap-1">
<Link
href="/"
className={`px-3 py-2 rounded-md text-sm font-medium transition-colors ${
isActive("/")
? "bg-accent text-accent-foreground"
: "text-muted-foreground hover:text-foreground"
}`}
>
Dashboard
</Link>
{zfsAvailable && (
<>
<Link
href="/snapshots"
className={`px-3 py-2 rounded-md text-sm font-medium transition-colors ${
isActive("/snapshots")
? "bg-accent text-accent-foreground"
: "text-muted-foreground hover:text-foreground"
}`}
>
Snapshots
</Link>
<Link
href="/datasets"
className={`px-3 py-2 rounded-md text-sm font-medium transition-colors ${
isActive("/datasets")
? "bg-accent text-accent-foreground"
: "text-muted-foreground hover:text-foreground"
}`}
>
Datasets
</Link>
</>
)}
<Link
href="/navigator"
className={`px-3 py-2 rounded-md text-sm font-medium transition-colors ${
isActive("/navigator")
? "bg-accent text-accent-foreground"
: "text-muted-foreground hover:text-foreground"
}`}
>
Navigator
</Link>
<Link
href="/shares"
className={`px-3 py-2 rounded-md text-sm font-medium transition-colors ${
isActive("/shares")
? "bg-accent text-accent-foreground"
: "text-muted-foreground hover:text-foreground"
}`}
>
Shares
</Link>
<Link
href="/file-sharing"
className={`px-3 py-2 rounded-md text-sm font-medium transition-colors ${
isActive("/file-sharing")
? "bg-accent text-accent-foreground"
: "text-muted-foreground hover:text-foreground"
}`}
>
File Sharing
</Link>
<Link
href="/identities"
className={`px-3 py-2 rounded-md text-sm font-medium transition-colors ${
isActive("/identities")
? "bg-accent text-accent-foreground"
: "text-muted-foreground hover:text-foreground"
}`}
>
Identities
</Link>
<Link
href="/logs"
className={`px-3 py-2 rounded-md text-sm font-medium transition-colors ${
isActive("/logs")
? "bg-accent text-accent-foreground"
: "text-muted-foreground hover:text-foreground"
}`}
>
Logs
</Link>
<Link
href="/services"
className={`px-3 py-2 rounded-md text-sm font-medium transition-colors ${
isActive("/services")
? "bg-accent text-accent-foreground"
: "text-muted-foreground hover:text-foreground"
}`}
>
Services
</Link>
</nav>
{/* Logout Button */}
<div className="flex items-center gap-2">
<Button variant="ghost" size="sm" onClick={handleLogout}>
<LogOut className="w-4 h-4 mr-2" />
<span className="hidden sm:inline">Logout</span>
</Button>
{/* Mobile Menu Button */}
<button
className="md:hidden p-2"
onClick={() => setIsMenuOpen(!isMenuOpen)}
>
<Menu className="w-6 h-6" />
</button>
</div>
</div>
{/* Mobile Navigation */}
{isMenuOpen && (
<nav className="md:hidden pb-4 space-y-1">
<Link
href="/"
className={`block px-3 py-2 rounded-md text-sm font-medium ${
isActive("/")
? "bg-accent text-accent-foreground"
: "text-muted-foreground hover:text-foreground"
}`}
onClick={() => setIsMenuOpen(false)}
>
Dashboard
</Link>
{zfsAvailable && (
<>
<Link
href="/snapshots"
className={`block px-3 py-2 rounded-md text-sm font-medium ${
isActive("/snapshots")
? "bg-accent text-accent-foreground"
: "text-muted-foreground hover:text-foreground"
}`}
onClick={() => setIsMenuOpen(false)}
>
Snapshots
</Link>
<Link
href="/datasets"
className={`block px-3 py-2 rounded-md text-sm font-medium ${
isActive("/datasets")
? "bg-accent text-accent-foreground"
: "text-muted-foreground hover:text-foreground"
}`}
onClick={() => setIsMenuOpen(false)}
>
Datasets
</Link>
</>
)}
<Link
href="/files"
className={`block px-3 py-2 rounded-md text-sm font-medium ${
isActive("/files")
? "bg-accent text-accent-foreground"
: "text-muted-foreground hover:text-foreground"
}`}
onClick={() => setIsMenuOpen(false)}
>
Files
</Link>
<Link
href="/shares"
className={`block px-3 py-2 rounded-md text-sm font-medium ${
isActive("/shares")
? "bg-accent text-accent-foreground"
: "text-muted-foreground hover:text-foreground"
}`}
onClick={() => setIsMenuOpen(false)}
>
Shares
</Link>
<Link
href="/file-sharing"
className={`block px-3 py-2 rounded-md text-sm font-medium ${
isActive("/file-sharing")
? "bg-accent text-accent-foreground"
: "text-muted-foreground hover:text-foreground"
}`}
onClick={() => setIsMenuOpen(false)}
>
File Sharing
</Link>
<Link
href="/identities"
className={`block px-3 py-2 rounded-md text-sm font-medium ${
isActive("/identities")
? "bg-accent text-accent-foreground"
: "text-muted-foreground hover:text-foreground"
}`}
onClick={() => setIsMenuOpen(false)}
>
Identities
</Link>
<Link
href="/logs"
className={`block px-3 py-2 rounded-md text-sm font-medium ${
isActive("/logs")
? "bg-accent text-accent-foreground"
: "text-muted-foreground hover:text-foreground"
}`}
onClick={() => setIsMenuOpen(false)}
>
Logs
</Link>
<Link
href="/services"
className={`block px-3 py-2 rounded-md text-sm font-medium ${
isActive("/services")
? "bg-accent text-accent-foreground"
: "text-muted-foreground hover:text-foreground"
}`}
onClick={() => setIsMenuOpen(false)}
>
Services
</Link>
</nav>
)}
</div>
</header>
)
}