import { useEffect, useRef, useState } from "react" import { Check, ChevronsUpDown, ExternalLink, Hexagon } from "lucide-react" import { useNodes } from "@/services/api/hooks" import type { NodeSummary } from "@/types" import { cn } from "@/lib/utils" // Each machine's castle is served at its own origin (castle.), so hopping // between hosts is a cross-origin navigation. This shows which host you're driving // (the is_local node) and lets you jump to a peer's dashboard, preserving the view. function dashboardUrl(n: NodeSummary): string { const base = n.gateway_domain ? `https://castle.${n.gateway_domain}` : `http://${n.hostname}:${n.gateway_port}` return `${base}${window.location.pathname}` } export function HostSwitcher({ collapsed }: { collapsed: boolean }) { const { data: nodes } = useNodes() const [open, setOpen] = useState(false) const ref = useRef(null) useEffect(() => { if (!open) return const onDown = (e: MouseEvent) => { if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false) } window.addEventListener("mousedown", onDown) return () => window.removeEventListener("mousedown", onDown) }, [open]) const list = nodes ?? [] const current = list.find((n) => n.is_local) const others = list.filter((n) => !n.is_local) const label = current?.hostname ?? "this node" const canSwitch = others.length > 0 return (
{open && (
Castle hosts
{list.map((n) => { const isCur = n.is_local const inner = ( <> {n.hostname} {isCur ? ( ) : ( )} ) const cls = "flex items-center gap-2 px-2.5 py-2 text-sm" if (isCur) return (
{inner}
) return ( setOpen(false)} className={cn(cls, "hover:bg-white/5", !n.online && "opacity-40")} > {inner} ) })}
)}
) }