Release
This commit is contained in:
parent
bc0838213e
commit
ecc16a198d
3 changed files with 17 additions and 14 deletions
|
|
@ -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");
|
||||||
|
|
|
||||||
|
|
@ -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
15
README.md
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
# SpectralVPN
|
||||||
|
|
||||||
|
> Быстрый, лёгкий и современный VPN-сервер с удобным веб-интерфейсом
|
||||||
|
|
||||||
|
   
|
||||||
|
|
||||||
|
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)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue