edit users in club-settings
This commit is contained in:
parent
f9e72d095b
commit
51b8c2dbd4
|
|
@ -613,6 +613,9 @@ public class UserService : IUserService
|
||||||
|
|
||||||
await _appDb.SaveChangesAsync(ct);
|
await _appDb.SaveChangesAsync(ct);
|
||||||
|
|
||||||
|
// Assign default Viewer role to new member
|
||||||
|
await AssignClubRoleAsync(userProfileId, clubId, "Viewer", approvedById, ct);
|
||||||
|
|
||||||
// Send notification to user
|
// Send notification to user
|
||||||
var identityUser = await _userManager.FindByIdAsync(membership.UserProfile.IdentityUserId.ToString());
|
var identityUser = await _userManager.FindByIdAsync(membership.UserProfile.IdentityUserId.ToString());
|
||||||
if (identityUser?.Email != null)
|
if (identityUser?.Email != null)
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,14 @@
|
||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
private HttpContext HttpContext { get; set; } = default!;
|
private HttpContext HttpContext { get; set; } = default!;
|
||||||
|
|
||||||
private IComponentRenderMode? RenderModeForPage => HttpContext.Request.Path.StartsWithSegments("/Account")
|
private IComponentRenderMode? RenderModeForPage
|
||||||
? new InteractiveServerRenderMode(prerender: false)
|
{
|
||||||
: new InteractiveServerRenderMode(prerender: true);
|
get
|
||||||
|
{
|
||||||
|
var path = HttpContext.Request.Path;
|
||||||
|
var disablePrerender = path.StartsWithSegments("/Account")
|
||||||
|
|| path.StartsWithSegments("/settings");
|
||||||
|
return new InteractiveServerRenderMode(prerender: !disablePrerender);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,132 @@
|
||||||
|
@using Koogle.Application.DTOs
|
||||||
|
@using Koogle.Application.Interfaces
|
||||||
|
@using Koogle.Domain.Enums
|
||||||
|
|
||||||
|
@inject IUserService UserService
|
||||||
|
@inject ISnackbar Snackbar
|
||||||
|
|
||||||
|
<MudDialog>
|
||||||
|
<DialogContent>
|
||||||
|
<MudText Typo="Typo.subtitle1" Class="mb-3">Rollen fuer @User.DisplayName</MudText>
|
||||||
|
|
||||||
|
<MudPaper Class="pa-3" Elevation="1">
|
||||||
|
<MudStack Row="true" Spacing="2" Wrap="Wrap.Wrap">
|
||||||
|
@foreach (var role in _availableRoles)
|
||||||
|
{
|
||||||
|
var hasRole = _currentRoles.Contains(role);
|
||||||
|
<MudChip T="string"
|
||||||
|
Color="@(hasRole ? Color.Primary : Color.Default)"
|
||||||
|
Variant="@(hasRole ? Variant.Filled : Variant.Outlined)"
|
||||||
|
OnClick="@(() => ToggleRole(role, hasRole))"
|
||||||
|
Disabled="_isProcessing">
|
||||||
|
@GetRoleDisplayName(role)
|
||||||
|
</MudChip>
|
||||||
|
}
|
||||||
|
</MudStack>
|
||||||
|
</MudPaper>
|
||||||
|
|
||||||
|
<MudDivider Class="my-4" />
|
||||||
|
|
||||||
|
<MudButton Size="Size.Small"
|
||||||
|
Color="Color.Error"
|
||||||
|
Variant="Variant.Text"
|
||||||
|
StartIcon="@Icons.Material.Filled.RemoveCircle"
|
||||||
|
OnClick="RemoveFromClub"
|
||||||
|
Disabled="_isProcessing">
|
||||||
|
Aus Verein entfernen
|
||||||
|
</MudButton>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<MudButton OnClick="Close">Schliessen</MudButton>
|
||||||
|
</DialogActions>
|
||||||
|
</MudDialog>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[CascadingParameter] private IMudDialogInstance MudDialog { get; set; } = null!;
|
||||||
|
|
||||||
|
[Parameter] public UserDto User { get; set; } = null!;
|
||||||
|
[Parameter] public Guid ClubId { get; set; }
|
||||||
|
[Parameter] public Guid CurrentUserProfileId { get; set; }
|
||||||
|
|
||||||
|
// Available roles for club-admin (no SuperAdmin)
|
||||||
|
private readonly string[] _availableRoles = { UserRole.Viewer, UserRole.Editor, UserRole.Admin };
|
||||||
|
private List<string> _currentRoles = new();
|
||||||
|
private bool _isProcessing;
|
||||||
|
private bool _hasChanges;
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
var membership = User.ClubMemberships.FirstOrDefault(m => m.ClubId == ClubId);
|
||||||
|
_currentRoles = membership?.Roles.ToList() ?? new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetRoleDisplayName(string role) => role switch
|
||||||
|
{
|
||||||
|
UserRole.Viewer => "Betrachter",
|
||||||
|
UserRole.Editor => "Bearbeiter",
|
||||||
|
UserRole.Admin => "Administrator",
|
||||||
|
_ => role
|
||||||
|
};
|
||||||
|
|
||||||
|
private async Task ToggleRole(string role, bool currentlyHasRole)
|
||||||
|
{
|
||||||
|
_isProcessing = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bool success;
|
||||||
|
if (currentlyHasRole)
|
||||||
|
{
|
||||||
|
success = await UserService.RemoveClubRoleAsync(User.ProfileId, ClubId, role);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
success = await UserService.AssignClubRoleAsync(User.ProfileId, ClubId, role, CurrentUserProfileId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
if (currentlyHasRole)
|
||||||
|
_currentRoles.Remove(role);
|
||||||
|
else
|
||||||
|
_currentRoles.Add(role);
|
||||||
|
|
||||||
|
_hasChanges = true;
|
||||||
|
Snackbar.Add(currentlyHasRole ? "Rolle entfernt" : "Rolle hinzugefuegt", Severity.Success);
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Snackbar.Add("Fehler beim Aendern der Rolle", Severity.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_isProcessing = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task RemoveFromClub()
|
||||||
|
{
|
||||||
|
_isProcessing = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var success = await UserService.RemoveUserFromClubAsync(User.ProfileId, ClubId);
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
_hasChanges = true;
|
||||||
|
Snackbar.Add("Aus Verein entfernt", Severity.Success);
|
||||||
|
MudDialog.Close(DialogResult.Ok(_hasChanges));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Snackbar.Add("Fehler beim Entfernen", Severity.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_isProcessing = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Close() => MudDialog.Close(DialogResult.Ok(_hasChanges));
|
||||||
|
}
|
||||||
|
|
@ -196,6 +196,61 @@ else
|
||||||
</MudCardContent>
|
</MudCardContent>
|
||||||
</MudCard>
|
</MudCard>
|
||||||
</MudTabPanel>
|
</MudTabPanel>
|
||||||
|
|
||||||
|
<MudTabPanel Text="Mitglieder" BadgeData="@(_clubMembers.Count)" BadgeColor="Color.Primary">
|
||||||
|
<MudCard Class="mt-4">
|
||||||
|
<MudCardContent>
|
||||||
|
@if (_isLoadingMembers)
|
||||||
|
{
|
||||||
|
<MudProgressCircular Indeterminate="true" Size="Size.Small" />
|
||||||
|
}
|
||||||
|
else if (!_clubMembers.Any())
|
||||||
|
{
|
||||||
|
<MudAlert Severity="Severity.Info">Keine Mitglieder vorhanden.</MudAlert>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<MudTable Items="_clubMembers" Dense="true" Hover="true">
|
||||||
|
<HeaderContent>
|
||||||
|
<MudTh>Name</MudTh>
|
||||||
|
<MudTh>E-Mail</MudTh>
|
||||||
|
<MudTh>Rollen</MudTh>
|
||||||
|
<MudTh>Aktionen</MudTh>
|
||||||
|
</HeaderContent>
|
||||||
|
<RowTemplate>
|
||||||
|
<MudTd DataLabel="Name">@context.DisplayName</MudTd>
|
||||||
|
<MudTd DataLabel="E-Mail">@context.Identity.Email</MudTd>
|
||||||
|
<MudTd DataLabel="Rollen">
|
||||||
|
@{
|
||||||
|
var membership = context.ClubMemberships.FirstOrDefault(m => m.ClubId == CurrentClubContext.ClubId);
|
||||||
|
if (membership != null && membership.Roles.Any())
|
||||||
|
{
|
||||||
|
@foreach (var role in membership.Roles)
|
||||||
|
{
|
||||||
|
<MudChip T="string" Size="Size.Small" Color="GetRoleColor(role)" Class="mr-1">
|
||||||
|
@GetRoleDisplayName(role)
|
||||||
|
</MudChip>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<MudText Typo="Typo.caption" Color="Color.Warning">Keine Rolle</MudText>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</MudTd>
|
||||||
|
<MudTd DataLabel="Aktionen">
|
||||||
|
<MudTooltip Text="Rollen verwalten">
|
||||||
|
<MudIconButton Icon="@Icons.Material.Filled.Security"
|
||||||
|
Size="Size.Small"
|
||||||
|
OnClick="@(() => OpenMemberRolesDialog(context))" />
|
||||||
|
</MudTooltip>
|
||||||
|
</MudTd>
|
||||||
|
</RowTemplate>
|
||||||
|
</MudTable>
|
||||||
|
}
|
||||||
|
</MudCardContent>
|
||||||
|
</MudCard>
|
||||||
|
</MudTabPanel>
|
||||||
</MudTabs>
|
</MudTabs>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -204,9 +259,11 @@ else
|
||||||
private bool _isLoading = true;
|
private bool _isLoading = true;
|
||||||
private bool _isLoadingInvitations = true;
|
private bool _isLoadingInvitations = true;
|
||||||
private bool _isLoadingPending = true;
|
private bool _isLoadingPending = true;
|
||||||
|
private bool _isLoadingMembers = true;
|
||||||
private int _activeTabIndex = 0;
|
private int _activeTabIndex = 0;
|
||||||
private List<ClubInvitationDto> _invitations = new();
|
private List<ClubInvitationDto> _invitations = new();
|
||||||
private List<PendingMembershipDto> _pendingMemberships = new();
|
private List<PendingMembershipDto> _pendingMemberships = new();
|
||||||
|
private List<UserDto> _clubMembers = new();
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
|
|
@ -217,19 +274,34 @@ else
|
||||||
private async Task LoadAllDataAsync()
|
private async Task LoadAllDataAsync()
|
||||||
{
|
{
|
||||||
_isLoading = true;
|
_isLoading = true;
|
||||||
|
_isLoadingInvitations = true;
|
||||||
|
_isLoadingPending = true;
|
||||||
|
_isLoadingMembers = true;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var clubId = CurrentClubContext.ClubId;
|
var clubId = CurrentClubContext.ClubId;
|
||||||
if (clubId != Guid.Empty)
|
if (clubId != Guid.Empty)
|
||||||
{
|
{
|
||||||
_club = await ClubService.GetByIdAsync(clubId);
|
_club = await ClubService.GetByIdAsync(clubId);
|
||||||
await LoadInvitationsAsync();
|
_isLoading = false;
|
||||||
await LoadPendingMembershipsAsync();
|
|
||||||
|
_invitations = (await ClubService.GetInvitationsByClubAsync(clubId)).ToList();
|
||||||
|
_isLoadingInvitations = false;
|
||||||
|
|
||||||
|
_pendingMemberships = (await UserService.GetPendingMembershipsAsync(clubId)).ToList();
|
||||||
|
_isLoadingPending = false;
|
||||||
|
|
||||||
|
_clubMembers = (await UserService.GetUsersByClubAsync(clubId)).ToList();
|
||||||
|
_isLoadingMembers = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
|
_isLoadingInvitations = false;
|
||||||
|
_isLoadingPending = false;
|
||||||
|
_isLoadingMembers = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -267,6 +339,23 @@ else
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task LoadMembersAsync()
|
||||||
|
{
|
||||||
|
_isLoadingMembers = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var clubId = CurrentClubContext.ClubId;
|
||||||
|
if (clubId != Guid.Empty)
|
||||||
|
{
|
||||||
|
_clubMembers = (await UserService.GetUsersByClubAsync(clubId)).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_isLoadingMembers = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ClearError()
|
private void ClearError()
|
||||||
{
|
{
|
||||||
Dispatcher.Dispatch(new ClearClubErrorAction());
|
Dispatcher.Dispatch(new ClearClubErrorAction());
|
||||||
|
|
@ -461,4 +550,47 @@ else
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string GetRoleDisplayName(string role) => role switch
|
||||||
|
{
|
||||||
|
UserRole.Viewer => "Betrachter",
|
||||||
|
UserRole.Editor => "Bearbeiter",
|
||||||
|
UserRole.Admin => "Administrator",
|
||||||
|
_ => role
|
||||||
|
};
|
||||||
|
|
||||||
|
private static Color GetRoleColor(string role) => role switch
|
||||||
|
{
|
||||||
|
UserRole.Admin => Color.Error,
|
||||||
|
UserRole.Editor => Color.Warning,
|
||||||
|
UserRole.Viewer => Color.Info,
|
||||||
|
_ => Color.Default
|
||||||
|
};
|
||||||
|
|
||||||
|
private async Task OpenMemberRolesDialog(UserDto user)
|
||||||
|
{
|
||||||
|
var currentUser = await UserService.GetCurrentUserAsync();
|
||||||
|
if (currentUser == null)
|
||||||
|
{
|
||||||
|
Snackbar.Add("Nicht angemeldet", Severity.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var parameters = new DialogParameters
|
||||||
|
{
|
||||||
|
{ "User", user },
|
||||||
|
{ "ClubId", CurrentClubContext.ClubId },
|
||||||
|
{ "CurrentUserProfileId", currentUser.ProfileId }
|
||||||
|
};
|
||||||
|
|
||||||
|
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.Small };
|
||||||
|
var dialog = await DialogService.ShowAsync<ClubMemberRolesDialog>("Rollen verwalten", parameters, options);
|
||||||
|
var result = await dialog.Result;
|
||||||
|
|
||||||
|
if (result != null && !result.Canceled && result.Data is bool hasChanges && hasChanges)
|
||||||
|
{
|
||||||
|
await LoadMembersAsync();
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue