diff --git a/src/components/multi-site-selector.tsx b/src/components/multi-site-selector.tsx index 407e3b3e1..c06f6c74a 100644 --- a/src/components/multi-site-selector.tsx +++ b/src/components/multi-site-selector.tsx @@ -12,7 +12,7 @@ import { import { Checkbox } from "./ui/checkbox"; import { useTranslations } from "next-intl"; import { useDebounce } from "use-debounce"; -import type { Selectedsite } from "./site-selector"; +import { SiteOnlineStatus, type Selectedsite } from "./site-selector"; export type MultiSitesSelectorProps = { orgId: string; @@ -107,7 +107,16 @@ export function MultiSitesSelector({ aria-hidden tabIndex={-1} /> - {site.name} +
+ + {site.name} + + +
))} diff --git a/src/components/site-selector.tsx b/src/components/site-selector.tsx index db23362dc..1c6302d98 100644 --- a/src/components/site-selector.tsx +++ b/src/components/site-selector.tsx @@ -18,7 +18,41 @@ import { useDebounce } from "use-debounce"; export type Selectedsite = Pick< ListSitesResponse["sites"][number], "name" | "siteId" | "type" ->; +> & { + /** When omitted, no online/offline indicator is shown. */ + online?: ListSitesResponse["sites"][number]["online"]; +}; + +type SiteOnlineStatusProps = { + type: Selectedsite["type"]; + online: Selectedsite["online"]; + t: (key: "online" | "offline") => string; +}; + +/** Dot-only indicator matching `SitesTable` colors (newt/wireguard only; nothing for local or missing status). */ +export function SiteOnlineStatus({ type, online, t }: SiteOnlineStatusProps) { + if (type !== "newt" && type !== "wireguard") { + return null; + } + if (typeof online !== "boolean") { + return null; + } + return ( + +
+ + ); +} export type SitesSelectorProps = { orgId: string; @@ -86,7 +120,16 @@ export function SitesSelector({ : "opacity-0" )} /> - {site.name} +
+ + {site.name} + + +
))}