This commit is contained in:
Lev 2026-04-20 16:31:12 +03:00
parent bc0838213e
commit ecc16a198d
3 changed files with 17 additions and 14 deletions

View file

@ -41,14 +41,12 @@ async function apiRequest(endpoint, options = {}) {
return res; return res;
} }
// Показать окно логина
function showLoginModal() { function showLoginModal() {
document.getElementById("loginModal").classList.add("active"); document.getElementById("loginModal").classList.add("active");
document.getElementById("mainContent").classList.add("hidden"); document.getElementById("mainContent").classList.add("hidden");
document.getElementById("userInfo").style.display = "none"; document.getElementById("userInfo").style.display = "none";
} }
// Скрыть окно логина и показать кабинет
function hideLoginModal() { function hideLoginModal() {
document.getElementById("loginModal").classList.remove("active"); document.getElementById("loginModal").classList.remove("active");
document.getElementById("mainContent").classList.remove("hidden"); document.getElementById("mainContent").classList.remove("hidden");
@ -73,7 +71,7 @@ async function loadPanel() {
const data = await res.json(); const data = await res.json();
document.getElementById("userEmail").textContent = data.email || "Аккаунт активен"; document.getElementById("userEmail").textContent = data.email || "Аккаунт активен";
hideLoginModal(); // ← Важно! hideLoginModal();
renderConfigs(data.configs || []); renderConfigs(data.configs || []);
} }
@ -133,7 +131,6 @@ function renderConfigs(configs) {
}); });
} }
// ==================== ЛОГИН ====================
document.getElementById("loginSubmit").addEventListener("click", async () => { document.getElementById("loginSubmit").addEventListener("click", async () => {
const email = document.getElementById("loginEmail").value.trim(); const email = document.getElementById("loginEmail").value.trim();
const password = document.getElementById("loginPassword").value; const password = document.getElementById("loginPassword").value;
@ -160,7 +157,7 @@ document.getElementById("loginSubmit").addEventListener("click", async () => {
showNotification("Вход выполнен успешно!"); showNotification("Вход выполнен успешно!");
document.getElementById("loginEmail").value = ""; document.getElementById("loginEmail").value = "";
document.getElementById("loginPassword").value = ""; document.getElementById("loginPassword").value = "";
loadPanel(); // ← Главное исправление loadPanel();
} else { } else {
errorEl.textContent = data.detail || "Неверный email или пароль"; errorEl.textContent = data.detail || "Неверный email или пароль";
} }
@ -170,7 +167,6 @@ document.getElementById("loginSubmit").addEventListener("click", async () => {
} }
}); });
// ==================== Создание конфига ====================
document.getElementById("addConfigBtn").addEventListener("click", () => { document.getElementById("addConfigBtn").addEventListener("click", () => {
document.getElementById("addModal").classList.add("active"); document.getElementById("addModal").classList.add("active");
document.getElementById("configName").focus(); document.getElementById("configName").focus();
@ -206,7 +202,6 @@ document.getElementById("addSubmit").addEventListener("click", async () => {
} }
}); });
// ==================== Выход ====================
document.getElementById("logoutBtn").addEventListener("click", async () => { document.getElementById("logoutBtn").addEventListener("click", async () => {
if (!confirm("Выйти из аккаунта?")) return; if (!confirm("Выйти из аккаунта?")) return;
@ -223,7 +218,6 @@ document.getElementById("logoutBtn").addEventListener("click", async () => {
showLoginModal(); showLoginModal();
}); });
// ==================== Удаление аккаунта ====================
document.getElementById("deleteAccountBtn").addEventListener("click", async () => { document.getElementById("deleteAccountBtn").addEventListener("click", async () => {
if (!confirm("Вы уверены? Это действие необратимо!")) return; if (!confirm("Вы уверены? Это действие необратимо!")) return;
@ -238,7 +232,6 @@ document.getElementById("deleteAccountBtn").addEventListener("click", async () =
} }
}); });
// Табы "Как подключиться"
document.querySelectorAll(".tab-btn").forEach(btn => { document.querySelectorAll(".tab-btn").forEach(btn => {
btn.addEventListener("click", () => { btn.addEventListener("click", () => {
document.querySelectorAll(".tab-btn").forEach(b => b.classList.remove("active")); document.querySelectorAll(".tab-btn").forEach(b => b.classList.remove("active"));
@ -249,7 +242,6 @@ document.querySelectorAll(".tab-btn").forEach(btn => {
}); });
}); });
// Закрытие модалки создания конфига кликом вне
document.getElementById("addModal").addEventListener("click", (e) => { document.getElementById("addModal").addEventListener("click", (e) => {
if (e.target === document.getElementById("addModal")) { if (e.target === document.getElementById("addModal")) {
document.getElementById("addModal").classList.remove("active"); document.getElementById("addModal").classList.remove("active");

View file

@ -17,9 +17,7 @@
</div> </div>
</header> </header>
<!-- Главный контент (скрыт, пока не авторизован) -->
<main id="mainContent" class="hidden"> <main id="mainContent" class="hidden">
<!-- Как подключиться -->
<div class="how-to-connect"> <div class="how-to-connect">
<h1>Как подключиться</h1> <h1>Как подключиться</h1>
<div class="platform-tabs"> <div class="platform-tabs">
@ -64,7 +62,6 @@
</div> </div>
</main> </main>
<!-- Модальное окно ЛОГИНА (показывается при отсутствии токена) -->
<div class="modal active" id="loginModal"> <div class="modal active" id="loginModal">
<div class="modal-content"> <div class="modal-content">
<h2>Вход в аккаунт</h2> <h2>Вход в аккаунт</h2>
@ -83,7 +80,6 @@
</div> </div>
</div> </div>
<!-- Модальное окно создания конфига -->
<div class="modal" id="addModal"> <div class="modal" id="addModal">
<div class="modal-content"> <div class="modal-content">
<h2>Новая конфигурация</h2> <h2>Новая конфигурация</h2>

15
README.md Normal file
View file

@ -0,0 +1,15 @@
# SpectralVPN
> Быстрый, лёгкий и современный VPN-сервер с удобным веб-интерфейсом
![Python](https://img.shields.io/badge/Python-3776AB?logo=python&logoColor=white) ![JavaScript](https://img.shields.io/badge/JavaScript-F7DF1E?logo=javascript&logoColor=black) ![Docker](https://img.shields.io/badge/Docker-2496ED?logo=docker&logoColor=white) ![License](https://img.shields.io/github/license/lev4ikysss/SpectralVPN)
SpectralVPN — это открытый VPN-решение, состоящее из бэкенда (API) и современного фронтенда. Проект предназначен для быстрого развёртывания собственного VPN-сервера с удобным управлением через веб-панель.
## ✨ Возможности
- Современный REST API на Python - Красивый и responsive веб-интерфейс (Frontend) - Поддержка Docker и docker-compose (быстрое развёртывание) - Управление пользователями, конфигурациями и сессиями - Лёгкая расширяемость
## 🛠 Технологический стек
- \*\*Backend\*\*: Python + FastAPI (предположительно) - \*\*Frontend\*\*: HTML, CSS, JavaScript (возможно React/Vue или vanilla с современным дизайном) - \*\*Контейнеризация\*\*: Docker + docker-compose - \*\*База данных\*\*: (укажи, если используешь SQLite/PostgreSQL/Redis)