"use client" import { useState, useEffect } from "react"; import { SidebarTrigger } from "@/components/ui/sidebar"; import { Separator } from "@/components/ui/separator"; import { Button } from "@/components/ui/button"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog"; import { Avatar, AvatarFallback } from "@/components/ui/avatar"; import { Badge } from "@/components/ui/badge"; import { Moon, Sun, LogOut, User, Search, Globe, Copy } from "lucide-react"; import { useTheme } from "next-themes"; import { toast } from "sonner"; import { useAuthStore } from "@/stores/auth-store"; import { CommandPalette, openCommandPalette } from "@/components/layout/command-palette"; import { AppBreadcrumbs } from "@/components/layout/breadcrumbs"; import { QuickActions } from "@/components/layout/quick-actions"; import { NotificationsPanel } from "@/components/layout/notifications-panel"; const pageTitles: Record = { "/": "Dashboard", "/catalog": "Catalog", "/users": "Users", "/wallets": "Wallets", "/purchases": "Purchases", "/audit": "Audit Log", "/categories": "Categories", "/locations": "Locations", "/settings": "Settings", "/locales": "Locales", "/seed": "Danger Zone", "/login": "Sign In", }; function getInitialTime() { const now = new Date(); const hh = String(now.getHours()).padStart(2, "0"); const mm = String(now.getMinutes()).padStart(2, "0"); return `${hh}:${mm}`; } function RealtimeClock() { const [time, setTime] = useState(getInitialTime); useEffect(() => { const interval = setInterval(() => { const now = new Date(); const hh = String(now.getHours()).padStart(2, "0"); const mm = String(now.getMinutes()).padStart(2, "0"); setTime(`${hh}:${mm}`); }, 1000); return () => clearInterval(interval); }, []); const parts = time.split(":"); return ( {parts[0]}:{parts[1]} ); } export function AdminHeader() { const [hash, setHash] = useState(""); const { theme, setTheme } = useTheme(); const { role, logout } = useAuthStore(); const [logoutOpen, setLogoutOpen] = useState(false); const [onion, setOnion] = useState(""); useEffect(() => { const update = () => setHash(window.location.hash.slice(1) || "/"); update(); window.addEventListener("hashchange", update); return () => window.removeEventListener("hashchange", update); }, []); useEffect(() => { let cancelled = false; (async () => { try { const res = await fetch("/api/system/info"); if (!res.ok) throw new Error("Failed to fetch system info"); const data = await res.json(); if (cancelled) return; setOnion(data.adminOnion || ""); } catch { if (cancelled) return; setOnion(""); } })(); return () => { cancelled = true; }; }, []); const copyOnion = async () => { if (!onion) return; try { await navigator.clipboard.writeText(onion); toast.success("Onion address copied"); } catch { toast.error("Failed to copy onion address"); } }; const title = pageTitles[hash] || (hash.startsWith("/users/") ? "User Detail" : hash.split("/").pop()?.charAt(0).toUpperCase() + hash.split("/").pop()?.slice(1) || "Page"); return (

{title}

{/* 1. Clock (hidden on mobile) */} {/* 1b. Onion host badge (hidden on mobile) */} {/* 2. Command palette search button */} {/* 3. Notifications bell button */} {/* 4. Quick actions zap button */} {/* 5. Theme toggle */} {/* 6. User dropdown */}

{role === "super_admin" ? "Super Admin" : "Admin"}

{role}
{ window.location.hash = "/settings"; }}> Settings setLogoutOpen(true)} className="text-destructive" > Sign out
Sign out Are you sure you want to sign out? You will need to re-enter your admin token. Cancel { logout(); window.location.hash = "/login"; }} className="bg-destructive text-white hover:bg-destructive/90" > Sign out
); }