Implemented ManageUser Page
This commit is contained in:
parent
7fd3b5e933
commit
ec90ded45a
25
Wave/Components/ModalComponent.razor
Normal file
25
Wave/Components/ModalComponent.razor
Normal 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;
|
||||||
|
}
|
|
@ -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 {
|
||||||
|
|
|
@ -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">
|
||||||
|
|
2
Wave/wwwroot/css/main.min.css
vendored
2
Wave/wwwroot/css/main.min.css
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue