Files
MikrotikManager/components/data-grids/wireguard-peers-detail.tsx
T
Denozordec d3a2d38b37
Docker images / prepare-release (push) Successful in 6s
Docker images / backend-image (push) Successful in 1m37s
Docker images / frontend-image (push) Successful in 1m50s
Docker images / updater-image (push) Successful in 44s
Docker images / notify-webhook (push) Has been skipped
Docker images / publish-release (push) Successful in 7s
fix(ui): заменить таблицы на карточки данных и улучшить функциональность поиска
2026-06-30 22:22:51 +07:00

82 lines
2.9 KiB
TypeScript

"use client"
import type { WireGuardPeer } from "@/lib/data"
import { cn } from "@/lib/utils"
import {
ArrowDownIcon,
ArrowUpIcon,
KeyRoundIcon,
} from "lucide-react"
function fmtBytes(n: number | undefined): string {
if (!n) return "—"
if (n >= 1_000_000_000) return `${(n / 1_000_000_000).toFixed(1)} ГБ`
if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)} МБ`
if (n >= 1_000) return `${(n / 1_000).toFixed(0)} КБ`
return `${n} Б`
}
function truncKey(key: string): string {
if (key.length <= 20) return key
return `${key.slice(0, 8)}${key.slice(-8)}`
}
function WireGuardPeersDetail({ peers }: { peers: WireGuardPeer[] }) {
if (peers.length === 0) {
return (
<div className="px-5 py-4 text-xs text-muted-foreground text-center border-t border-border/50">
Нет пиров
</div>
)
}
return (
<div className="border-t border-border/50">
<div className="grid grid-cols-[1fr_1fr_auto_auto_auto] gap-3 px-5 py-1.5 bg-muted/10 text-[10px] font-semibold uppercase tracking-widest text-muted-foreground">
<span>Public Key</span>
<span>Allowed IPs</span>
<span>Последнее рукопожатие</span>
<span>RX / TX</span>
<span>Endpoint</span>
</div>
{peers.map((peer) => (
<div
key={peer.publicKey}
className="grid grid-cols-[1fr_1fr_auto_auto_auto] gap-3 px-5 py-2.5 items-center text-xs border-t border-border/50 bg-muted/20"
>
<div className="flex items-center gap-1.5 min-w-0">
<KeyRoundIcon className="size-3 text-muted-foreground shrink-0" />
<span className="font-mono text-muted-foreground truncate" title={peer.publicKey}>
{truncKey(peer.publicKey)}
</span>
</div>
<div className="font-mono text-muted-foreground truncate">
{peer.allowedIps.join(", ")}
</div>
<span
className={cn(
"font-mono text-[11px] whitespace-nowrap",
peer.latestHandshake ? "text-emerald-600 dark:text-emerald-400" : "text-muted-foreground",
)}
>
{peer.latestHandshake ?? "нет рукопожатия"}
</span>
<div className="flex items-center gap-2 text-muted-foreground whitespace-nowrap">
<span className="flex items-center gap-0.5">
<ArrowDownIcon className="size-3 text-emerald-500" />
{fmtBytes(peer.transferRx)}
</span>
<span className="flex items-center gap-0.5">
<ArrowUpIcon className="size-3 text-blue-400" />
{fmtBytes(peer.transferTx)}
</span>
</div>
<span className="font-mono text-muted-foreground/60 text-[11px]">{peer.endpoint ?? "—"}</span>
</div>
))}
</div>
)
}
export { WireGuardPeersDetail, fmtBytes, truncKey }