468 lines
18 KiB
PHP
468 lines
18 KiB
PHP
<?php
|
|
require_once __DIR__ . '/../includes/auth.php';
|
|
require_once __DIR__ . '/../includes/functions.php';
|
|
|
|
requireRole('admin'); // Tylko administratorzy
|
|
|
|
$message = '';
|
|
$error = '';
|
|
$db = getDB();
|
|
|
|
// Obsługa akcji
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
if (isset($_POST['action'])) {
|
|
switch ($_POST['action']) {
|
|
case 'create':
|
|
// Walidacja
|
|
if (strlen($_POST['username']) < 3) {
|
|
$error = 'Nazwa użytkownika musi mieć co najmniej 3 znaki';
|
|
} elseif (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
|
|
$error = 'Nieprawidłowy adres email';
|
|
} elseif (strlen($_POST['password']) < 6) {
|
|
$error = 'Hasło musi mieć co najmniej 6 znaków';
|
|
} else {
|
|
// Sprawdź czy użytkownik już istnieje
|
|
$stmt = $db->prepare("SELECT id FROM users WHERE username = ? OR email = ?");
|
|
$stmt->execute([$_POST['username'], $_POST['email']]);
|
|
|
|
if ($stmt->fetch()) {
|
|
$error = 'Użytkownik o tej nazwie lub emailu już istnieje';
|
|
} else {
|
|
// Utwórz użytkownika
|
|
$hashedPassword = password_hash($_POST['password'], PASSWORD_DEFAULT);
|
|
$stmt = $db->prepare("
|
|
INSERT INTO users (username, email, password, role, status)
|
|
VALUES (?, ?, ?, ?, ?)
|
|
");
|
|
|
|
if ($stmt->execute([
|
|
$_POST['username'],
|
|
$_POST['email'],
|
|
$hashedPassword,
|
|
$_POST['role'],
|
|
$_POST['status']
|
|
])) {
|
|
$message = 'Użytkownik został utworzony';
|
|
logActivity('user_created', 'user', $db->lastInsertId());
|
|
} else {
|
|
$error = 'Błąd podczas tworzenia użytkownika';
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'update':
|
|
$stmt = $db->prepare("
|
|
UPDATE users
|
|
SET username = ?, email = ?, role = ?, status = ?
|
|
WHERE id = ?
|
|
");
|
|
|
|
if ($stmt->execute([
|
|
$_POST['username'],
|
|
$_POST['email'],
|
|
$_POST['role'],
|
|
$_POST['status'],
|
|
$_POST['id']
|
|
])) {
|
|
// Jeśli podano nowe hasło
|
|
if (!empty($_POST['password'])) {
|
|
$hashedPassword = password_hash($_POST['password'], PASSWORD_DEFAULT);
|
|
$stmt = $db->prepare("UPDATE users SET password = ? WHERE id = ?");
|
|
$stmt->execute([$hashedPassword, $_POST['id']]);
|
|
}
|
|
|
|
$message = 'Użytkownik został zaktualizowany';
|
|
logActivity('user_updated', 'user', $_POST['id']);
|
|
} else {
|
|
$error = 'Błąd podczas aktualizacji użytkownika';
|
|
}
|
|
break;
|
|
|
|
case 'delete':
|
|
// Nie pozwól usunąć własnego konta
|
|
if ($_POST['id'] == $_SESSION['user_id']) {
|
|
$error = 'Nie możesz usunąć własnego konta';
|
|
} else {
|
|
$stmt = $db->prepare("DELETE FROM users WHERE id = ?");
|
|
if ($stmt->execute([$_POST['id']])) {
|
|
$message = 'Użytkownik został usunięty';
|
|
logActivity('user_deleted', 'user', $_POST['id']);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Pobierz wszystkich użytkowników
|
|
$stmt = $db->query("
|
|
SELECT u.*,
|
|
(SELECT COUNT(*) FROM pages WHERE author_id = u.id) as page_count
|
|
FROM users u
|
|
ORDER BY u.created_at DESC
|
|
");
|
|
$users = $stmt->fetchAll();
|
|
|
|
// Tryb edycji
|
|
$editUser = null;
|
|
if (isset($_GET['edit'])) {
|
|
$stmt = $db->prepare("SELECT * FROM users WHERE id = ?");
|
|
$stmt->execute([$_GET['edit']]);
|
|
$editUser = $stmt->fetch();
|
|
}
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="pl">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Użytkownicy - Panel CMS</title>
|
|
<style>
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
|
|
body {
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
background: #f5f5f5;
|
|
}
|
|
|
|
.header {
|
|
background: #2c3e50;
|
|
color: white;
|
|
padding: 0 20px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
height: 60px;
|
|
}
|
|
|
|
.sidebar {
|
|
position: fixed;
|
|
left: 0;
|
|
top: 60px;
|
|
width: 250px;
|
|
background: white;
|
|
height: calc(100vh - 60px);
|
|
border-right: 1px solid #e0e0e0;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.sidebar nav a {
|
|
display: block;
|
|
padding: 15px 20px;
|
|
color: #333;
|
|
text-decoration: none;
|
|
border-left: 3px solid transparent;
|
|
}
|
|
|
|
.sidebar nav a:hover, .sidebar nav a.active {
|
|
background: #f0f4ff;
|
|
border-left-color: #667eea;
|
|
color: #667eea;
|
|
}
|
|
|
|
.main-content {
|
|
margin-left: 250px;
|
|
padding: 30px;
|
|
}
|
|
|
|
.btn {
|
|
display: inline-block;
|
|
padding: 10px 20px;
|
|
background: #667eea;
|
|
color: white;
|
|
text-decoration: none;
|
|
border: none;
|
|
border-radius: 5px;
|
|
cursor: pointer;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.btn:hover { background: #5568d3; }
|
|
.btn-sm { padding: 6px 12px; font-size: 13px; }
|
|
.btn-danger { background: #e74c3c; }
|
|
.btn-danger:hover { background: #c0392b; }
|
|
|
|
.card {
|
|
background: white;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.card-header {
|
|
padding: 20px;
|
|
border-bottom: 1px solid #e0e0e0;
|
|
}
|
|
|
|
.card-body { padding: 20px; }
|
|
|
|
.form-group {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.form-group label {
|
|
display: block;
|
|
margin-bottom: 8px;
|
|
font-weight: 500;
|
|
color: #333;
|
|
}
|
|
|
|
.form-group input, .form-group select {
|
|
width: 100%;
|
|
padding: 10px;
|
|
border: 2px solid #e1e8ed;
|
|
border-radius: 5px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.form-group small {
|
|
display: block;
|
|
margin-top: 5px;
|
|
color: #666;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.grid-2 {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 20px;
|
|
}
|
|
|
|
table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
}
|
|
|
|
table th, table td {
|
|
padding: 12px;
|
|
text-align: left;
|
|
border-bottom: 1px solid #e0e0e0;
|
|
}
|
|
|
|
table th {
|
|
background: #f8f9fa;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.message {
|
|
padding: 12px 20px;
|
|
background: #d4edda;
|
|
color: #155724;
|
|
border-radius: 5px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.error {
|
|
padding: 12px 20px;
|
|
background: #f8d7da;
|
|
color: #721c24;
|
|
border-radius: 5px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.badge {
|
|
display: inline-block;
|
|
padding: 4px 10px;
|
|
border-radius: 12px;
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.badge-admin { background: #667eea; color: white; }
|
|
.badge-editor { background: #3498db; color: white; }
|
|
.badge-user { background: #95a5a6; color: white; }
|
|
.badge-active { background: #27ae60; color: white; }
|
|
.badge-inactive { background: #e74c3c; color: white; }
|
|
|
|
@media (max-width: 768px) {
|
|
.grid-2 { grid-template-columns: 1fr; }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="header">
|
|
<h1>Panel CMS</h1>
|
|
<a href="index.php" class="btn btn-sm">← Powrót</a>
|
|
</div>
|
|
|
|
<div class="sidebar">
|
|
<nav>
|
|
<a href="index.php">📊 Dashboard</a>
|
|
<a href="pages.php">📄 Strony</a>
|
|
<a href="media.php">🖼️ Media</a>
|
|
<a href="menus.php">🔗 Menu</a>
|
|
<a href="categories.php">📁 Kategorie</a>
|
|
<a href="users.php" class="active">👥 Użytkownicy</a>
|
|
<a href="settings.php">⚙️ Ustawienia</a>
|
|
</nav>
|
|
</div>
|
|
|
|
<div class="main-content">
|
|
<h1 style="margin-bottom: 30px;">Zarządzanie użytkownikami</h1>
|
|
|
|
<?php if ($message): ?>
|
|
<div class="message"><?php echo escape($message); ?></div>
|
|
<?php endif; ?>
|
|
|
|
<?php if ($error): ?>
|
|
<div class="error"><?php echo escape($error); ?></div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Formularz dodawania/edycji -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h2><?php echo $editUser ? 'Edytuj użytkownika' : 'Dodaj nowego użytkownika'; ?></h2>
|
|
</div>
|
|
<div class="card-body">
|
|
<form method="POST">
|
|
<input type="hidden" name="action" value="<?php echo $editUser ? 'update' : 'create'; ?>">
|
|
<?php if ($editUser): ?>
|
|
<input type="hidden" name="id" value="<?php echo $editUser['id']; ?>">
|
|
<?php endif; ?>
|
|
|
|
<div class="grid-2">
|
|
<div class="form-group">
|
|
<label>Nazwa użytkownika *</label>
|
|
<input type="text" name="username" required
|
|
value="<?php echo escape($editUser['username'] ?? ''); ?>">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Email *</label>
|
|
<input type="email" name="email" required
|
|
value="<?php echo escape($editUser['email'] ?? ''); ?>">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid-2">
|
|
<div class="form-group">
|
|
<label>Hasło <?php echo $editUser ? '(pozostaw puste, aby nie zmieniać)' : '*'; ?></label>
|
|
<input type="password" name="password" <?php echo $editUser ? '' : 'required'; ?>>
|
|
<small>Minimum 6 znaków</small>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Rola *</label>
|
|
<select name="role" required>
|
|
<option value="user" <?php echo ($editUser['role'] ?? '') === 'user' ? 'selected' : ''; ?>>
|
|
Użytkownik
|
|
</option>
|
|
<option value="editor" <?php echo ($editUser['role'] ?? '') === 'editor' ? 'selected' : ''; ?>>
|
|
Edytor
|
|
</option>
|
|
<option value="admin" <?php echo ($editUser['role'] ?? '') === 'admin' ? 'selected' : ''; ?>>
|
|
Administrator
|
|
</option>
|
|
</select>
|
|
<small>
|
|
Użytkownik: może przeglądać<br>
|
|
Edytor: może edytować strony<br>
|
|
Administrator: pełny dostęp
|
|
</small>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Status *</label>
|
|
<select name="status" required>
|
|
<option value="active" <?php echo ($editUser['status'] ?? '') === 'active' ? 'selected' : ''; ?>>
|
|
Aktywny
|
|
</option>
|
|
<option value="inactive" <?php echo ($editUser['status'] ?? '') === 'inactive' ? 'selected' : ''; ?>>
|
|
Nieaktywny
|
|
</option>
|
|
</select>
|
|
</div>
|
|
|
|
<button type="submit" class="btn">
|
|
<?php echo $editUser ? 'Zaktualizuj użytkownika' : 'Dodaj użytkownika'; ?>
|
|
</button>
|
|
<?php if ($editUser): ?>
|
|
<a href="users.php" class="btn" style="background: #6c757d;">Anuluj</a>
|
|
<?php endif; ?>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Lista użytkowników -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h2>Wszyscy użytkownicy (<?php echo count($users); ?>)</h2>
|
|
</div>
|
|
<div class="card-body">
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Nazwa użytkownika</th>
|
|
<th>Email</th>
|
|
<th>Rola</th>
|
|
<th>Status</th>
|
|
<th>Liczba stron</th>
|
|
<th>Ostatnie logowanie</th>
|
|
<th>Data rejestracji</th>
|
|
<th>Akcje</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($users as $user): ?>
|
|
<tr>
|
|
<td>
|
|
<strong><?php echo escape($user['username']); ?></strong>
|
|
<?php if ($user['id'] == $_SESSION['user_id']): ?>
|
|
<span style="color: #667eea; font-size: 12px;">(Ty)</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td><?php echo escape($user['email']); ?></td>
|
|
<td>
|
|
<span class="badge badge-<?php echo $user['role']; ?>">
|
|
<?php
|
|
$roles = ['user' => 'Użytkownik', 'editor' => 'Edytor', 'admin' => 'Administrator'];
|
|
echo $roles[$user['role']];
|
|
?>
|
|
</span>
|
|
</td>
|
|
<td>
|
|
<span class="badge badge-<?php echo $user['status']; ?>">
|
|
<?php echo $user['status'] === 'active' ? 'Aktywny' : 'Nieaktywny'; ?>
|
|
</span>
|
|
</td>
|
|
<td>
|
|
<?php if ($user['page_count'] > 0): ?>
|
|
<span class="badge" style="background: #667eea;">
|
|
<?php echo $user['page_count']; ?>
|
|
</span>
|
|
<?php else: ?>
|
|
<span style="color: #999;">0</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td>
|
|
<?php if ($user['last_login']): ?>
|
|
<?php echo formatDate($user['last_login'], 'd.m.Y H:i'); ?>
|
|
<?php else: ?>
|
|
<span style="color: #999;">Nigdy</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td><?php echo formatDate($user['created_at'], 'd.m.Y'); ?></td>
|
|
<td>
|
|
<a href="?edit=<?php echo $user['id']; ?>" class="btn btn-sm">Edytuj</a>
|
|
<?php if ($user['id'] != $_SESSION['user_id']): ?>
|
|
<form method="POST" style="display: inline;">
|
|
<input type="hidden" name="action" value="delete">
|
|
<input type="hidden" name="id" value="<?php echo $user['id']; ?>">
|
|
<button type="submit" class="btn btn-sm btn-danger"
|
|
onclick="return confirm('Czy na pewno chcesz usunąć tego użytkownika?')">
|
|
Usuń
|
|
</button>
|
|
</form>
|
|
<?php endif; ?>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|