diff --git a/Components/Pages/Admin/UserManagement.razor b/Components/Pages/Admin/UserManagement.razor index c95360e..bed3d93 100644 --- a/Components/Pages/Admin/UserManagement.razor +++ b/Components/Pages/Admin/UserManagement.razor @@ -86,11 +86,12 @@ else @@ -192,16 +193,26 @@ else } } - // Bound via @bind:after, so user.Role already holds the newly-selected value when this runs. - private async Task PersistRoleAsync(AppUser user) + private async Task OnRoleChange(AppUser user, ChangeEventArgs e) { + // Surface every branch on-screen so a failed save is never silent. The "saved" value is + // re-read from the store, so it proves whether the write actually landed on disk. + var raw = e.Value?.ToString(); + if (!Enum.TryParse(raw, out var newRole)) + { + _message = string.Format(T["usermgmt.msg.error"], $"unrecognized role value '{raw}'"); + _isError = true; + return; + } try { - var oldRole = await UserService.UpdateRoleAsync(user.Id, user.Role); + var oldRole = await UserService.UpdateRoleAsync(user.Id, newRole); + user.Role = newRole; + var saved = (await UserService.GetByEmailAsync(user.Email))?.Role; await Audit.LogAsync("RoleChanged", "", Array.Empty(), - $"Changed role for {user.Email} ({user.DisplayName}) from {oldRole} to {user.Role}."); - _message = string.Format(T["usermgmt.msg.roleupdated"], user.DisplayName); - _isError = false; + $"Changed role for {user.Email} ({user.DisplayName}) from {oldRole} to {newRole}."); + _message = $"{string.Format(T["usermgmt.msg.roleupdated"], user.DisplayName)} ({oldRole} → {newRole}, saved: {saved})"; + _isError = saved != newRole; } catch (Exception ex) {