Files
alpine-router/public/home.html
2026-04-15 11:38:26 +03:00

291 lines
12 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NanoRouter — Главная</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<div class="header-left">
<svg class="logo" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M12 2L2 7l10 5 10-5-10-5z"/>
<path d="M2 17l10 5 10-5"/>
<path d="M2 12l10 5 10-5"/>
</svg>
<h1>NanoRouter</h1>
</div>
<div class="header-right">
</div>
</header>
<nav class="tab-nav">
<a href="/home.html" class="tab-link active">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="15" height="15">
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>
<polyline points="9 22 9 12 15 12 15 22"/>
</svg>
Главная
</a>
<a href="/ifaces.html" class="tab-link">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="15" height="15">
<path d="M12 2L2 7l10 5 10-5-10-5z"/>
<path d="M2 17l10 5 10-5"/>
<path d="M2 12l10 5 10-5"/>
</svg>
Интерфейсы
</a>
<a href="/dhcp.html" class="tab-link">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="15" height="15">
<path d="M5 12h14M12 5l7 7-7 7"/>
</svg>
DHCP сервер
</a>
<a href="/clients.html" class="tab-link">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="15" height="15">
<circle cx="9" cy="7" r="4"/><path d="M3 21v-2a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v2"/>
<path d="M16 3.13a4 4 0 0 1 0 7.75M21 21v-2a4 4 0 0 0-3-3.87"/>
</svg>
Клиенты
</a>
<a href="/firewall.html" class="tab-link">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="15" height="15">
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>
<path d="M9 12l2 2 4-4"/>
</svg>
Файрвол
</a>
<a href="/proxy.html" class="tab-link">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="15" height="15">
<circle cx="12" cy="12" r="3"/>
<path d="M12 1v4M12 19v4M4.22 4.22l2.83 2.83M16.95 16.95l2.83 2.83M1 12h4M19 12h4M4.22 19.78l2.83-2.83M16.95 7.05l2.83-2.83"/>
</svg>
Прокси
</a>
<a href="/profile.html" class="tab-link">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="15" height="15">
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/>
<circle cx="12" cy="7" r="4"/>
</svg>
Профиль
</a>
</nav>
<main class="home-main">
<div id="defaultPwWarning" class="alert alert-error hidden" style="margin-bottom:16px">
<div>
<strong>&#9888; Пароль по умолчанию!</strong> Аккаунт использует стандартный пароль <code>admin:admin</code>. <a href="/profile.html" style="color:var(--accent)">Задайте свой пароль &rarr;</a>
</div>
</div>
<div id="loading" class="loading">
<div class="spinner"></div>
<span>Загрузка...</span>
</div>
<!-- Status Banner -->
<div id="statusBanner" class="status-banner hidden">
<div id="statusIcon" class="status-icon"></div>
<div class="status-text">
<div id="statusTitle" class="status-title"></div>
<div id="statusSubtitle" class="status-subtitle"></div>
</div>
</div>
<!-- Top Row: System + Mihomo -->
<div class="home-grid-2">
<!-- System Resources -->
<div class="dash-card">
<h3 class="dash-card-title">Система</h3>
<div class="gauge-row">
<div class="gauge-item">
<div class="gauge-svg-wrap">
<svg viewBox="0 0 100 100" class="gauge-svg">
<circle cx="50" cy="50" r="42" class="gauge-bg"/>
<circle cx="50" cy="50" r="42" class="gauge-fg" id="cpuArc" transform="rotate(-90 50 50)"/>
</svg>
<div class="gauge-val" id="cpuVal"></div>
</div>
<div class="gauge-label">CPU</div>
</div>
<div class="gauge-item">
<div class="gauge-svg-wrap">
<svg viewBox="0 0 100 100" class="gauge-svg">
<circle cx="50" cy="50" r="42" class="gauge-bg"/>
<circle cx="50" cy="50" r="42" class="gauge-fg gauge-mem" id="memArc" transform="rotate(-90 50 50)"/>
</svg>
<div class="gauge-val" id="memVal"></div>
</div>
<div class="gauge-label">ОЗУ</div>
</div>
</div>
<div class="sys-info" id="sysInfo"></div>
</div>
<!-- Mihomo Status -->
<div class="dash-card">
<h3 class="dash-card-title">Mihomo</h3>
<div id="mihomoStatus" class="mihomo-block">
<div class="mihomo-info">
<span id="mihomoBadge" class="svc-badge stopped">Остановлен</span>
<span id="mihomoPid" class="mihomo-pid"></span>
</div>
<div class="mihomo-actions">
<label class="toggle-label" title="Запустить / Остановить">
<input type="checkbox" id="mihomoToggle">
<span class="toggle-slider"></span>
</label>
<button class="btn-icon" id="mihomoRestartBtn" disabled title="Перезапустить">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16">
<path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/>
<path d="M3 3v5h5"/>
</svg>
</button>
</div>
</div>
</div>
</div>
<!-- Connectivity -->
<div class="dash-card">
<div class="dash-card-header-row">
<h3 class="dash-card-title">Подключение</h3>
<button class="btn-icon" id="connSettingsBtn" title="Настройки проверки подключения">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16">
<circle cx="12" cy="12" r="3"/>
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>
</svg>
</button>
</div>
<div class="conn-row">
<div class="conn-item">
<div class="conn-label">Интернет (напрямую)</div>
<div class="conn-timeline" id="directTimeline"></div>
<div class="conn-current" id="directStatus"></div>
</div>
<div class="conn-item">
<div class="conn-label">VPN (через Mihomo)</div>
<div class="conn-timeline" id="vpnTimeline"></div>
<div class="conn-current" id="vpnStatus"></div>
</div>
</div>
</div>
<!-- Traffic Speed -->
<div class="dash-card dash-wide">
<div class="dash-card-header-row">
<h3 class="dash-card-title">Загрузка сети</h3>
<div class="dash-mode-switch" id="speedModeSwitch">
<button class="seg-btn" data-mode="avg">10 мин</button>
<button class="seg-btn active" data-mode="real">Realtime</button>
</div>
</div>
<div class="speed-current-row">
<div class="speed-item">
<span class="speed-arrow"></span>
<span class="speed-value" id="rxSpeed">0 bps</span>
</div>
<div class="speed-item">
<span class="speed-arrow"></span>
<span class="speed-value" id="txSpeed">0 bps</span>
</div>
<div class="speed-iface" id="gwIface"></div>
</div>
<div class="speed-chart-wrap">
<canvas id="speedChart" width="800" height="200"></canvas>
</div>
</div>
<!-- IP Info -->
<div class="home-grid-2">
<div class="dash-card">
<h3 class="dash-card-title">IP без VPN</h3>
<div id="ipDirect" class="ip-block">
<div class="ip-address"></div>
<div class="ip-country"></div>
</div>
</div>
<div class="dash-card">
<h3 class="dash-card-title">IP с VPN</h3>
<div id="ipVPN" class="ip-block">
<div class="ip-address"></div>
<div class="ip-country"></div>
</div>
</div>
</div>
</main>
<!-- Connectivity Settings Modal -->
<div id="connModal" class="modal hidden">
<div class="modal-backdrop" id="connModalBackdrop"></div>
<div class="modal-box">
<div class="modal-header">
<h2>Настройки проверки подключения</h2>
<button class="btn-icon" id="closeConnModal" title="Закрыть">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16">
<line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
</svg>
</button>
</div>
<form id="connSettingsForm">
<div class="conn-settings-section">
<div class="conn-settings-label">Прямое подключение</div>
<div class="conn-endpoint-row">
<div class="form-row">
<label>Название 1</label>
<input type="text" id="direct1Name" placeholder="Cloudflare">
</div>
<div class="form-row">
<label>URL 1</label>
<input type="text" id="direct1Url" placeholder="http://cp.cloudflare.com/generate_204">
</div>
</div>
<div class="conn-endpoint-row">
<div class="form-row">
<label>Название 2</label>
<input type="text" id="direct2Name" placeholder="Google">
</div>
<div class="form-row">
<label>URL 2</label>
<input type="text" id="direct2Url" placeholder="http://connectivitycheck.gstatic.com/generate_204">
</div>
</div>
</div>
<hr class="form-divider">
<div class="conn-settings-section">
<div class="conn-settings-label">Через прокси (VPN)</div>
<div class="conn-endpoint-row">
<div class="form-row">
<label>Название 1</label>
<input type="text" id="proxy1Name" placeholder="Cloudflare">
</div>
<div class="form-row">
<label>URL 1</label>
<input type="text" id="proxy1Url" placeholder="http://cp.cloudflare.com/generate_204">
</div>
</div>
<div class="conn-endpoint-row">
<div class="form-row">
<label>Название 2</label>
<input type="text" id="proxy2Name" placeholder="Google">
</div>
<div class="form-row">
<label>URL 2</label>
<input type="text" id="proxy2Url" placeholder="http://connectivitycheck.gstatic.com/generate_204">
</div>
</div>
</div>
<div class="conn-settings-hint">Соединение считается успешным при HTTP-коде 2xx или 3xx.</div>
<div class="modal-footer">
<button type="button" class="btn btn-ghost" id="cancelConnSettings">Отмена</button>
<button type="submit" class="btn btn-primary">Сохранить</button>
</div>
</form>
</div>
</div>
<div id="toast" class="toast hidden"></div>
<script src="home.js"></script>
</body>
</html>