"use client" import { useMemo, useState, type ReactNode } from "react" import type { ServerStatus, ServerType } from "@/lib/data" import { Flag } from "@/components/flag" import { StatusDot } from "@/components/status-dot" import { Badge } from "@/components/reui/badge" import { IconTile } from "@/components/reui/icon-tile" import { Frame, FrameHeader, FramePanel, FrameTitle, } from "@/components/reui/frame" import { ScrollArea } from "@/components/ui/scroll-area" import { InputGroup, InputGroupAddon, InputGroupInput, } from "@/components/ui/input-group" import { cn } from "@/lib/utils" import { LayersIcon, SearchIcon, ServerIcon } from "lucide-react" /** Preview: https://reui.io/preview/base/list-9 · https://reui.io/docs/components/base/icon-tile · https://reui.io/preview/base/components/c-input-group-1 */ export const ALL_SERVERS_ID = "all" export interface ServerTileItem { id: string name: string country?: string status?: ServerStatus type?: ServerType count?: number enabled?: boolean selectable?: boolean title?: string } function typeBadgeVariant( type: ServerType, ): "focus-light" | "info-light" | "success-light" { if (type === "jump-host") return "focus-light" if (type === "home-router") return "success-light" return "info-light" } function typeBadgeLabel(type: ServerType): string { if (type === "jump-host") return "JH" if (type === "home-router") return "HR" return "EN" } function ServerTypeBadge({ type }: { type: ServerType }) { return ( {typeBadgeLabel(type)} ) } function matchesQuery(item: ServerTileItem, q: string): boolean { if (!q) return true const hay = [item.name, item.title ?? ""].join(" ").toLowerCase() return hay.includes(q) } function ServerTileRail({ items, selectedId, onSelect, allCount = 0, showHeader = true, showAll = true, showCount = true, showType = true, headerRight, className, }: { items: ServerTileItem[] selectedId: string onSelect: (id: string) => void allCount?: number showHeader?: boolean showAll?: boolean showCount?: boolean showType?: boolean headerRight?: ReactNode className?: string }) { const [query, setQuery] = useState("") const q = query.trim().toLowerCase() const filtered = useMemo( () => items.filter((item) => matchesQuery(item, q)), [items, q], ) const showAllTile = showAll && !q return ( {showHeader ? (
Серверы {headerRight}
) : headerRight ? (
{headerRight}
) : null} setQuery(e.target.value)} placeholder="Поиск…" aria-label="Поиск сервера" />
{showAllTile ? ( onSelect(ALL_SERVERS_ID)} title="Все серверы" name="Все" count={showCount ? allCount : undefined} icon={ } /> ) : null} {filtered.map((item) => ( onSelect(item.id)} title={item.title ?? item.name} name={item.name} count={showCount ? item.count : undefined} enabled={item.enabled} selectable={item.selectable} status={item.status} type={showType ? item.type : undefined} icon={ } /> ))} {filtered.length === 0 && !showAllTile ? (

{items.length === 0 ? "Нет доступных серверов" : "Ничего не найдено"}

) : null}
) } function ServerTileButton({ selected, onSelect, title, name, count, enabled = true, selectable = true, status, type, icon, }: { selected: boolean onSelect: () => void title: string name: string count?: number enabled?: boolean selectable?: boolean status?: ServerStatus type?: ServerType icon: ReactNode }) { return ( ) } export { ServerTileRail, ServerTypeBadge }