Show sourcecode
The following files exists in this folder. Click to view.
public_html/smartkortet/admin/
index.php
login.php
logout.php
statistik.php
index.php
194 lines UTF-8 Windows (CRLF)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
<?php
declare(strict_types=1);
require_once __DIR__ . '/../includes/functions.php';
startAppSession();
require_once __DIR__ . '/../includes/auth.php';
require_once __DIR__ . '/../config/database.php';
$admin = requireAdminAuth();
$adminId = (int) $admin['id'];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
verifyCsrf();
$action = $_POST['action'] ?? '';
if ($action === 'toggle_admin') {
$targetId = (int) ($_POST['target_id'] ?? 0);
if ($targetId === $adminId) {
setFlash('error', 'Du kan inte ändra din egen adminroll här.');
redirect('/admin/index.php');
}
$stmt = db()->prepare('UPDATE users SET is_admin = CASE WHEN is_admin = 1 THEN 0 ELSE 1 END WHERE id = :id');
$stmt->execute(['id' => $targetId]);
setFlash('success', 'Adminroll uppdaterad.');
redirect('/admin/index.php');
}
if ($action === 'reset_password') {
$targetId = (int) ($_POST['target_id'] ?? 0);
$newPassword = $_POST['new_password'] ?? '';
if (mb_strlen($newPassword) < 8) {
setFlash('error', 'Nytt lösenord måste vara minst 8 tecken.');
redirect('/admin/index.php');
}
$stmt = db()->prepare('UPDATE users SET password_hash = :password_hash WHERE id = :id');
$stmt->execute([
'password_hash' => password_hash($newPassword, PASSWORD_DEFAULT),
'id' => $targetId,
]);
setFlash('success', 'Lösenord uppdaterat.');
redirect('/admin/index.php');
}
if ($action === 'delete_user') {
$targetId = (int) ($_POST['target_id'] ?? 0);
if ($targetId === $adminId) {
setFlash('error', 'Du kan inte radera ditt eget konto.');
redirect('/admin/index.php');
}
$stmt = db()->prepare('DELETE FROM users WHERE id = :id');
$stmt->execute(['id' => $targetId]);
setFlash('success', 'Användare raderad.');
redirect('/admin/index.php');
}
}
$flash = getFlash();
$kpi = [
'users' => 0,
'admins' => 0,
'spend_entries' => 0,
'month_spent' => 0.0,
];
$kpi['users'] = (int) db()->query('SELECT COUNT(*) FROM users')->fetchColumn();
$kpi['admins'] = (int) db()->query('SELECT COUNT(*) FROM users WHERE is_admin = 1')->fetchColumn();
$kpi['spend_entries'] = (int) db()->query('SELECT COUNT(*) FROM spend_entries')->fetchColumn();
$kpi['month_spent'] = (float) db()->query('SELECT COALESCE(SUM(amount), 0) FROM spend_entries WHERE spent_on BETWEEN DATE_FORMAT(CURDATE(), "%Y-%m-01") AND LAST_DAY(CURDATE())')->fetchColumn();
$users = db()->query('SELECT id, name, email, is_admin, created_at FROM users ORDER BY created_at DESC')->fetchAll();
?>
<!doctype html>
<html lang="sv">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="theme-color" content="#0b1220">
<title>Admin Dashboard | Matkortet</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="<?= e(url('assets/css/style.css')) ?>">
</head>
<body data-theme="dark">
<main class="app-shell">
<header class="card panel topbar">
<div>
<h1>Admin Dashboard</h1>
<p class="subtitle">Inloggad som <?= e($admin['name']) ?> (<?= e($admin['email']) ?>)</p>
</div>
<div class="admin-actions">
<a class="btn btn-secondary" href="<?= e(url('index.php')) ?>">Till appen</a>
<a class="btn btn-secondary" href="<?= e(url('database/createdb.php')) ?>">DB Console</a>
<a class="btn btn-danger" href="<?= e(url('admin/logout.php')) ?>">Logga ut admin</a>
</div>
</header>
<nav class="card panel admin-subnav">
<a class="tab-link active" href="<?= e(url('admin/index.php')) ?>">Dashboard</a>
<a class="tab-link" href="<?= e(url('admin/statistik.php')) ?>">Statistik</a>
</nav>
<?php if ($flash): ?>
<div class="notice <?= e($flash['type']) ?>"><?= e($flash['message']) ?></div>
<?php endif; ?>
<section class="kpi-grid">
<article class="card kpi">
<span>Användare</span>
<strong><?= e((string) $kpi['users']) ?></strong>
</article>
<article class="card kpi">
<span>Admins</span>
<strong><?= e((string) $kpi['admins']) ?></strong>
</article>
<article class="card kpi">
<span>Transaktioner</span>
<strong><?= e((string) $kpi['spend_entries']) ?></strong>
</article>
<article class="card kpi">
<span>Spend denna månad</span>
<strong><?= e(formatCurrency($kpi['month_spent'])) ?></strong>
</article>
</section>
<section class="card panel" style="margin-top:16px;">
<h3>Användarhantering</h3>
<div class="admin-table-wrap">
<table class="admin-table">
<thead>
<tr>
<th>ID</th>
<th>Namn</th>
<th>E-post</th>
<th>Roll</th>
<th>Skapad</th>
<th>Åtgärder</th>
</tr>
</thead>
<tbody>
<?php foreach ($users as $u): ?>
<tr>
<td data-label="ID"><?= e((string) $u['id']) ?></td>
<td data-label="Namn"><?= e($u['name']) ?></td>
<td data-label="E-post"><?= e($u['email']) ?></td>
<td data-label="Roll"><?= ((int) $u['is_admin'] === 1) ? 'Admin' : 'User' ?></td>
<td data-label="Skapad"><?= e((string) $u['created_at']) ?></td>
<td data-label="Åtgärder">
<div class="admin-row-actions">
<form method="post" class="inline-admin-form">
<input type="hidden" name="csrf_token" value="<?= e(csrfToken()) ?>">
<input type="hidden" name="action" value="toggle_admin">
<input type="hidden" name="target_id" value="<?= e((string) $u['id']) ?>">
<button class="btn btn-secondary" type="submit">Toggle Admin</button>
</form>
<form method="post" class="inline-admin-form">
<input type="hidden" name="csrf_token" value="<?= e(csrfToken()) ?>">
<input type="hidden" name="action" value="reset_password">
<input type="hidden" name="target_id" value="<?= e((string) $u['id']) ?>">
<input type="password" name="new_password" placeholder="Nytt lösenord" minlength="8" required>
<button class="btn" type="submit">Reset</button>
</form>
<form method="post" class="inline-admin-form" onsubmit="return confirm('Radera användaren?');">
<input type="hidden" name="csrf_token" value="<?= e(csrfToken()) ?>">
<input type="hidden" name="action" value="delete_user">
<input type="hidden" name="target_id" value="<?= e((string) $u['id']) ?>">
<button class="btn btn-danger" type="submit">Radera</button>
</form>
</div>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</section>
</main>
</body>
</html>