218 lines
12 KiB
HTML
218 lines
12 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="ru">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Рейтинг сотрудника</title>
|
||
<script src="https://cdn.tailwindcss.com"></script>
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
|
||
<style>
|
||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
|
||
body { font-family: 'Inter', sans-serif; }
|
||
.gradient-bg { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); }
|
||
.card { transition: all 0.3s ease; }
|
||
.card:hover { transform: translateY(-2px); box-shadow: 0 10px 25px rgba(0,0,0,0.1); }
|
||
.trend-up { color: #10b981; }
|
||
.trend-down { color: #ef4444; }
|
||
.trend-neutral { color: #6b7280; }
|
||
.warning-badge { background: #fef3c7; color: #92400e; border: 1px solid #fcd34d; }
|
||
.low-availability { background: #fee2e2; color: #991b1b; }
|
||
.modal-overlay { background: rgba(0,0,0,0.5); }
|
||
.tab-active { border-bottom: 2px solid #667eea; color: #667eea; }
|
||
</style>
|
||
</head>
|
||
<body class="bg-gray-50 min-h-screen">
|
||
<!-- Header -->
|
||
<header class="gradient-bg text-white py-6 shadow-lg">
|
||
<div class="container mx-auto px-4">
|
||
<h1 class="text-3xl font-bold mb-2">📊 Рейтинг сотрудника</h1>
|
||
<p class="text-purple-100">Анализ рейтинга с учётом фактически отработанного времени</p>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- Main Content -->
|
||
<main class="container mx-auto px-4 py-8">
|
||
<!-- Upload Section -->
|
||
<section id="uploadSection" class="mb-8">
|
||
<div class="bg-white rounded-xl shadow-md p-6 card">
|
||
<h2 class="text-xl font-semibold mb-4 text-gray-800">📁 Загрузка отчёта</h2>
|
||
<div class="flex items-center gap-4">
|
||
<label class="block">
|
||
<span class="sr-only">Выберите Excel файл</span>
|
||
<input type="file" id="fileInput" accept=".xlsx,.xls"
|
||
class="block w-full text-sm text-gray-500 file:mr-4 file:py-3 file:px-6 file:rounded-lg file:border-0 file:text-sm file:font-semibold file:bg-purple-50 file:text-purple-700 hover:file:bg-purple-100 cursor-pointer"/>
|
||
</label>
|
||
<button onclick="processFile()" class="bg-purple-600 hover:bg-purple-700 text-white px-6 py-3 rounded-lg font-medium transition">
|
||
Загрузить
|
||
</button>
|
||
</div>
|
||
<p class="text-sm text-gray-500 mt-2">Загрузите файл «Сводный рейтинг с нарастающим итогом за 01.08–06.08.2026»</p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Filters & Controls -->
|
||
<section id="controlsSection" class="mb-6 hidden">
|
||
<div class="bg-white rounded-xl shadow-md p-6">
|
||
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-2">Подразделение</label>
|
||
<select id="deptFilter" onchange="applyFilters()" class="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-purple-500 focus:border-transparent">
|
||
<option value="">Все подразделения</option>
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-2">Сотрудник</label>
|
||
<input type="text" id="nameFilter" placeholder="Поиск по ФИО" oninput="applyFilters()"
|
||
class="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-purple-500 focus:border-transparent"/>
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-2">Период</label>
|
||
<input type="text" id="periodDisplay" readonly class="w-full border border-gray-300 rounded-lg px-3 py-2 bg-gray-50"/>
|
||
</div>
|
||
<div class="flex items-end">
|
||
<button onclick="switchView('table')" id="tableViewBtn" class="tab-active px-4 py-2 font-medium">📋 Таблица</button>
|
||
<button onclick="switchView('analysis')" id="analysisViewBtn" class="px-4 py-2 font-medium text-gray-600">📈 Анализ периода</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Table View -->
|
||
<section id="tableView" class="hidden">
|
||
<div class="bg-white rounded-xl shadow-md overflow-hidden">
|
||
<div class="overflow-x-auto">
|
||
<table class="w-full">
|
||
<thead class="bg-gray-100">
|
||
<tr>
|
||
<th class="px-4 py-3 text-left text-xs font-semibold text-gray-600 uppercase">Место</th>
|
||
<th class="px-4 py-3 text-left text-xs font-semibold text-gray-600 uppercase">ФИО</th>
|
||
<th class="px-4 py-3 text-left text-xs font-semibold text-gray-600 uppercase">Подразделение</th>
|
||
<th class="px-4 py-3 text-left text-xs font-semibold text-gray-600 uppercase">Рейтинг</th>
|
||
<th class="px-4 py-3 text-left text-xs font-semibold text-gray-600 uppercase">Предыдущее</th>
|
||
<th class="px-4 py-3 text-left text-xs font-semibold text-gray-600 uppercase">Δ</th>
|
||
<th class="px-4 py-3 text-left text-xs font-semibold text-gray-600 uppercase">Коэфф. доступности</th>
|
||
<th class="px-4 py-3 text-left text-xs font-semibold text-gray-600 uppercase">Статус</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="ratingTableBody" class="divide-y divide-gray-200"></tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Analysis View -->
|
||
<section id="analysisView" class="hidden">
|
||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
|
||
<!-- TOP Employees -->
|
||
<div class="bg-white rounded-xl shadow-md p-6 card">
|
||
<h3 class="text-lg font-semibold text-gray-800 mb-4">🏆 ТОП сотрудников</h3>
|
||
<div id="topEmployees" class="space-y-3"></div>
|
||
</div>
|
||
|
||
<!-- Biggest Growth -->
|
||
<div class="bg-white rounded-xl shadow-md p-6 card">
|
||
<h3 class="text-lg font-semibold text-gray-800 mb-4">📈 Наибольший рост</h3>
|
||
<div id="biggestGrowth" class="space-y-3"></div>
|
||
</div>
|
||
|
||
<!-- Biggest Decline -->
|
||
<div class="bg-white rounded-xl shadow-md p-6 card">
|
||
<h3 class="text-lg font-semibold text-gray-800 mb-4">📉 Наибольшее снижение</h3>
|
||
<div id="biggestDecline" class="space-y-3"></div>
|
||
</div>
|
||
|
||
<!-- Low Availability -->
|
||
<div class="bg-white rounded-xl shadow-md p-6 card">
|
||
<h3 class="text-lg font-semibold text-gray-800 mb-4">⚠️ Низкая доступность</h3>
|
||
<div id="lowAvailability" class="space-y-3"></div>
|
||
</div>
|
||
|
||
<!-- Needs Review -->
|
||
<div class="bg-white rounded-xl shadow-md p-6 card">
|
||
<h3 class="text-lg font-semibold text-gray-800 mb-4">🔍 Требует проверки</h3>
|
||
<div id="needsReview" class="space-y-3"></div>
|
||
</div>
|
||
|
||
<!-- Summary Stats -->
|
||
<div class="bg-white rounded-xl shadow-md p-6 card">
|
||
<h3 class="text-lg font-semibold text-gray-800 mb-4">📊 Общая статистика</h3>
|
||
<div id="summaryStats" class="space-y-3"></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
<!-- Employee Modal -->
|
||
<div id="employeeModal" class="modal-overlay fixed inset-0 hidden items-center justify-center z-50">
|
||
<div class="bg-white rounded-2xl shadow-2xl max-w-4xl w-full mx-4 max-h-[90vh] overflow-y-auto">
|
||
<div class="gradient-bg text-white p-6 rounded-t-2xl">
|
||
<div class="flex justify-between items-start">
|
||
<div>
|
||
<h2 id="modalName" class="text-2xl font-bold"></h2>
|
||
<p id="modalDept" class="text-purple-100"></p>
|
||
</div>
|
||
<button onclick="closeModal()" class="text-white hover:text-gray-200 text-2xl">×</button>
|
||
</div>
|
||
</div>
|
||
<div class="p-6">
|
||
<!-- Rating Overview -->
|
||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
|
||
<div class="bg-purple-50 rounded-xl p-4">
|
||
<p class="text-sm text-gray-600">Текущий рейтинг</p>
|
||
<p id="modalRating" class="text-3xl font-bold text-purple-700"></p>
|
||
</div>
|
||
<div class="bg-blue-50 rounded-xl p-4">
|
||
<p class="text-sm text-gray-600">Предыдущее место</p>
|
||
<p id="modalPrevPlace" class="text-3xl font-bold text-blue-700"></p>
|
||
</div>
|
||
<div class="bg-green-50 rounded-xl p-4">
|
||
<p class="text-sm text-gray-600">Коэффициент доступности</p>
|
||
<p id="modalAvailability" class="text-3xl font-bold text-green-700"></p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Availability Details -->
|
||
<div class="mb-6">
|
||
<h3 class="text-lg font-semibold text-gray-800 mb-3">⏱️ Рабочее время</h3>
|
||
<div class="bg-gray-50 rounded-xl p-4 space-y-2">
|
||
<div class="flex justify-between">
|
||
<span class="text-gray-600">Плановое рабочее время:</span>
|
||
<span id="modalPlannedHours" class="font-medium"></span>
|
||
</div>
|
||
<div class="flex justify-between">
|
||
<span class="text-gray-600">Время отсутствия:</span>
|
||
<span id="modalAbsenceHours" class="font-medium"></span>
|
||
</div>
|
||
<div class="flex justify-between">
|
||
<span class="text-gray-600">Доступное рабочее время:</span>
|
||
<span id="modalAvailableHours" class="font-medium"></span>
|
||
</div>
|
||
<div class="border-t pt-2 flex justify-between">
|
||
<span class="text-gray-600">График:</span>
|
||
<span id="modalSchedule" class="font-medium"></span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Absences -->
|
||
<div class="mb-6">
|
||
<h3 class="text-lg font-semibold text-gray-800 mb-3">📋 Отсутствия</h3>
|
||
<div id="modalAbsences" class="bg-gray-50 rounded-xl p-4"></div>
|
||
</div>
|
||
|
||
<!-- Warnings -->
|
||
<div id="modalWarnings" class="mb-6"></div>
|
||
|
||
<!-- Rating Explanation -->
|
||
<div class="bg-yellow-50 border border-yellow-200 rounded-xl p-4">
|
||
<h3 class="text-lg font-semibold text-yellow-800 mb-2">💡 Прозрачность расчёта</h3>
|
||
<p id="modalExplanation" class="text-sm text-yellow-700"></p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="app.js"></script>
|
||
</body>
|
||
</html>
|