Implemented ManageUser Page

This commit is contained in:
Mia Rose Winter 2024-01-18 21:03:23 +01:00
parent 7fd3b5e933
commit ec90ded45a
Signed by: miawinter
GPG key ID: 4B6F6A83178F595E
4 changed files with 74 additions and 9 deletions

View file

@ -0,0 +1,25 @@
<dialog id="@Id" class="modal">
<div class="modal-box">
@ChildContent
<div class="modal-action">
@Actions
@if (ShowCloseButton) {
<form method="dialog">
<!-- if there is a button in form, it will close the modal -->
<button class="btn" type="submit">Close</button>
</form>
}
</div>
</div>
</dialog>
@code {
[Parameter]
public string Id { get; set; } = Guid.NewGuid().ToString();
[Parameter]
public required RenderFragment ChildContent { get; set; }
[Parameter]
public RenderFragment? Actions { get; set; }
[Parameter]
public bool ShowCloseButton { get; set; } = true;
}

View file

@ -7,6 +7,8 @@
@rendermode InteractiveServer @rendermode InteractiveServer
@attribute [Authorize(Policy = "RoleAssignPermissions")] @attribute [Authorize(Policy = "RoleAssignPermissions")]
@attribute [StreamRendering] @attribute [StreamRendering]
@inject RoleManager<IdentityRole> RoleManager
@inject UserManager<ApplicationUser> UserManager @inject UserManager<ApplicationUser> UserManager
@inject IStringLocalizer<ManageUsers> Localizer @inject IStringLocalizer<ManageUsers> Localizer
@ -14,6 +16,18 @@
<h1 class="text-3xl lg:text-5xl font-light mb-6">@Localizer["Title"]</h1> <h1 class="text-3xl lg:text-5xl font-light mb-6">@Localizer["Title"]</h1>
<ModalComponent Id="@ModalId">
<ChildContent>
<InputLabelComponent LabelText="@Localizer["UserName_Label"]">
<InputText class="input input-bordered w-full" type="email" autocomplete="off"
@bind-Value="@UserName" />
</InputLabelComponent>
</ChildContent>
<Actions>
<button class="btn btn-primary" @onclick="Add">@Localizer["UserName_Submit"]</button>
</Actions>
</ModalComponent>
<section class="mb-3 overflow-x-auto"> <section class="mb-3 overflow-x-auto">
<h3 class="text-xl lg:text-3xl mb-2"> <h3 class="text-xl lg:text-3xl mb-2">
@Localizer[CurrentRole.ToString().Pluralize()] @Localizer[CurrentRole.ToString().Pluralize()]
@ -26,7 +40,7 @@
<option value="@role">@Localizer[role.ToString()]</option> <option value="@role">@Localizer[role.ToString()]</option>
} }
</InputSelect> </InputSelect>
<button class="btn btn-sm btn-square btn-ghost text-success"> <button class="btn btn-sm btn-square btn-ghost text-success" onclick="@(ModalId).showModal()">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v6m3-3H9m12 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" /> <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v6m3-3H9m12 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg> </svg>
@ -47,6 +61,7 @@
[CascadingParameter(Name = "TitlePrefix")] [CascadingParameter(Name = "TitlePrefix")]
private string TitlePrefix { get; set; } = default!; private string TitlePrefix { get; set; } = default!;
public ToastComponent Toast { get; set; } = null!; public ToastComponent Toast { get; set; } = null!;
private string ModalId { get; } = "UserDialog";
[CascadingParameter] [CascadingParameter]
private Task<AuthenticationState> AuthenticationState { get; set; } = default!; private Task<AuthenticationState> AuthenticationState { get; set; } = default!;
@ -55,6 +70,8 @@
private List<ApplicationUser> Users { get; } = []; private List<ApplicationUser> Users { get; } = [];
private bool Busy { get; set; } private bool Busy { get; set; }
private string UserName { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender) { protected override async Task OnAfterRenderAsync(bool firstRender) {
if (!firstRender) return; if (!firstRender) return;
var state = await AuthenticationState; var state = await AuthenticationState;
@ -75,6 +92,27 @@
await InvokeAsync(StateHasChanged); await InvokeAsync(StateHasChanged);
} }
private async Task Add() {
var user = await UserManager.FindByNameAsync(UserName);
if (user is null) {
Toast.ShowError(Localizer["Error_UserNotFound"]);
return;
}
if (!await RoleManager.RoleExistsAsync(CurrentRole.ToString())) {
var result = await RoleManager.CreateAsync(new IdentityRole(CurrentRole.ToString()));
if (result.Succeeded is not true) {
Toast.ShowError(Localizer["Error_CreateRole"]);
return;
}
}
await UserManager.AddToRoleAsync(user, CurrentRole.ToString());
await LoadAsync(CurrentRole);
Toast.ShowSuccess(Localizer["Success_AddUser"]);
}
private async Task RemoveAsync(ApplicationUser user, Role role) { private async Task RemoveAsync(ApplicationUser user, Role role) {
if (User is null) return; if (User is null) return;
if (user.Id == User.Id) { if (user.Id == User.Id) {
@ -82,6 +120,8 @@
return; return;
} }
await UserManager.RemoveFromRoleAsync(user, role.ToString()); await UserManager.RemoveFromRoleAsync(user, role.ToString());
Toast.ShowSuccess(Localizer["Success_RemoveUser"]);
await LoadAsync(CurrentRole);
} }
private enum Role { private enum Role {

View file

@ -1,24 +1,24 @@
@using Wave.Data @using Wave.Data
<table class="table table-fixed"> <table class="table">
<thead> <thead>
<tr> <tr>
<th></th> <th class="max-md:hidden"> </th>
<th>Name</th> <th>Name</th>
<th>Email</th> <th class="max-md:hidden">Email</th>
<th> </th> <th> </th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@foreach (var user in Users) { @foreach (var user in Users) {
<tr> <tr>
<td> <td class="max-md:hidden">
<div class="w-6 h-6"> <div class="w-6 h-6">
<ProfilePictureComponent ProfileId="@user.Id" /> <ProfilePictureComponent ProfileId="@user.Id" />
</div> </div>
</td> </td>
<td>@user.Name</td> <td>@user.Name</td>
<td>@user.Email</td> <td class="max-md:hidden">@user.Email</td>
<td> <td>
<button class="btn btn-sm btn-error" title="remove" @onclick="async () => await RemoveClicked(user)"> <button class="btn btn-sm btn-error" title="remove" @onclick="async () => await RemoveClicked(user)">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">

File diff suppressed because one or more lines are too long