import { useState, useEffect } from "react"; import { useTranslation } from "react-i18next"; import { Clock, Hammer, KeyRound, LayoutPanelLeft, Network, Play, Plug, Server, Settings, User, Zap, } from "lucide-react"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/dropdown-menu"; import type { SplitMode, TabType, ToolsTab } from "@/types/ui-types"; export type RailView = | "hosts" | "credentials" | "quick-connect" | ToolsTab | "connections" | "user-profile" | "admin-settings"; type RailItem = | { kind?: undefined; view: RailView; icon: React.ReactNode; title: string; dot?: boolean; } | { kind: "tab"; tabType: TabType; icon: React.ReactNode; title: string } | { kind: "separator" }; function buildRailButtons( splitMode: SplitMode, t: (key: string) => string, connectionCount: number, ): RailItem[] { return [ { view: "hosts", icon: , title: t("nav.hosts") }, { view: "credentials", icon: , title: t("nav.credentials"), }, { kind: "separator" }, { view: "connections", icon: , title: t("nav.connections"), }, { kind: "separator" }, { view: "quick-connect", icon: , title: t("nav.quickConnect"), }, { kind: "separator" }, { view: "ssh-tools", icon: , title: t("nav.sshTools") }, { kind: "separator" }, { view: "snippets", icon: , title: t("nav.snippets") }, { kind: "separator" }, { view: "history", icon: , title: t("nav.history") }, { kind: "separator" }, { view: "split-screen", icon: , title: t("nav.splitScreen"), dot: splitMode !== "none", }, { kind: "separator" }, { kind: "tab", tabType: "network_graph" as TabType, icon: , title: t("nav.networkGraph"), }, { kind: "separator" }, ]; } const btnBase = "relative flex items-center gap-2.5 h-7 rounded shrink-0 transition-colors"; const btnStyle = { margin: "0 4px", padding: "0 6px" }; export function AppRail({ railView, sidebarOpen, splitMode, connectionCount, username, isAdmin, profileDropdownOpen, onProfileDropdownChange, onRailClick, onOpenTab, onLogout, }: { railView: RailView; sidebarOpen: boolean; splitMode: SplitMode; connectionCount: number; username: string; isAdmin: boolean; profileDropdownOpen: boolean; onProfileDropdownChange: (open: boolean) => void; onRailClick: (view: RailView) => void; onOpenTab?: (type: TabType) => void; onLogout: () => void; }) { const { t } = useTranslation(); const [hovered, setHovered] = useState(false); const [pinned, setPinned] = useState( () => localStorage.getItem("pinAppRail") === "true", ); useEffect(() => { const handler = () => setPinned(localStorage.getItem("pinAppRail") === "true"); window.addEventListener("pinAppRailChanged", handler); return () => window.removeEventListener("pinAppRailChanged", handler); }, []); const railExpanded = pinned || hovered || profileDropdownOpen; const railButtons = buildRailButtons(splitMode, t, connectionCount); return (
setHovered(true)} onMouseLeave={() => setHovered(false)} >
{railButtons.map((item, i) => item.kind === "separator" ? (
) : item.kind === "tab" ? ( ) : ( ), )}
{[ { view: "user-profile" as RailView, icon: , title: t("nav.userProfile"), }, ...(isAdmin ? [ { view: "admin-settings" as RailView, icon: , title: t("nav.admin"), }, ] : []), ].map((item) => ( ))}
Logout
); }