Files
2026-05-17 05:22:06 +03:00

210 lines
10 KiB
PHP

<?php
require_once __DIR__ . '/../../inc/auth.php';
require_once __DIR__ . '/../../inc/functions.php';
$session = auth_require('owner');
$pdo = getDB();
$message = '';
// Create / Update user
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$id = (int)($_POST['id'] ?? 0);
$login = trim($_POST['login'] ?? '');
$password = $_POST['password'] ?? '';
$fullName = trim($_POST['full_name'] ?? '');
$role = $_POST['role'] ?? 'technician';
$phone = trim($_POST['phone'] ?? '');
$email = trim($_POST['email'] ?? '');
$isActive = isset($_POST['is_active']) ? 1 : 0;
$csrf = $_POST['csrf_token'] ?? '';
if (!auth_csrf_verify($csrf)) {
$message = 'Ошибка безопасности.';
} elseif ($login === '' || $fullName === '') {
$message = 'Заполните обязательные поля.';
} elseif ($id === 0 && $password === '') {
$message = 'Пароль обязателен для нового сотрудника.';
} else {
try {
// Check if we're editing an owner — prevent role change
$isOwnerEdit = false;
if ($id > 0) {
$checkStmt = $pdo->prepare("SELECT role FROM users WHERE id=?");
$checkStmt->execute([$id]);
$checkRow = $checkStmt->fetch();
if ($checkRow && $checkRow['role'] === 'owner') {
$isOwnerEdit = true;
$role = 'owner'; // Force owner role, ignore POST value
}
}
if ($id > 0) {
// Update
if ($password !== '') {
$hash = password_hash($password, PASSWORD_BCRYPT);
$stmt = $pdo->prepare("UPDATE users SET login=?, password_hash=?, full_name=?, role=?, phone=?, email=?, is_active=? WHERE id=?");
$stmt->execute([$login, $hash, $fullName, $role, $phone, $email, $isActive, $id]);
} else {
$stmt = $pdo->prepare("UPDATE users SET login=?, full_name=?, role=?, phone=?, email=?, is_active=? WHERE id=?");
$stmt->execute([$login, $fullName, $role, $phone, $email, $isActive, $id]);
}
$message = $isOwnerEdit ? 'Профиль обновлён.' : 'Сотрудник обновлён.';
auth_log($session['user_id'], 'user_update', "ID: $id");
} else {
$hash = password_hash($password, PASSWORD_BCRYPT);
$stmt = $pdo->prepare("INSERT INTO users (login, password_hash, full_name, role, phone, email, is_active) VALUES (?,?,?,?,?,?,?)");
$stmt->execute([$login, $hash, $fullName, $role, $phone, $email, $isActive]);
$message = 'Сотрудник создан.';
auth_log($session['user_id'], 'user_create', "Login: $login");
}
} catch (\PDOException $e) {
$message = 'Ошибка: ' . ($e->getCode() === '23000' ? 'Логин уже занят.' : $e->getMessage());
}
}
}
// Delete user
if (isset($_GET['delete'])) {
$id = (int)$_GET['delete'];
$csrf = $_GET['csrf'] ?? '';
if (auth_csrf_verify($csrf)) {
$stmt = $pdo->prepare("DELETE FROM users WHERE id=? AND role!='owner'");
$stmt->execute([$id]);
$message = 'Сотрудник удалён.';
auth_log($session['user_id'], 'user_delete', "ID: $id");
}
}
// Get edit user
$editUser = null;
$isEditingOwner = false;
if (isset($_GET['edit'])) {
$stmt = $pdo->prepare("SELECT * FROM users WHERE id=?");
$stmt->execute([(int)$_GET['edit']]);
$editUser = $stmt->fetch();
if ($editUser && $editUser['role'] === 'owner') {
$isEditingOwner = true;
}
}
// Get all users (except owner for editing, but show owner in list)
$users = $pdo->query("SELECT id, login, full_name, role, phone, email, is_active, created_at FROM users ORDER BY role, full_name")->fetchAll();
$csrf = auth_csrf_token();
require __DIR__ . '/../../inc/header.php';
?>
<div class="main-header">
<div>
<h1>Сотрудники</h1>
<div class="breadcrumb"><a href="/service/dashboard.php">Главная</a> / Сотрудники</div>
</div>
<button class="btn btn-primary btn-sm" onclick="openModal()" data-tooltip="Добавить сотрудника">+ Добавить</button>
</div>
<?php if ($message): ?>
<div class="alert alert-info"><?= htmlspecialchars($message) ?></div>
<?php endif; ?>
<div class="card">
<div class="table-wrap">
<table>
<thead>
<tr>
<th>Логин</th>
<th>ФИО</th>
<th>Роль</th>
<th>Телефон</th>
<th>Email</th>
<th>Статус</th>
<th>Создан</th>
<th class="actions">Действия</th>
</tr>
</thead>
<tbody>
<?php foreach ($users as $u): ?>
<tr>
<td><?= htmlspecialchars($u['login']) ?></td>
<td><?= htmlspecialchars($u['full_name']) ?></td>
<td><span class="badge badge-<?= $u['role'] === 'owner' ? 'critical' : ($u['role'] === 'engineer' ? 'high' : 'medium') ?>"><?= $u['role'] === 'owner' ? 'Владелец' : ($u['role'] === 'engineer' ? 'Инженер' : 'Техник') ?></span></td>
<td><?= htmlspecialchars($u['phone'] ?: '—') ?></td>
<td><?= htmlspecialchars($u['email'] ?: '—') ?></td>
<td><span class="badge <?= $u['is_active'] ? 'badge-active' : 'badge-inactive' ?>"><?= $u['is_active'] ? 'Активен' : 'Заблокирован' ?></span></td>
<td><?= date('d.m.Y', strtotime($u['created_at'])) ?></td>
<td class="actions">
<a href="?edit=<?= $u['id'] ?>" class="btn btn-secondary btn-sm" data-tooltip="Редактировать">✏️</a>
<?php if ($u['role'] !== 'owner'): ?>
<a href="?delete=<?= $u['id'] ?>&csrf=<?= $csrf ?>" class="btn btn-danger btn-sm" onclick="return confirm('Удалить сотрудника?')" data-tooltip="Удалить">🗑️</a>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<!-- Modal -->
<div class="modal-overlay <?= $editUser ? 'open' : '' ?>" id="userModal">
<div class="modal">
<button class="modal-close" onclick="closeModal()">&times;</button>
<h2><?= $editUser ? ($isEditingOwner ? 'Редактировать профиль' : 'Редактировать сотрудника') : 'Добавить сотрудника' ?></h2>
<form method="post">
<input type="hidden" name="csrf_token" value="<?= $csrf ?>">
<input type="hidden" name="id" value="<?= $editUser['id'] ?? 0 ?>">
<div class="form-row">
<div class="form-group">
<label for="login">Логин *</label>
<input type="text" id="login" name="login" value="<?= htmlspecialchars($editUser['login'] ?? '') ?>" required>
</div>
<div class="form-group">
<label for="full_name">ФИО *</label>
<input type="text" id="full_name" name="full_name" value="<?= htmlspecialchars($editUser['full_name'] ?? '') ?>" required>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="password">Пароль <?= $editUser ? '(оставьте пустым, чтобы не менять)' : '*' ?></label>
<input type="password" id="password" name="password" <?= $editUser ? '' : 'required' ?>>
</div>
<div class="form-group">
<label for="role">Роль *</label>
<?php if ($isEditingOwner): ?>
<input type="text" value="Владелец" disabled style="opacity:0.6;">
<input type="hidden" name="role" value="owner">
<?php else: ?>
<select id="role" name="role" required>
<option value="engineer" <?= ($editUser['role'] ?? '') === 'engineer' ? 'selected' : '' ?>>Инженер</option>
<option value="technician" <?= ($editUser['role'] ?? '') === 'technician' ? 'selected' : '' ?>>Техник</option>
</select>
<?php endif; ?>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="phone">Телефон</label>
<input type="text" id="phone" name="phone" value="<?= htmlspecialchars($editUser['phone'] ?? '') ?>">
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" id="email" name="email" value="<?= htmlspecialchars($editUser['email'] ?? '') ?>">
</div>
</div>
<div class="form-check" style="margin-bottom:16px;">
<input type="checkbox" id="is_active" name="is_active" <?= (!isset($editUser) || $editUser['is_active']) ? 'checked' : '' ?>>
<label for="is_active">Активен</label>
</div>
<button type="submit" class="btn btn-primary">Сохранить</button>
<button type="button" class="btn btn-secondary" onclick="closeModal()">Отмена</button>
</form>
</div>
</div>
<script>
function openModal() { document.getElementById('userModal').classList.add('open'); }
function closeModal() { document.getElementById('userModal').classList.remove('open'); window.location.href = 'users.php'; }
</script>
<?php require __DIR__ . '/../../inc/footer.php'; ?>