From 4f143bb2893a154cf009347dc0521ce4cd43512f Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Sun, 22 Mar 2026 04:04:46 +0100 Subject: [PATCH] fix: add missing Instance sub-panel titles and overhaul reset password UX - Add

title headings to General, Streaming, Storage, Users panels - Reset password now shows confirmation dialog before executing - Temp password displays inline below the user row (not at top of list) - Temp password has copy button and dismiss action --- .../instanceSettingsPanels/GeneralPanel.tsx | 1 + .../instanceSettingsPanels/StoragePanel.tsx | 1 + .../instanceSettingsPanels/StreamingPanel.tsx | 1 + .../instanceSettingsPanels/UsersPanel.tsx | 272 ++++++++++-------- 4 files changed, 152 insertions(+), 123 deletions(-) diff --git a/packages/web/src/components/modals/instanceSettingsPanels/GeneralPanel.tsx b/packages/web/src/components/modals/instanceSettingsPanels/GeneralPanel.tsx index db61258a..d8d56aa2 100644 --- a/packages/web/src/components/modals/instanceSettingsPanels/GeneralPanel.tsx +++ b/packages/web/src/components/modals/instanceSettingsPanels/GeneralPanel.tsx @@ -65,6 +65,7 @@ export function GeneralPanel() { return (
e.preventDefault()}> +

General

Configure your Backspace instance. These settings affect all users.
diff --git a/packages/web/src/components/modals/instanceSettingsPanels/StoragePanel.tsx b/packages/web/src/components/modals/instanceSettingsPanels/StoragePanel.tsx index 608beefb..9393646e 100644 --- a/packages/web/src/components/modals/instanceSettingsPanels/StoragePanel.tsx +++ b/packages/web/src/components/modals/instanceSettingsPanels/StoragePanel.tsx @@ -74,6 +74,7 @@ export function StoragePanel() { return (
+

Storage

Monitor disk usage and clean up orphaned files left behind by deleted content or replaced avatars/banners.
diff --git a/packages/web/src/components/modals/instanceSettingsPanels/StreamingPanel.tsx b/packages/web/src/components/modals/instanceSettingsPanels/StreamingPanel.tsx index fc44323c..3471336d 100644 --- a/packages/web/src/components/modals/instanceSettingsPanels/StreamingPanel.tsx +++ b/packages/web/src/components/modals/instanceSettingsPanels/StreamingPanel.tsx @@ -162,6 +162,7 @@ export function StreamingPanel() { return (
+

Streaming

These limits apply to all users on this instance. Users can pick values within these bounds.
diff --git a/packages/web/src/components/modals/instanceSettingsPanels/UsersPanel.tsx b/packages/web/src/components/modals/instanceSettingsPanels/UsersPanel.tsx index b3238eb8..18c1f495 100644 --- a/packages/web/src/components/modals/instanceSettingsPanels/UsersPanel.tsx +++ b/packages/web/src/components/modals/instanceSettingsPanels/UsersPanel.tsx @@ -67,14 +67,27 @@ export function UsersPanel() { } }; - const handleResetPassword = async (user: AdminUser) => { + const [resetConfirmUser, setResetConfirmUser] = useState(null); + const [resetLoading, setResetLoading] = useState(false); + + const handleResetPassword = (user: AdminUser) => { + setResetConfirmUser(user); + }; + + const handleResetConfirm = async () => { + if (!resetConfirmUser) return; + setResetLoading(true); setError(''); setTempPassword(null); try { - const result = await api.admin.resetUserPassword(user.id); - setTempPassword({ userId: user.id, password: result.temporaryPassword }); + const result = await api.admin.resetUserPassword(resetConfirmUser.id); + setTempPassword({ userId: resetConfirmUser.id, password: result.temporaryPassword }); + setResetConfirmUser(null); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to reset password'); + setResetConfirmUser(null); + } finally { + setResetLoading(false); } }; @@ -111,6 +124,7 @@ export function UsersPanel() { return (
+

Users

View and manage user accounts on this instance.
@@ -140,37 +154,6 @@ export function UsersPanel() {
{error}
)} - {/* Temp password banner */} - {tempPassword && ( -
-
-
- Temporary password for {data?.users.find(u => u.id === tempPassword.userId)?.username ?? 'user'}: -
- -
-
- - {tempPassword.password} - - -
-
- This password is shown once. The user has been disconnected and must log in again. -
-
- )} - {/* Loading */} {loading && !data && (
Loading users...
@@ -187,102 +170,135 @@ export function UsersPanel() { const isFederated = !!user.homeInstance; const isDeleted = user.isDeleted; + const hasTempPassword = tempPassword?.userId === user.id; + return ( -
- {/* Avatar */} -
- -
- - {/* Info */} -
-
- - {user.username} - - {user.displayName && !isDeleted && ( - {user.displayName} - )} +
+
+ {/* Avatar */} +
+
-
- {user.isAdmin && ( - - Admin - - )} - {isFederated && ( - - {user.homeInstance} - - )} - {isDeleted && ( - - Deleted - - )} - - {formatDate(user.createdAt)} - -
-
- {/* Actions */} - {!isDeleted && ( -
- {/* Toggle admin */} - + + {/* Reset password */} + + }`} + > + + + + - {/* Reset password */} - + {/* Delete user */} + +
+ )} +
- {/* Delete user */} - + {/* Inline temp password display */} + {hasTempPassword && ( +
+
+
Temporary password:
+ +
+
+ + {tempPassword.password} + + +
+
+ Shown once. User has been disconnected and must log in again. +
)}
@@ -315,6 +331,16 @@ export function UsersPanel() { )} {/* Confirm dialogs */} + setResetConfirmUser(null)} + onConfirm={handleResetConfirm} + title="Reset Password" + description={<>Reset the password for {resetConfirmUser?.username}? They will be disconnected immediately and must log in with the new temporary password.} + confirmLabel="Reset Password" + variant="warning" + loading={resetLoading} + /> setConfirmAction(null)}