- Добавлены функции для переключения между темной и светлой темами с использованием localStorage. - Обновлены стили для поддержки темной темы, включая цвета фона, текста и иконок. - Добавлены кнопки для переключения темы на страницах входа, профиля, заметок и настроек. - Оптимизирован код для предотвращения мерцания темы при загрузке страницы.
133 lines
4.5 KiB
JavaScript
133 lines
4.5 KiB
JavaScript
// Логика переключения темы
|
||
function initThemeToggle() {
|
||
const themeToggleBtn = document.getElementById("theme-toggle-btn");
|
||
|
||
if (!themeToggleBtn) return;
|
||
|
||
// Загружаем сохраненную тему или используем системную
|
||
const savedTheme = localStorage.getItem("theme");
|
||
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches
|
||
? "dark"
|
||
: "light";
|
||
const currentTheme = savedTheme || systemTheme;
|
||
|
||
// Применяем тему
|
||
applyTheme(currentTheme);
|
||
|
||
// Обработчик клика на переключатель
|
||
themeToggleBtn.addEventListener("click", () => {
|
||
const currentTheme = document.documentElement.getAttribute("data-theme");
|
||
const newTheme = currentTheme === "dark" ? "light" : "dark";
|
||
applyTheme(newTheme);
|
||
localStorage.setItem("theme", newTheme);
|
||
});
|
||
|
||
// Слушаем изменения системной темы
|
||
window
|
||
.matchMedia("(prefers-color-scheme: dark)")
|
||
.addEventListener("change", (e) => {
|
||
if (!localStorage.getItem("theme")) {
|
||
applyTheme(e.matches ? "dark" : "light");
|
||
}
|
||
});
|
||
}
|
||
|
||
function applyTheme(theme) {
|
||
document.documentElement.setAttribute("data-theme", theme);
|
||
|
||
// Обновляем meta теги для PWA
|
||
const themeColorMeta = document.querySelector('meta[name="theme-color"]');
|
||
if (themeColorMeta) {
|
||
themeColorMeta.setAttribute(
|
||
"content",
|
||
theme === "dark" ? "#1a1a1a" : "#007bff"
|
||
);
|
||
}
|
||
|
||
// Обновляем иконку переключателя
|
||
const themeToggleBtn = document.getElementById("theme-toggle-btn");
|
||
if (themeToggleBtn) {
|
||
const icon = themeToggleBtn.querySelector(".iconify");
|
||
if (icon) {
|
||
icon.setAttribute(
|
||
"data-icon",
|
||
theme === "dark" ? "mdi:weather-sunny" : "mdi:weather-night"
|
||
);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Инициализируем переключатель темы при загрузке страницы
|
||
document.addEventListener("DOMContentLoaded", initThemeToggle);
|
||
|
||
// Проверяем, не авторизован ли уже пользователь
|
||
if (localStorage.getItem("isAuthenticated") === "true") {
|
||
window.location.href = "/notes";
|
||
}
|
||
|
||
// Обработка формы регистрации
|
||
const registerForm = document.getElementById("registerForm");
|
||
const errorMessage = document.getElementById("errorMessage");
|
||
|
||
if (registerForm) {
|
||
registerForm.addEventListener("submit", async (e) => {
|
||
e.preventDefault();
|
||
|
||
const username = document.getElementById("username").value.trim();
|
||
const password = document.getElementById("password").value;
|
||
const confirmPassword = document.getElementById("confirmPassword").value;
|
||
|
||
// Клиентская валидация
|
||
if (!username || !password || !confirmPassword) {
|
||
errorMessage.textContent = "Все поля обязательны";
|
||
errorMessage.style.display = "block";
|
||
return;
|
||
}
|
||
|
||
if (username.length < 3) {
|
||
errorMessage.textContent = "Логин должен быть не менее 3 символов";
|
||
errorMessage.style.display = "block";
|
||
return;
|
||
}
|
||
|
||
if (password.length < 6) {
|
||
errorMessage.textContent = "Пароль должен быть не менее 6 символов";
|
||
errorMessage.style.display = "block";
|
||
return;
|
||
}
|
||
|
||
if (password !== confirmPassword) {
|
||
errorMessage.textContent = "Пароли не совпадают";
|
||
errorMessage.style.display = "block";
|
||
return;
|
||
}
|
||
|
||
try {
|
||
const response = await fetch("/api/register", {
|
||
method: "POST",
|
||
headers: {
|
||
"Content-Type": "application/json",
|
||
},
|
||
body: JSON.stringify({ username, password, confirmPassword }),
|
||
});
|
||
|
||
const data = await response.json();
|
||
|
||
if (response.ok) {
|
||
// Успешная регистрация - сохраняем состояние аутентификации
|
||
localStorage.setItem("isAuthenticated", "true");
|
||
localStorage.setItem("username", username);
|
||
window.location.href = "/notes";
|
||
} else {
|
||
// Ошибка регистрации
|
||
errorMessage.textContent = data.error || "Ошибка регистрации";
|
||
errorMessage.style.display = "block";
|
||
}
|
||
} catch (err) {
|
||
console.error("Ошибка:", err);
|
||
errorMessage.textContent = "Ошибка соединения с сервером";
|
||
errorMessage.style.display = "block";
|
||
}
|
||
});
|
||
}
|