Add menu enable toggle, user status, and mobile/UI polish
- Admin menu page: mobile item cards now put Actions in the top-right
corner next to Status, matching the desktop row layout instead of
stacking at the bottom; same treatment applied to announcements and
users for consistency across all three admin lists
- Center button label text everywhere via .btn { justify-content: center }
instead of one-off overrides
- Add a Disable/Enable Menu toggle to the admin menu toolbar; the public
menu page shows its existing "menu being updated" message while disabled
- Add an Enabled/Disabled status to user accounts, with its own toggle
badge, guardrails against disabling your own account or the last
enabled account, and an immediate session kick for anyone disabled
mid-session
- Fix the announcement banner / hero tagline "·" separators to hide only
when their neighboring text actually wraps onto a different line,
instead of a fixed breakpoint or always-on dot
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
eab20899de
commit
cd4c6c1969
13 files changed
+405
-50
No files matched your search
+53
-10
@@ -93,6 +93,32 @@ function handle_change_password(array $post, array $currentUser): array {
|
||||
return ['success' => true];
|
||||
}
|
||||
|
||||
function handle_toggle_user_enabled(array $post, array $currentUser): array {
|
||||
$targetId = (int) ($post['user_id'] ?? 0);
|
||||
$target = $targetId > 0 ? get_user_by_id($targetId) : null;
|
||||
if (!$target) {
|
||||
return ['success' => false, 'error' => 'User not found.'];
|
||||
}
|
||||
if ($targetId === (int) $currentUser['id']) {
|
||||
return ['success' => false, 'error' => "You can't disable your own account while logged in as it."];
|
||||
}
|
||||
|
||||
$currentlyEnabled = (int) $target['is_enabled'] === 1;
|
||||
if ($currentlyEnabled && count_enabled_users() <= 1) {
|
||||
return ['success' => false, 'error' => 'At least one user account must remain enabled.'];
|
||||
}
|
||||
|
||||
toggle_user_enabled($targetId);
|
||||
$isEnabled = (int) get_user_by_id($targetId)['is_enabled'] === 1;
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'is_enabled' => $isEnabled,
|
||||
'status_badge' => $isEnabled ? '● Enabled' : '○ Disabled',
|
||||
'status_class' => $isEnabled ? 'active' : 'inactive',
|
||||
];
|
||||
}
|
||||
|
||||
function handle_delete_user(array $post, array $currentUser): array {
|
||||
$targetId = (int) ($post['user_id'] ?? 0);
|
||||
if ($targetId <= 0 || !get_user_by_id($targetId)) {
|
||||
@@ -113,6 +139,7 @@ function handle_users_action(string $action, array $post, array $currentUser): a
|
||||
return match ($action) {
|
||||
'create_user' => handle_create_user($post, $currentUser),
|
||||
'change_password' => handle_change_password($post, $currentUser),
|
||||
'toggle_user_enabled' => handle_toggle_user_enabled($post, $currentUser),
|
||||
'delete_user' => handle_delete_user($post, $currentUser),
|
||||
default => ['success' => false, 'error' => 'Unknown action'],
|
||||
};
|
||||
@@ -191,6 +218,7 @@ $users = get_all_users();
|
||||
|
||||
<div class="user-grid-wrap">
|
||||
<div class="user-grid-head" aria-hidden="true">
|
||||
<span class="col-status">Status</span>
|
||||
<span class="col-username">Username</span>
|
||||
<span class="col-role">Role</span>
|
||||
<span class="col-created">Created</span>
|
||||
@@ -198,10 +226,23 @@ $users = get_all_users();
|
||||
</div>
|
||||
<div class="user-rows" id="users-rows">
|
||||
<?php foreach ($users as $row): ?>
|
||||
<?php $isSelf = (int) $row['id'] === (int) $user['id']; ?>
|
||||
<?php $isEnabled = (int) $row['is_enabled'] === 1; ?>
|
||||
<div class="user-row" id="user-row-<?= (int) $row['id'] ?>" data-user-id="<?= (int) $row['id'] ?>">
|
||||
<div data-label="Status">
|
||||
<?php if ($isSelf): ?>
|
||||
<span class="status-badge <?= $isEnabled ? 'active' : 'inactive' ?>" title="You can't disable your own account.">
|
||||
<?= $isEnabled ? '● Enabled' : '○ Disabled' ?>
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<button type="button" class="status-badge btn-toggle-user <?= $isEnabled ? 'active' : 'inactive' ?>" data-id="<?= (int) $row['id'] ?>" title="Click to mark as <?= $isEnabled ? 'disabled' : 'enabled' ?>">
|
||||
<?= $isEnabled ? '● Enabled' : '○ Disabled' ?>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div data-label="Username">
|
||||
<strong><?= htmlspecialchars($row['username']) ?></strong>
|
||||
<?php if ((int) $row['id'] === (int) $user['id']): ?>
|
||||
<?php if ($isSelf): ?>
|
||||
<span class="muted"> (you)</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@@ -209,16 +250,18 @@ $users = get_all_users();
|
||||
<div class="font-mono timestamp-cell" data-label="Created"><?= htmlspecialchars($row['created_at']) ?></div>
|
||||
<div data-label="Actions">
|
||||
<div class="row-actions">
|
||||
<button type="button" class="btn btn-outline btn-sm btn-change-password"
|
||||
data-id="<?= (int) $row['id'] ?>"
|
||||
data-username="<?= htmlspecialchars($row['username']) ?>">
|
||||
Change Password
|
||||
</button>
|
||||
<?php if ((int) $row['id'] !== (int) $user['id']): ?>
|
||||
<button type="button" class="btn btn-danger btn-sm btn-delete-user" data-id="<?= (int) $row['id'] ?>">
|
||||
Delete
|
||||
<div class="action-stack">
|
||||
<button type="button" class="btn btn-outline btn-sm btn-change-password"
|
||||
data-id="<?= (int) $row['id'] ?>"
|
||||
data-username="<?= htmlspecialchars($row['username']) ?>">
|
||||
Change Password
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<?php if (!$isSelf): ?>
|
||||
<button type="button" class="btn btn-danger btn-sm btn-delete-user" data-id="<?= (int) $row['id'] ?>">
|
||||
Delete
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user