From 4f82da47bba76e4a581dbd82d065384a74364e09 Mon Sep 17 00:00:00 2001 From: Katipa Date: Fri, 21 Aug 2026 10:28:48 +0000 Subject: [PATCH] =?UTF-8?q?Pulse:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=B1=D0=BB=D0=BE=D0=BA=D0=B8=20=D0=9D?= =?UTF-8?q?=D0=B5=D0=BC=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=B0=D1=8F=20=D0=BC=D0=BE=D1=82=D0=B8=D0=B2=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D1=8F,=20=D0=9A=D0=9F=D0=94,=20=D0=9A=D0=B0=D0=B4=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D1=8B=D0=B9=20=D1=80=D0=B5=D0=B7=D0=B5=D1=80=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.js | 176 +++++++++++++++++++++ data.js | 35 ++++- index.html | 293 +++++++++++++++++++++++++++++++++++ style.css | 446 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 949 insertions(+), 1 deletion(-) diff --git a/app.js b/app.js index 6acd138..66bf5a0 100644 --- a/app.js +++ b/app.js @@ -11,6 +11,9 @@ document.addEventListener('DOMContentLoaded', () => { initFilters(); initModals(); renderCharts(); + loadMotivation(); + loadKPI(); + loadReserve(); }); // Навигация между секциями @@ -247,6 +250,63 @@ function initForms() { e.target.reset(); }); + // Форма благодарности + document.getElementById('thankFormEl').addEventListener('submit', (e) => { + e.preventDefault(); + + const thank = { + id: Date.now(), + to: document.getElementById('thankTo').value, + from: document.getElementById('thankAnonymous').checked ? 'Анонимно' : appData.profile.name, + reason: document.getElementById('thankReason').value, + type: document.getElementById('thankType').value, + date: new Date().toISOString().split('T')[0], + anonymous: document.getElementById('thankAnonymous').checked + }; + + appData.motivation.thanks.unshift(thank); + saveData(appData); + + document.getElementById('thankForm').style.display = 'none'; + loadMotivation(); + alert('Благодарность отправлена!'); + }); + + // Цели КПД + document.getElementById('kpiGoalsForm').addEventListener('submit', (e) => { + e.preventDefault(); + + appData.kpi.goals = [ + document.getElementById('kpiGoal1').value, + document.getElementById('kpiGoal2').value, + document.getElementById('kpiGoal3').value + ]; + saveData(appData); + + alert('Цели сохранены!'); + }); + + // Заявка в кадровый резерв + document.getElementById('reserveFormEl').addEventListener('submit', (e) => { + e.preventDefault(); + + const application = { + id: Date.now(), + position: document.getElementById('reservePosition').value, + experience: document.getElementById('reserveExperience').value, + motivation: document.getElementById('reserveMotivation').value, + skills: document.getElementById('reserveSkills').value, + date: new Date().toISOString().split('T')[0], + status: 'new' + }; + + appData.reserve.applications.push(application); + saveData(appData); + + document.getElementById('reserveForm').style.display = 'none'; + alert('Заявка подана! HR свяжется с вами.'); + }); + // Форма автоматизации document.getElementById('automationForm').addEventListener('submit', (e) => { e.preventDefault(); @@ -423,6 +483,122 @@ window.closeModal = function(modalId) { document.getElementById(modalId).classList.remove('active'); }; +// Мотивация +function loadMotivation() { + const mot = appData.motivation; + + if (mot.employeeOfMonth) { + const empEl = document.getElementById('employeeOfMonth'); + if (empEl) { + empEl.innerHTML = ` +
${mot.employeeOfMonth.avatar}
+
${mot.employeeOfMonth.name}
+
${mot.employeeOfMonth.dept}
+ `; + } + } + + if (mot.ideaOfMonth) { + const ideaEl = document.getElementById('ideaOfMonth'); + if (ideaEl) { + ideaEl.innerHTML = ` +
${mot.ideaOfMonth.title}
+
${mot.ideaOfMonth.author}
+ `; + } + } + + const thanksList = document.getElementById('thanksList'); + if (thanksList && mot.thanks) { + thanksList.innerHTML = mot.thanks.map(t => ` +
+
+ ${t.to} + ${getThankTypeName(t.type)} +
+
${t.reason}
+
+ От: ${t.anonymous ? 'Анонимно' : t.from} + ${formatDate(t.date)} +
+
+ `).join(''); + } +} + +window.showThankForm = function() { + document.getElementById('thankForm').style.display = 'block'; + document.getElementById('thankFormEl').reset(); +}; + +window.nominateEmployee = function() { + alert('Форма номинации будет доступна в конце месяца'); +}; + +window.loadAchievements = function() { + const achievements = appData.motivation.achievements; + const html = achievements.map(a => ` +
+ ${a.icon} + ${a.name} + x${a.count} +
+ `).join(''); + alert('Ваши достижения:\n\n' + achievements.map(a => `${a.icon} ${a.name}: ${a.count}`).join('\n')); +}; + +function getThankTypeName(type) { + const names = { + help: 'За помощь', + mentor: 'За наставничество', + initiative: 'За инициативу', + team: 'За команду', + other: 'Другое' + }; + return names[type] || type; +} + +// КПД +function loadKPI() { + const kpi = appData.kpi; + + document.getElementById('kpiValue').textContent = kpi.overall; + document.getElementById('kpiCirclePath').style.strokeDasharray = `${kpi.overall}, 100`; + + const kpiChartCanvas = document.getElementById('kpiChartCanvas'); + if (kpiChartCanvas) { + const ctx = kpiChartCanvas.getContext('2d'); + drawLineChart(ctx, kpi.history, '#4A90E2', 400, 200); + } +} + +// Кадровый резерв +function loadReserve() { + const participants = appData.reserve.participants; + const list = document.getElementById('participantsList'); + if (list) { + list.innerHTML = participants.map(p => ` +
+
👤
+
+
${p.name}
+
${p.dept}
+
Этап: ${p.stage}
+
+
+
+ ${p.progress}% +
+
+ `).join(''); + } +} + +window.showReserveForm = function() { + document.getElementById('reserveForm').style.display = 'block'; + document.getElementById('reserveForm').scrollIntoView({ behavior: 'smooth' }); +}; + window.resetFeedbackForm = function() { document.getElementById('feedbackForm').reset(); document.getElementById('feedbackForm').style.display = 'flex'; diff --git a/data.js b/data.js index ecb92c6..483c3e9 100644 --- a/data.js +++ b/data.js @@ -35,9 +35,42 @@ const INITIAL_DATA = { }, settings: { engagementIndex: 78, - engagementTrend: 'up', // up, stable, down + engagementTrend: 'up', totalEmployees: 245, departments: ['hr', 'it', 'finance', 'procurement', 'sales', 'support'] + }, + motivation: { + employeeOfMonth: { name: 'Алексей К.', dept: 'IT Департамент', avatar: '👤' }, + ideaOfMonth: { title: 'Чат-бот для HR', author: 'Сергей Л.' }, + thanks: [ + { id: 1, to: 'Мария С.', from: 'Александр И.', reason: 'За помощь в обучении новой системы', type: 'help', date: '2026-08-18', anonymous: false }, + { id: 2, to: 'Дмитрий В.', from: 'Анонимно', reason: 'За наставничество и поддержку', type: 'mentor', date: '2026-08-17', anonymous: true }, + { id: 3, to: 'Ольга Н.', from: 'Анна П.', reason: 'За инициативу в оптимизации закупок', type: 'initiative', date: '2026-08-15', anonymous: false } + ], + achievements: [ + { id: 1, name: 'Новичок года', icon: '🌟', count: 1 }, + { id: 2, name: 'Генератор идей', icon: '💡', count: 3 }, + { id: 3, name: 'Наставник', icon: '🎓', count: 2 } + ] + }, + kpi: { + overall: 75, + components: { + tasks: 85, + deadlines: 78, + quality: 82, + initiative: 65, + team: 88 + }, + history: [68, 70, 72, 71, 74, 75], + goals: ['', '', ''] + }, + reserve: { + participants: [ + { id: 1, name: 'Мария С.', dept: 'HR Департамент', stage: 'Обучение', progress: 50 }, + { id: 2, name: 'Дмитрий В.', dept: 'IT Департамент', stage: 'Стажировка', progress: 75 } + ], + applications: [] } }; diff --git a/index.html b/index.html index 1a99712..991f18a 100644 --- a/index.html +++ b/index.html @@ -20,6 +20,9 @@ Трудовая дисциплина Автоматизация Инновации + Мотивация + КПД + Кадровый резерв Обратная связь Профиль Аналитика @@ -410,6 +413,296 @@ + +
+
+

Нематериальная мотивация

+

Признание заслуг и поощрение сотрудников

+
+ +
+
+

🏆 Сотрудник месяца

+

Лучший сотрудник по итогам месяца

+
+
👤
+
Алексей К.
+
IT Департамент
+
+ +
+ +
+

⭐ Благодарности

+

Поблагодарите коллегу за помощь

+ +
+ +
+

🎖 Достижения

+

Ваши награды и значки

+ +
+ +
+

💡 Идея месяца

+

Лучшая идея месяца

+
+
Чат-бот для HR
+
Сергей Л.
+
+
+
+ +
+

Стена благодарностей

+
+
+ + +
+ + +
+
+

КПД сотрудника

+

Оценка эффективности и продуктивности

+
+ +
+
+
👤
+
+

Александр Иванов

+

IT Департамент

+
+
+ +
+
+ + + + +
75
+
+
Общий КПД
+
+ +
+
+
Выполнение задач
+
+
85%
+
+
+
Соблюдение сроков
+
+
78%
+
+
+
Качество работы
+
+
82%
+
+
+
Инициативность
+
+
65%
+
+
+
Командная работа
+
+
88%
+
+
+
+ +
+

Динамика КПД

+
+ +
+
+ +
+

Цели на следующий период

+
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+ + +
+
+

Кадровый резерв

+

Программа развития и подготовки руководителей

+
+ +
+
+

🎯 Программа кадрового резерва

+

Участвуйте в программе подготовки руководителей и получите возможность карьерного роста

+ +
+
+ +
+

Требования для участия

+
+
+
📊
+
Стаж работы
+
Не менее 2 лет в компании
+
+
+
⭐
+
Рейтинг
+
КПД не ниже 75%
+
+
+
🎓
+
Обучение
+
Пройденные курсы лидерства
+
+
+
💡
+
Инициативы
+
Реализованные проекты
+
+
+
+ +
+

Этапы программы

+
+
+
1
+
+

Отборочный этап

+

Собеседование с HR, оценка компетенций

+
+
+
+
2
+
+

Обучение

+

Курсы по управлению, лидерству, коммуникациям

+
+
+
+
3
+
+

Стажировка

+

Практика под руководством наставника

+
+
+
+
4
+
+

Аттестация

+

Финальная оценка и включение в резерв

+
+
+
+
+ +
+

Текущие участники программы

+
+
+
👤
+
+
Мария С.
+
HR Департамент
+
Этап: Обучение
+
+
+
+ 50% +
+
+
+
👤
+
+
Дмитрий В.
+
IT Департамент
+
Этап: Стажировка
+
+
+
+ 75% +
+
+
+
+ + +
+
diff --git a/style.css b/style.css index 1259174..05a5bc6 100644 --- a/style.css +++ b/style.css @@ -836,6 +836,452 @@ textarea { color: var(--primary); } +/* Motivation */ +.motivation-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 20px; + margin-bottom: 32px; +} + +.motivation-card { + background: var(--white); + padding: 24px; + border-radius: 12px; + box-shadow: var(--shadow); + text-align: center; +} + +.motivation-card.highlight { + background: linear-gradient(135deg, var(--primary), var(--secondary)); + color: var(--white); +} + +.motivation-card h3 { + font-size: 18px; + margin-bottom: 8px; +} + +.motivation-card p { + color: var(--text-gray); + margin-bottom: 16px; + font-size: 14px; +} + +.motivation-card.highlight p { + color: rgba(255,255,255,0.9); +} + +.employee-badge, +.idea-badge { + background: rgba(255,255,255,0.2); + padding: 16px; + border-radius: 8px; + margin-bottom: 16px; +} + +.badge-avatar { + font-size: 48px; + margin-bottom: 8px; +} + +.badge-name { + font-size: 18px; + font-weight: 600; + margin-bottom: 4px; +} + +.badge-dept { + font-size: 14px; + opacity: 0.9; +} + +.idea-badge-title { + font-size: 16px; + font-weight: 600; + margin-bottom: 4px; +} + +.idea-badge-author { + font-size: 14px; + opacity: 0.9; +} + +.thanks-wall { + background: var(--white); + padding: 24px; + border-radius: 12px; + box-shadow: var(--shadow); + margin-top: 24px; +} + +.thanks-wall h2 { + font-size: 20px; + margin-bottom: 16px; +} + +.thanks-list { + display: grid; + gap: 16px; +} + +.thank-card { + border: 1px solid var(--border); + border-radius: 8px; + padding: 16px; + background: var(--bg-light); +} + +.thank-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 8px; +} + +.thank-to { + font-weight: 600; + font-size: 16px; +} + +.thank-type { + padding: 4px 12px; + border-radius: 20px; + font-size: 12px; + background: var(--primary-light); + color: var(--primary); +} + +.thank-reason { + color: var(--text-dark); + margin-bottom: 8px; +} + +.thank-meta { + display: flex; + gap: 16px; + font-size: 13px; + color: var(--text-gray); +} + +.thank-form { + background: var(--white); + padding: 32px; + border-radius: 12px; + box-shadow: var(--shadow); + margin-top: 24px; + max-width: 600px; +} + +.thank-form h3 { + margin-bottom: 20px; +} + +/* KPI Employee */ +.kpi-employee-card { + background: var(--white); + padding: 32px; + border-radius: 12px; + box-shadow: var(--shadow); + margin-bottom: 24px; +} + +.kpi-employee-header { + display: flex; + align-items: center; + gap: 20px; + margin-bottom: 32px; +} + +.kpi-avatar { + font-size: 64px; +} + +.kpi-employee-header h2 { + font-size: 24px; + margin-bottom: 4px; +} + +.kpi-dept { + color: var(--text-gray); +} + +.kpi-score { + text-align: center; + margin-bottom: 32px; +} + +.kpi-circle { + position: relative; + width: 150px; + height: 150px; + margin: 0 auto 16px; +} + +.kpi-svg { + width: 100%; + height: 100%; + transform: rotate(-90deg); +} + +.kpi-value { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + font-size: 36px; + font-weight: 700; + color: var(--primary); +} + +.kpi-label { + font-size: 16px; + color: var(--text-gray); +} + +.kpi-components { + display: grid; + gap: 16px; + max-width: 600px; + margin: 0 auto; +} + +.kpi-component { + display: grid; + grid-template-columns: 1fr 80px 50px; + align-items: center; + gap: 12px; +} + +.kpi-comp-label { + font-size: 14px; + color: var(--text-gray); +} + +.kpi-bar { + height: 8px; + background: var(--border); + border-radius: 4px; + overflow: hidden; +} + +.kpi-bar-fill { + height: 100%; + background: var(--primary); + border-radius: 4px; + transition: width 0.3s; +} + +.kpi-comp-value { + font-weight: 600; + color: var(--primary); + font-size: 14px; +} + +.kpi-dynamics, +.kpi-goals { + background: var(--white); + padding: 24px; + border-radius: 12px; + box-shadow: var(--shadow); + margin-bottom: 24px; +} + +.kpi-dynamics h3, +.kpi-goals h3 { + margin-bottom: 16px; +} + +.kpi-chart { + height: 250px; + background: var(--bg-light); + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; +} + +.kpi-goals form { + max-width: 600px; + display: flex; + flex-direction: column; + gap: 16px; +} + +/* Reserve */ +.reserve-info { + margin-bottom: 32px; +} + +.reserve-banner { + background: linear-gradient(135deg, var(--primary), var(--secondary)); + color: var(--white); + padding: 40px; + border-radius: 12px; + text-align: center; +} + +.reserve-banner h2 { + font-size: 28px; + margin-bottom: 12px; +} + +.reserve-banner p { + font-size: 16px; + margin-bottom: 24px; + opacity: 0.95; +} + +.reserve-requirements, +.reserve-program, +.reserve-participants { + background: var(--white); + padding: 24px; + border-radius: 12px; + box-shadow: var(--shadow); + margin-bottom: 24px; +} + +.reserve-requirements h3, +.reserve-program h3, +.reserve-participants h3 { + margin-bottom: 20px; +} + +.requirements-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); + gap: 16px; +} + +.requirement-card { + background: var(--bg-light); + padding: 20px; + border-radius: 8px; + text-align: center; +} + +.req-icon { + font-size: 36px; + margin-bottom: 12px; +} + +.req-title { + font-weight: 600; + margin-bottom: 8px; +} + +.req-desc { + font-size: 14px; + color: var(--text-gray); +} + +.stages-timeline { + display: grid; + gap: 20px; +} + +.stage { + display: flex; + gap: 16px; + align-items: flex-start; +} + +.stage-dot { + width: 40px; + height: 40px; + border-radius: 50%; + background: var(--primary); + color: var(--white); + display: flex; + align-items: center; + justify-content: center; + font-weight: 700; + flex-shrink: 0; +} + +.stage-content h4 { + font-size: 18px; + margin-bottom: 4px; +} + +.stage-content p { + color: var(--text-gray); + font-size: 14px; +} + +.participants-list { + display: grid; + gap: 16px; +} + +.participant-card { + display: flex; + align-items: center; + gap: 16px; + padding: 16px; + border: 1px solid var(--border); + border-radius: 8px; +} + +.participant-avatar { + font-size: 40px; +} + +.participant-info { + flex: 1; +} + +.participant-name { + font-weight: 600; + margin-bottom: 4px; +} + +.participant-dept { + font-size: 13px; + color: var(--text-gray); + margin-bottom: 4px; +} + +.participant-stage { + font-size: 13px; + color: var(--primary); +} + +.participant-progress { + display: flex; + align-items: center; + gap: 12px; + min-width: 120px; +} + +.progress-bar { + flex: 1; + height: 8px; + background: var(--border); + border-radius: 4px; + overflow: hidden; +} + +.progress-fill { + height: 100%; + background: var(--primary); + border-radius: 4px; + transition: width 0.3s; +} + +.reserve-form { + background: var(--white); + padding: 32px; + border-radius: 12px; + box-shadow: var(--shadow); + max-width: 700px; +} + +.reserve-form h3 { + margin-bottom: 20px; +} + /* Modal */ .modal { display: none;