diff --git a/api-users.js b/api-users.js index bf89c9c..80565b2 100644 --- a/api-users.js +++ b/api-users.js @@ -28,7 +28,8 @@ module.exports = function(app, db) { } const isAdmin = user.role === 'admin'; - callback(null, isAdmin); + const isTasks = user.role === 'tasks'; // Пользователи с ролью tasks тоже имеют доступ + callback(null, isAdmin || isTasks); }); }); } diff --git a/public/auth.js b/public/auth.js index e01cc26..3e72011 100644 --- a/public/auth.js +++ b/public/auth.js @@ -83,6 +83,12 @@ function showMainInterface() { document.getElementById('current-user').textContent = userInfo; + // 👇 СОЗДАЕМ НАВИГАЦИЮ ПОСЛЕ УСТАНОВКИ ПОЛЬЗОВАТЕЛЯ 👇 + if (typeof createNavigation === 'function') { + console.log('🔄 Создание навигации для пользователя:', currentUser.role); + createNavigation(); + } + document.getElementById('tasks-controls').style.display = 'block'; const showDeletedLabel = document.querySelector('.show-deleted-label'); diff --git a/public/index.html b/public/index.html index c6bcad5..9e0b5be 100644 --- a/public/index.html +++ b/public/index.html @@ -203,7 +203,7 @@

Личный кабинет

- +

Настройки уведомлений

@@ -373,7 +373,6 @@
- @@ -385,6 +384,7 @@ + \ No newline at end of file diff --git a/public/navbar.js b/public/navbar.js index cd7b215..10564ab 100644 --- a/public/navbar.js +++ b/public/navbar.js @@ -2,7 +2,15 @@ function createNavigation() { const navbar = document.getElementById('navbar-container'); if (!navbar) return; - + // 👇 ДОБАВЛЯЕМ ПОДРОБНЫЕ ЛОГИ 👇 + if (currentUser) { + console.log('ID:', currentUser.id); + console.log('ФИО:', currentUser.name); + console.log('Логин:', currentUser.login); + console.log('Роль:', currentUser.role); + } else { + console.log('currentUser отсутствует (не авторизован)'); + } // Базовые кнопки для всех авторизованных пользователей const navButtons = [ { @@ -42,8 +50,8 @@ function createNavigation() { } ]; - // Кнопка админ-панели только для admin - //if (currentUser.role === 'admin') { + // 👇 Кнопка админ-панели ТОЛЬКО для admin 👇 + if (currentUser && currentUser.role === 'admin') { navButtons.push({ onclick: "window.location.href = '/admin'", className: "nav-btn admin", @@ -51,7 +59,7 @@ function createNavigation() { text: "Админ-панель", id: "admin-btn" }); - //} + } // Кнопка выхода navButtons.push({ @@ -76,7 +84,7 @@ function createNavigation() { // Инициализация при загрузке страницы document.addEventListener('DOMContentLoaded', function() { - createNavigation(); + // createNavigation(); // Если нужно обновлять навигацию при изменениях // window.addEventListener('userRoleChanged', createNavigation); diff --git a/public/profile.js b/public/profile.js index 3b880a1..23ebe57 100644 --- a/public/profile.js +++ b/public/profile.js @@ -15,56 +15,77 @@ async function loadUserProfile() { if (data.user) { const userInfo = document.getElementById('user-profile-info'); userInfo.innerHTML = ` -
-
- -
- Имя: -

${data.user.name}

+
+ +
+
+ +
+
+

${data.user.name}

+ + ${data.user.role === 'admin' ? 'Администратор' : 'Сотрудник'} +
-
- -
- Логин: -

${data.user.login}

-
-
-
- -
- Email: -

${data.user.email || 'Не указан'}

-
-
-
- -
- Роль: -

${data.user.role === 'admin' ? 'Администратор' : 'Учитель'}

-
-
-
- -
- Тип авторизации: -

${data.user.auth_type === 'ldap' ? 'LDAP' : 'Локальная'}

-
-
- ${data.user.groups && data.user.groups.length > 0 ? ` -
- -
- Группы: -

${Array.isArray(data.user.groups) ? data.user.groups.join(', ') : data.user.groups}

+ +
+
+
+ +
+
+ Логин + ${data.user.login}
- ` : ''} +
+
+ +
+
+ Тип авторизации + + ${data.user.auth_type === 'ldap' ? + ' LDAP' : + ' Локальная'} + +
+
+ + ${data.user.groups && data.user.groups.length > 0 ? ` +
+
+ +
+
+ Группы доступа +
+ ${Array.isArray(data.user.groups) ? + data.user.groups.map(group => + `${group}` + ).join('') : + `${data.user.groups}` + } +
+
+
+ ` : ''} +
`; } } catch (error) { console.error('Ошибка загрузки профиля:', error); + const userInfo = document.getElementById('user-profile-info'); + if (userInfo) { + userInfo.innerHTML = ` +
+ +

Ошибка загрузки профиля

+
+ `; + } } } diff --git a/public/style.css b/public/style.css index 28fa2bf..929ca42 100644 --- a/public/style.css +++ b/public/style.css @@ -4175,4 +4175,207 @@ button.btn-primary { background-color: #f1c40f; cursor: not-allowed; opacity: 0.7; +} +/* Современный профиль */ +.profile-modern { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + border-radius: 20px; + padding: 30px; + color: white; + margin-bottom: 30px; + box-shadow: 0 10px 40px rgba(0,0,0,0.1); +} + +.profile-header { + display: flex; + align-items: center; + gap: 20px; + margin-bottom: 30px; +} + +.profile-avatar { + width: 80px; + height: 80px; + background: rgba(255,255,255,0.2); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + border: 3px solid rgba(255,255,255,0.5); +} + +.profile-avatar i { + font-size: 50px; + color: white; +} + +.profile-title { + flex: 1; +} + +.profile-title h3 { + margin: 0 0 5px 0; + font-size: 24px; + font-weight: 600; +} + +.profile-badge { + display: inline-block; + padding: 5px 15px; + background: rgba(255,255,255,0.2); + border-radius: 20px; + font-size: 14px; + font-weight: 500; + backdrop-filter: blur(5px); +} + +.profile-badge.admin { + background: linear-gradient(45deg, #f093fb 0%, #f5576c 100%); +} + +.profile-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 15px; + margin-bottom: 30px; +} + +.profile-info-card { + background: rgba(255,255,255,0.1); + border-radius: 15px; + padding: 15px; + display: flex; + align-items: center; + gap: 15px; + backdrop-filter: blur(10px); + transition: transform 0.3s, background 0.3s; +} + +.profile-info-card:hover { + background: rgba(255,255,255,0.2); + transform: translateY(-2px); +} + +.info-icon { + width: 45px; + height: 45px; + background: rgba(255,255,255,0.2); + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; +} + +.info-icon i { + font-size: 20px; + color: white; +} + +.info-content { + flex: 1; + display: flex; + flex-direction: column; +} + +.info-label { + font-size: 12px; + opacity: 0.8; + margin-bottom: 2px; +} + +.info-value { + font-size: 16px; + font-weight: 600; +} + +.groups-card { + grid-column: 1 / -1; +} + +.groups-list { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-top: 5px; +} + +.group-tag { + background: rgba(255,255,255,0.2); + padding: 4px 12px; + border-radius: 15px; + font-size: 13px; + font-weight: 500; + backdrop-filter: blur(5px); +} + +.badge-ldap, .badge-local { + display: inline-flex; + align-items: center; + gap: 5px; + padding: 4px 12px; + border-radius: 15px; + font-size: 13px; + background: rgba(255,255,255,0.2); +} + +.profile-stats { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 15px; + margin-top: 20px; + padding-top: 20px; + border-top: 1px solid rgba(255,255,255,0.2); +} + +.stat-item { + text-align: center; +} + +.stat-value { + font-size: 28px; + font-weight: 700; + margin-bottom: 5px; +} + +.stat-label { + font-size: 13px; + opacity: 0.8; +} + +.profile-error { + background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); + border-radius: 20px; + padding: 30px; + color: white; + text-align: center; +} + +.profile-error i { + font-size: 40px; + margin-bottom: 10px; +} + +.profile-error p { + margin: 0; + font-size: 16px; +} + +/* Адаптивность */ +@media (max-width: 768px) { + .profile-modern { + padding: 20px; + } + + .profile-header { + flex-direction: column; + text-align: center; + } + + .profile-grid { + grid-template-columns: 1fr; + } + + .profile-stats { + grid-template-columns: 1fr; + } } \ No newline at end of file diff --git a/public/tasks.js b/public/tasks.js index a1ade4a..2925b79 100644 --- a/public/tasks.js +++ b/public/tasks.js @@ -467,6 +467,8 @@ function canUserEditTask(task) { // Администратор может всё if (currentUser.role === 'admin') return true; + // Пользователи с ролью 'tasks' могут редактировать любые задачи + if (currentUser.role === 'tasks') return true; // Создатель может редактировать свою задачу if (parseInt(task.created_by) === currentUser.id) { diff --git a/public/ui.js b/public/ui.js index 89b4954..692eb4a 100644 --- a/public/ui.js +++ b/public/ui.js @@ -87,8 +87,8 @@ function renderTasks() { ${currentUser && currentUser.login === 'minicrm' ? `` : ''} ${currentUser && currentUser.login === 'kalugin.o' ? `` : ''} -${currentUser && currentUser.login === 'kalugin.o' ? `` : ''} -${currentUser && currentUser.login === 'kalugin.o' ? `` : ''} +${currentUser && currentUser.role === 'tasks' && canEdit || currentUser.role === 'admin' ? `` : ''} +${currentUser && currentUser.role === 'tasks' && canEdit || currentUser.role === 'admin' ? `` : ''} ${currentUser && currentUser.login === 'minicrm' ? `` : ''} ${currentUser && currentUser.login === 'minicrm' ? `` : ''} @@ -1320,8 +1320,15 @@ async function assignAdd_openModal(taskId) { // Получаем доступных для добавления исполнителей try { const response = await fetch(`/api/tasks/${taskId}/available-assignees`); - const availableUsers = await response.json(); + //const availableUsers = await response.json(); + let availableUsers = await response.json(); + // 👇 ИСКЛЮЧАЕМ АВТОРА ЗАДАЧИ ИЗ СПИСКА 👇 + const taskCreatorId = task.created_by; + availableUsers = availableUsers.filter(user => + parseInt(user.id) !== parseInt(taskCreatorId) + ); + // Создаем модальное окно const modalHtml = `