Add admin delete-account flow with yes/no confirmation

This commit is contained in:
Jage9
2026-02-28 20:06:43 -05:00
parent b0fa040d33
commit 906c320e51
12 changed files with 239 additions and 6 deletions

View File

@@ -210,7 +210,8 @@ type AdminUserSummary = {
type AdminPendingUserMutation =
| { action: 'set_role'; username: string; role: string }
| { action: 'ban'; username: string }
| { action: 'unban'; username: string };
| { action: 'unban'; username: string }
| { action: 'delete_account'; username: string };
type ItemManagementAction = 'delete' | 'transfer';
@@ -332,10 +333,11 @@ let adminRolePermissionIndex = 0;
let adminRoleDeleteReplacementIndex = 0;
let adminUsers: AdminUserSummary[] = [];
let adminUserIndex = 0;
let adminPendingUserAction: 'set_role' | 'ban' | 'unban' | null = null;
let adminPendingUserAction: 'set_role' | 'ban' | 'unban' | 'delete_account' | null = null;
let adminSelectedRoleName = '';
let adminSelectedUsername = '';
let adminPendingUserMutation: AdminPendingUserMutation | null = null;
let adminDeleteConfirmIndex = 0;
let itemManagementSelectedItemId: string | null = null;
let itemManagementOptions: ItemManagementOption[] = [];
let itemManagementOptionIndex = 0;
@@ -1830,6 +1832,16 @@ function handleAdminActionResult(message: Extract<IncomingMessage, { type: 'admi
adminPendingUserAction = null;
}
}
} else if (adminPendingUserMutation.action === 'delete_account') {
adminUsers = adminUsers.filter((entry) => entry.username !== adminPendingUserMutation.username);
if (state.mode === 'adminUserList' && adminPendingUserAction === 'delete_account') {
if (adminUsers.length > 0) {
adminUserIndex = Math.max(0, Math.min(adminUserIndex, adminUsers.length - 1));
} else {
state.mode = 'adminMenu';
adminPendingUserAction = null;
}
}
}
adminPendingUserMutation = null;
}
@@ -3029,6 +3041,12 @@ function handleAdminMenuModeInput(code: string, key: string): void {
adminPendingUserAction = 'unban';
signaling.send({ type: 'admin_users_list', action: 'unban' });
updateStatus('Loading users...');
return;
}
if (selected.id === 'delete_account') {
adminPendingUserAction = 'delete_account';
signaling.send({ type: 'admin_users_list', action: 'delete_account' });
updateStatus('Loading users...');
}
return;
}
@@ -3217,6 +3235,13 @@ function handleAdminUserListModeInput(code: string, key: string): void {
adminPendingUserAction = 'unban';
return;
}
if (adminPendingUserAction === 'delete_account') {
adminDeleteConfirmIndex = 0;
state.mode = 'adminUserDeleteConfirm';
updateStatus(`Delete account ${selected.username}? ${YES_NO_OPTIONS[adminDeleteConfirmIndex].label}.`);
audio.sfxUiBlip();
return;
}
return;
}
if (control.type === 'cancel') {
@@ -3254,6 +3279,48 @@ function handleAdminUserRoleSelectModeInput(code: string, key: string): void {
}
}
/** Handles yes/no confirmation for delete-account admin flow. */
function handleAdminUserDeleteConfirmModeInput(code: string, key: string): void {
if (!adminSelectedUsername || adminPendingUserAction !== 'delete_account') {
state.mode = 'adminUserList';
return;
}
const control = handleYesNoMenuInput(code, key, adminDeleteConfirmIndex);
if (control.type === 'move') {
adminDeleteConfirmIndex = control.index;
updateStatus(`Delete account ${adminSelectedUsername}? ${YES_NO_OPTIONS[adminDeleteConfirmIndex].label}.`);
audio.sfxUiBlip();
return;
}
if (control.type === 'cancel') {
state.mode = 'adminUserList';
const selected = adminUsers[adminUserIndex];
if (selected) {
updateStatus(`${selected.username}, ${selected.role}, ${selected.status}.`);
} else {
updateStatus('Select user.');
}
audio.sfxUiCancel();
return;
}
if (control.type === 'select') {
const choice = YES_NO_OPTIONS[adminDeleteConfirmIndex];
if (choice.id === 'no') {
state.mode = 'adminUserList';
const selected = adminUsers[adminUserIndex];
if (selected) {
updateStatus(`${selected.username}, ${selected.role}, ${selected.status}.`);
} else {
updateStatus('Select user.');
}
audio.sfxUiCancel();
return;
}
adminPendingUserMutation = { action: 'delete_account', username: adminSelectedUsername };
signaling.send({ type: 'admin_user_delete', username: adminSelectedUsername });
}
}
/** Handles text edit for new-role creation from admin role list. */
function handleAdminRoleNameEditModeInput(code: string, key: string, ctrlKey: boolean): void {
const editAction = getEditSessionAction(code);
@@ -3475,6 +3542,7 @@ function setupInputHandlers(): void {
adminRoleDeleteReplacement: (currentCode, currentKey) => handleAdminRoleDeleteReplacementModeInput(currentCode, currentKey),
adminUserList: (currentCode, currentKey) => handleAdminUserListModeInput(currentCode, currentKey),
adminUserRoleSelect: (currentCode, currentKey) => handleAdminUserRoleSelectModeInput(currentCode, currentKey),
adminUserDeleteConfirm: (currentCode, currentKey) => handleAdminUserDeleteConfirmModeInput(currentCode, currentKey),
adminRoleNameEdit: (currentCode, currentKey, currentCtrlKey) =>
handleAdminRoleNameEditModeInput(currentCode, currentKey, currentCtrlKey),
itemProperties: (currentCode, currentKey) => itemPropertyEditor.handleItemPropertiesModeInput(currentCode, currentKey),