// Servers screen — VPN server monitoring const { useState: useStateSv, useEffect: useEffectSv } = React; function ServerCard({ server }) { const statusCfg = { ok: { dot: "bg-[#22c55e]", label: "В сети", labelColor: "text-[#22c55e]", bg: "border-[#22c55e]/20" }, high: { dot: "bg-[#eab308]", label: "Высокая нагрузка", labelColor: "text-[#eab308]", bg: "border-[#eab308]/20" }, down: { dot: "bg-[#ef4444]", label: "Недоступен", labelColor: "text-[#ef4444]", bg: "border-[#ef4444]/20" }, }[server.status] || { dot: "bg-zinc-500", label: "Неизвестно", labelColor: "text-zinc-400", bg: "" }; return (
{server.name}
{statusCfg.label}
Нагрузка
{server.load != null ? server.load + "%" : "—"}
Пинг
{server.ping != null ? server.ping + " мс" : "—"}
Uptime
{server.uptime != null ? server.uptime + "%" : "—"}
{server.location && (
📍 {server.location}
)}
); } function ServersScreen() { const [data, setData] = useStateSv({ servers: [], last_updated: null }); const [loading, setLoading] = useStateSv(true); function load() { setLoading(true); window.apiFetch("GET", "/api/servers") .then((d) => { setData(d); setLoading(false); }) .catch(() => setLoading(false)); } useEffectSv(() => { load(); }, []); const servers = data.servers || []; const online = servers.filter((s) => s.status === "ok").length; const high = servers.filter((s) => s.status === "high").length; const down = servers.filter((s) => s.status === "down").length; return (
{/* Stub mode banner */} {data.is_stub && (
Тестовый режим — показаны случайные данные. Настройте переменную SERVERS в .env для мониторинга реальных серверов.
)} {/* Header */}

Серверы VPN

{data.last_updated ? `Обновлено: ${data.last_updated}` : "Ожидание первой проверки..."}
{/* Summary */} {servers.length > 0 && (
{online}
В сети
{high}
Высокая нагрузка
{down}
Недоступно
)} {/* Server grid */} {loading && (
Загрузка...
)} {!loading && servers.length === 0 && (
Серверы не настроены
Добавьте серверы в .env через переменную SERVERS и задайте SERVERS_MONITOR_TYPE=tcp
)} {!loading && servers.length > 0 && (
{servers.map((s) => )}
)}
); } Object.assign(window, { ServersScreen });