Ryanhub - file viewer
filename: views/admin/users.php
branch: main
back to repo
<?php
if (!isAdmin()) {
    http_response_code(403);
    require __DIR__ . '/../public/403.php';
    return;
}

$pageTitle = "Admin Members";

if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
    $userId = (int)($_POST['user_id'] ?? 0);
    $action = $_POST['action'] ?? '';
    if ($userId > 0) {
        if ($action === 'set_status') {
            $status = $_POST['status'] ?? 'active';
            $stmt = $db->prepare('UPDATE users SET status = ? WHERE id = ?');
            $stmt->bind_param('si', $status, $userId);
            $stmt->execute();
        } elseif ($action === 'toggle_admin') {
            $stmt = $db->prepare('UPDATE users SET is_admin = 1 - is_admin WHERE id = ?');
            $stmt->bind_param('i', $userId);
            $stmt->execute();
        }
    }
}

$res = $db->query('SELECT id, email, full_name, is_admin, status, created_at, last_login_at FROM users ORDER BY created_at DESC');
$users = $res->fetch_all(MYSQLI_ASSOC);
?>

<section class="page-grid">
    <div class="card" data-animate-initial>
        <div class="muted" style="font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; margin-bottom: 10px;">
            Admin / Members
        </div>
        <a href="<?= url('admin') ?>" class="pill" style="display: inline-flex; align-items: center; gap: 6px; font-size: 11px; margin-bottom: 10px;">
            ← Back to admin
        </a>
        <h1 style="font-family: 'Georgia', 'Times New Roman', serif; font-weight: 400; font-size: 24px; margin: 0 0 12px;">
            Members and access.
        </h1>
    </div>

    <div class="card" data-animate>
        <?php if (!$users): ?>
            <p class="muted" style="font-size: 13px;">No members yet.</p>
        <?php else: ?>
            <div class="admin-users-table" style="overflow-x: auto;">
                <table style="width: 100%; border-collapse: collapse; font-size: 13px; min-width: 640px;">
                    <thead>
                    <tr class="muted">
                        <th style="text-align: left; padding: 8px 6px;">Name</th>
                        <th style="text-align: left; padding: 8px 6px;">Email</th>
                        <th style="text-align: left; padding: 8px 6px;">Status</th>
                        <th style="text-align: left; padding: 8px 6px;">Admin</th>
                        <th style="text-align: left; padding: 8px 6px;">Joined</th>
                        <th style="text-align: left; padding: 8px 6px;">Last Login</th>
                        <th style="text-align: left; padding: 8px 6px;">Actions</th>
                    </tr>
                    </thead>
                    <tbody>
                    <?php foreach ($users as $user): ?>
                        <tr style="border-top: 1px solid rgba(0,0,0,0.04);">
                            <td style="padding: 8px 6px; white-space: nowrap;"><?= htmlspecialchars($user['full_name'], ENT_QUOTES, 'UTF-8') ?></td>
                            <td style="padding: 8px 6px; word-break: break-all;"><?= htmlspecialchars($user['email'], ENT_QUOTES, 'UTF-8') ?></td>
                            <td style="padding: 8px 6px;"><?= htmlspecialchars($user['status'], ENT_QUOTES, 'UTF-8') ?></td>
                            <td style="padding: 8px 6px;"><?= $user['is_admin'] ? 'Yes' : 'No' ?></td>
                            <td style="padding: 8px 6px; white-space: nowrap;"><?= htmlspecialchars($user['created_at'], ENT_QUOTES, 'UTF-8') ?></td>
                            <td style="padding: 8px 6px; white-space: nowrap;"><?= htmlspecialchars($user['last_login_at'] ?? '—', ENT_QUOTES, 'UTF-8') ?></td>
                            <td style="padding: 8px 6px;">
                                <div style="display: flex; flex-wrap: wrap; gap: 4px;">
                                    <form method="post" style="display:inline-flex; gap: 4px; align-items: center; margin: 0;">
                                        <input type="hidden" name="user_id" value="<?= (int)$user['id'] ?>">
                                        <input type="hidden" name="action" value="set_status">
                                        <select name="status" style="font-size: 12px; padding: 2px 4px; border-radius: 6px; border: 1px solid rgba(0,0,0,0.12);">
                                            <option value="pending"<?= $user['status'] === 'pending' ? ' selected' : '' ?>>Pending</option>
                                            <option value="active"<?= $user['status'] === 'active' ? ' selected' : '' ?>>Active</option>
                                            <option value="suspended"<?= $user['status'] === 'suspended' ? ' selected' : '' ?>>Suspended</option>
                                        </select>
                                        <button type="submit" class="pill" style="font-size: 10px; padding: 4px 8px;">Save</button>
                                    </form>
                                    <form method="post" style="display:inline-flex; margin: 0;">
                                        <input type="hidden" name="user_id" value="<?= (int)$user['id'] ?>">
                                        <input type="hidden" name="action" value="toggle_admin">
                                        <button type="submit" class="pill" style="font-size: 10px; padding: 4px 8px;">
                                            <?= $user['is_admin'] ? 'Revoke admin' : 'Make admin' ?>
                                        </button>
                                    </form>
                                </div>
                            </td>
                        </tr>
                    <?php endforeach; ?>
                    </tbody>
                </table>
            </div>
        <?php endif; ?>
    </div>
</section>