import { apiRequest } from './api.js'; import { getCookie, deleteCookie, setCookie } from './cookies.js'; class ClientManager { constructor() { this.userData = null; this.accessData = null; this.init(); } async init() { try { // Получаем данные пользователя из cookie this.userData = await getCookie('toolbox_user'); this.accessData = await getCookie('toolbox_access'); if (!this.userData || !this.accessData) { console.warn('User data or access data not found in cookie'); this.initLogout(); } // Вставляем данные пользователя в DOM this.renderUserInfo(); // Инициализируем обработчики this.initLogoutHandler(); this.initHoverEffects(); this.addAvatarErrorHandler(); } catch (error) { console.error('Error initializing client manager:', error); } } renderUserInfo() { if (!this.userData) { this.initLogout(); return; } // Находим элементы для обновления const avatar = document.querySelector('.client-avatar'); const nameElement = document.querySelector('.client-name'); const roleElement = document.querySelector('.client-role'); // Обновляем аватар if (avatar) { avatar.src = this.userData.photo || 'static/images/users/default.png'; avatar.alt = this.userData.username || 'Пользователь'; } // Обновляем имя if (nameElement) { nameElement.textContent = this.userData.username || 'Неизвестный пользователь'; } // Обновляем роль if (roleElement) { const role = this.accessData.title || 'Неизвестная роль'; roleElement.textContent = role; } } initLogoutHandler() { const logoutBtn = document.getElementById('clientLogoutBtn'); if (logoutBtn) { logoutBtn.addEventListener('click', (e) => { e.preventDefault(); this.handleLogout(logoutBtn); }); } } initLogout() { const logoutBtn = document.getElementById('clientLogoutBtn'); if (logoutBtn) { this.handleLogout(logoutBtn); } } handleLogout(button) { // Анимация нажатия button.style.transform = 'scale(0.95)'; // Добавляем иконку загрузки button.innerHTML = ` Выход... `; button.disabled = true; // Очищаем cookie пользователя this.clearUserCookie(); // Очищаем локальное хранилище localStorage.clear(); // Переход на страницу выхода setTimeout(() => { window.location.href = '/user/login'; }, 800); } clearUserCookie() { try { const cookieNames = ['toolbox_user', 'toolbox_access']; cookieNames.forEach(cookieName => { deleteCookie(cookieName); }); } catch (error) { console.warn('Error clearing cookies:', error); } } initHoverEffects() { const clientCard = document.querySelector('.client-card'); if (clientCard) { clientCard.addEventListener('mouseenter', () => { clientCard.style.transform = 'translateY(-4px) scale(1.01)'; }); clientCard.addEventListener('mouseleave', () => { clientCard.style.transform = 'translateY(0) scale(1)'; }); } } addAvatarErrorHandler() { const avatar = document.querySelector('.client-avatar'); if (avatar) { avatar.onerror = () => { avatar.src = 'static/images/users/default.png'; }; } } userProfile() { const avatarBtn = document.getElementById('userProfile'); async function openEditUserModal(user = null) { const isNew = !user; const modalId = `profile-edit-user-modal`; // Удаляем старую модалку, если есть const existingModal = document.getElementById(modalId); if (existingModal) { existingModal.remove(); } const modalHTML = `
`; document.body.insertAdjacentHTML('beforeend', modalHTML); const modal = new bootstrap.Modal(document.getElementById(modalId)); let photoFile = null; let removePhoto = false; // Обработчики для фото const changePhotoBtn = document.getElementById(`${modalId}-change-photo-btn`); const photoInput = document.getElementById(`${modalId}-photo-input`); const photoPreview = document.getElementById(`${modalId}-photo-preview`); changePhotoBtn.addEventListener('click', () => { photoInput.click(); }); photoInput.addEventListener('change', (e) => { const file = e.target.files[0]; if (file) { if (file.type.startsWith('image/')) { photoFile = file; const reader = new FileReader(); reader.onload = (e) => { photoPreview.src = e.target.result; }; reader.readAsDataURL(file); removePhoto = false; } else { showConfirmationModal('Ошибка', 'Пожалуйста, выберите файл изображения', () => { }); photoInput.value = ''; } } }); if (document.getElementById(`${modalId}-remove-photo-btn`)) { document.getElementById(`${modalId}-remove-photo-btn`).addEventListener('click', () => { photoPreview.src = 'static/images/users/default.png'; photoFile = null; removePhoto = true; }); } // Обработчик сохранения document.getElementById(`${modalId}-save-btn`).addEventListener('click', async () => { const form = document.getElementById(`${modalId}-form`); if (!form.checkValidity()) { form.reportValidity(); return; } const formUserData = { login: document.getElementById(`${modalId}-login`).value.trim(), username: document.getElementById(`${modalId}-username`).value.trim(), }; // Добавляем пароль, если он указан const password = document.getElementById(`${modalId}-password`).value; if (password || isNew) { formUserData.password = password || ''; } // Определяем действие let action = isNew ? 'create' : 'update'; // Обработка фото if (photoFile) { if (photoFile.size > 5 * 1024 * 1024) { showInfo('Фото больше 5 МБ, оно не подходит', 'warning'); return; } formUserData.photo = await new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => resolve(reader.result); reader.onerror = () => reject(new Error('Ошибка чтения файла')); reader.readAsDataURL(photoFile); }); } else if (removePhoto) { formUserData.photo = ''; } let changedUserData = {}; if (isNew) { changedUserData = formUserData; } else { changedUserData = Object.keys(formUserData).reduce((acc, key) => { if (formUserData[key] !== user[key]) { acc[key] = formUserData[key]; } return acc; }, {}); } if (Object.keys(changedUserData).length === 0) { showInfo('Нет изменений', 'info'); return; } // Обновляем данные if (!isNew) { changedUserData.id = user.id; } const result = await apiRequest('/user/', { action, userData: changedUserData, userId: user.id }); if (result && result.status === 'ok') { const newUserData = await apiRequest('/user/', { userId: user.id }, 'get'); await setCookie('toolbox_user', JSON.stringify(newUserData)); const checkData = await getCookie('toolbox_user'); if (window.clientManager) { window.clientManager.userData = newUserData; window.clientManager.renderUserInfo(); } if (modal) { modal.hide(); } } else { const errorMessageDiv = document.getElementById(`${modalId}-error-message`); errorMessageDiv.textContent = result.message; errorMessageDiv.hidden = false; } }); modal.show(); // Удаляем модалку после скрытия modal._element.addEventListener('hidden.bs.modal', () => { modal._element.remove(); }); } avatarBtn.addEventListener('click', async () => { await openEditUserModal(this.userData); }); } } // Инициализация при загрузке документа document.addEventListener('DOMContentLoaded', () => { // Инициализируем менеджер пользователя window.clientManager = new ClientManager(); // Добавляем анимацию появления const elements = document.querySelectorAll('.animate-fade-up'); elements.forEach((el, index) => { el.style.animationDelay = `${index * 0.1}s`; }); window.clientManager.userProfile(); }); // Экспорт для использования в других модулях export { ClientManager };