252 lines
8.0 KiB
JavaScript
252 lines
8.0 KiB
JavaScript
// DOM элементы
|
|
const avatarImage = document.getElementById("avatarImage");
|
|
const avatarPlaceholder = document.getElementById("avatarPlaceholder");
|
|
const avatarInput = document.getElementById("avatarInput");
|
|
const deleteAvatarBtn = document.getElementById("deleteAvatarBtn");
|
|
const usernameInput = document.getElementById("username");
|
|
const emailInput = document.getElementById("email");
|
|
const updateProfileBtn = document.getElementById("updateProfileBtn");
|
|
const currentPasswordInput = document.getElementById("currentPassword");
|
|
const newPasswordInput = document.getElementById("newPassword");
|
|
const confirmPasswordInput = document.getElementById("confirmPassword");
|
|
const changePasswordBtn = document.getElementById("changePasswordBtn");
|
|
const messageContainer = document.getElementById("messageContainer");
|
|
|
|
// Функция для показа сообщений
|
|
function showMessage(message, type = "success") {
|
|
messageContainer.textContent = message;
|
|
messageContainer.className = `message-container ${type}`;
|
|
messageContainer.style.display = "block";
|
|
|
|
setTimeout(() => {
|
|
messageContainer.style.display = "none";
|
|
}, 5000);
|
|
}
|
|
|
|
// Загрузка данных профиля
|
|
async function loadProfile() {
|
|
try {
|
|
const response = await fetch("/api/user");
|
|
if (!response.ok) {
|
|
throw new Error("Ошибка загрузки профиля");
|
|
}
|
|
|
|
const user = await response.json();
|
|
|
|
// Заполняем поля
|
|
usernameInput.value = user.username || "";
|
|
emailInput.value = user.email || "";
|
|
|
|
// Обрабатываем аватарку
|
|
if (user.avatar) {
|
|
avatarImage.src = user.avatar;
|
|
avatarImage.style.display = "block";
|
|
avatarPlaceholder.style.display = "none";
|
|
deleteAvatarBtn.style.display = "inline-block";
|
|
} else {
|
|
avatarImage.style.display = "none";
|
|
avatarPlaceholder.style.display = "inline-flex";
|
|
deleteAvatarBtn.style.display = "none";
|
|
}
|
|
} catch (error) {
|
|
console.error("Ошибка загрузки профиля:", error);
|
|
showMessage("Ошибка загрузки данных профиля", "error");
|
|
}
|
|
}
|
|
|
|
// Обработчик загрузки аватарки
|
|
avatarInput.addEventListener("change", async function (event) {
|
|
const file = event.target.files[0];
|
|
if (!file) return;
|
|
|
|
// Проверка размера файла (5MB)
|
|
if (file.size > 5 * 1024 * 1024) {
|
|
showMessage("Файл слишком большой. Максимальный размер: 5 МБ", "error");
|
|
return;
|
|
}
|
|
|
|
// Проверка типа файла
|
|
const allowedTypes = ["image/jpeg", "image/jpg", "image/png", "image/gif"];
|
|
if (!allowedTypes.includes(file.type)) {
|
|
showMessage(
|
|
"Недопустимый формат файла. Используйте JPG, PNG или GIF",
|
|
"error"
|
|
);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const formData = new FormData();
|
|
formData.append("avatar", file);
|
|
|
|
const response = await fetch("/api/user/avatar", {
|
|
method: "POST",
|
|
body: formData,
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const error = await response.json();
|
|
throw new Error(error.error || "Ошибка загрузки аватарки");
|
|
}
|
|
|
|
const result = await response.json();
|
|
|
|
// Обновляем отображение аватарки
|
|
avatarImage.src = result.avatar + "?t=" + Date.now(); // Добавляем timestamp для обновления кэша
|
|
avatarImage.style.display = "block";
|
|
avatarPlaceholder.style.display = "none";
|
|
deleteAvatarBtn.style.display = "inline-block";
|
|
|
|
showMessage("Аватарка успешно загружена", "success");
|
|
} catch (error) {
|
|
console.error("Ошибка загрузки аватарки:", error);
|
|
showMessage(error.message, "error");
|
|
}
|
|
|
|
// Сбрасываем input для возможности повторной загрузки того же файла
|
|
event.target.value = "";
|
|
});
|
|
|
|
// Обработчик удаления аватарки
|
|
deleteAvatarBtn.addEventListener("click", async function () {
|
|
if (!confirm("Вы уверены, что хотите удалить аватарку?")) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const response = await fetch("/api/user/avatar", {
|
|
method: "DELETE",
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const error = await response.json();
|
|
throw new Error(error.error || "Ошибка удаления аватарки");
|
|
}
|
|
|
|
// Обновляем отображение
|
|
avatarImage.style.display = "none";
|
|
avatarPlaceholder.style.display = "inline-flex";
|
|
deleteAvatarBtn.style.display = "none";
|
|
|
|
showMessage("Аватарка успешно удалена", "success");
|
|
} catch (error) {
|
|
console.error("Ошибка удаления аватарки:", error);
|
|
showMessage(error.message, "error");
|
|
}
|
|
});
|
|
|
|
// Обработчик обновления профиля
|
|
updateProfileBtn.addEventListener("click", async function () {
|
|
const username = usernameInput.value.trim();
|
|
const email = emailInput.value.trim();
|
|
|
|
// Валидация
|
|
if (!username) {
|
|
showMessage("Логин не может быть пустым", "error");
|
|
return;
|
|
}
|
|
|
|
if (username.length < 3) {
|
|
showMessage("Логин должен быть не менее 3 символов", "error");
|
|
return;
|
|
}
|
|
|
|
if (email && !isValidEmail(email)) {
|
|
showMessage("Некорректный email адрес", "error");
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const response = await fetch("/api/user/profile", {
|
|
method: "PUT",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({
|
|
username,
|
|
email: email || null,
|
|
}),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const error = await response.json();
|
|
throw new Error(error.error || "Ошибка обновления профиля");
|
|
}
|
|
|
|
const result = await response.json();
|
|
showMessage(result.message || "Профиль успешно обновлен", "success");
|
|
} catch (error) {
|
|
console.error("Ошибка обновления профиля:", error);
|
|
showMessage(error.message, "error");
|
|
}
|
|
});
|
|
|
|
// Обработчик изменения пароля
|
|
changePasswordBtn.addEventListener("click", async function () {
|
|
const currentPassword = currentPasswordInput.value;
|
|
const newPassword = newPasswordInput.value;
|
|
const confirmPassword = confirmPasswordInput.value;
|
|
|
|
// Валидация
|
|
if (!currentPassword) {
|
|
showMessage("Введите текущий пароль", "error");
|
|
return;
|
|
}
|
|
|
|
if (!newPassword) {
|
|
showMessage("Введите новый пароль", "error");
|
|
return;
|
|
}
|
|
|
|
if (newPassword.length < 6) {
|
|
showMessage("Новый пароль должен быть не менее 6 символов", "error");
|
|
return;
|
|
}
|
|
|
|
if (newPassword !== confirmPassword) {
|
|
showMessage("Новый пароль и подтверждение не совпадают", "error");
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const response = await fetch("/api/user/profile", {
|
|
method: "PUT",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({
|
|
currentPassword,
|
|
newPassword,
|
|
}),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const error = await response.json();
|
|
throw new Error(error.error || "Ошибка изменения пароля");
|
|
}
|
|
|
|
const result = await response.json();
|
|
|
|
// Очищаем поля паролей
|
|
currentPasswordInput.value = "";
|
|
newPasswordInput.value = "";
|
|
confirmPasswordInput.value = "";
|
|
|
|
showMessage(result.message || "Пароль успешно изменен", "success");
|
|
} catch (error) {
|
|
console.error("Ошибка изменения пароля:", error);
|
|
showMessage(error.message, "error");
|
|
}
|
|
});
|
|
|
|
// Функция валидации email
|
|
function isValidEmail(email) {
|
|
const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
return re.test(email);
|
|
}
|
|
|
|
// Загружаем профиль при загрузке страницы
|
|
document.addEventListener("DOMContentLoaded", function () {
|
|
loadProfile();
|
|
});
|