Files
a.beging@eas-solutions.de cefa47a176
All checks were successful
Build And Push Dev Docker Image / docker (push) Successful in 1m47s
Enhance user management: prevent deletion of the last admin user and restrict admin type changes for the last admin account
Co-authored-by: Copilot <copilot@github.com>
2026-04-30 09:53:05 +02:00

142 lines
6.0 KiB
Plaintext

@page "/user"
@page "/users"
@using FoodsharingSiegen.Contracts.Entity
@using FoodsharingSiegen.Contracts.Enums
@using FoodsharingSiegen.Server.Dialogs
@inherits FoodsharingSiegen.Server.BaseClasses.FsBase
<PageTitle>Benutzerverwaltung - @AppSettings.Terms.Title</PageTitle>
<div class="d-flex justify-content-between align-items-center mb-3">
<h2>Benutzerverwaltung <span style="font-size: .5em; line-height: 0;">Admin</span></h2>
<Button Color="Color.Success" Clicked="CreateNewUser">
<Icon Name="IconName.Add" /> Benutzer erstellen
</Button>
</div>
<div class="user-grid" style="max-width: 1000px;">
@if (SortedUsers != null)
{
@foreach (var user in SortedUsers)
{
<Card Class="user-card">
<CardBody>
<CardTitle Size="4">@user.Name</CardTitle>
<CardSubtitle Class="mb-2 text-muted">@user.Mail</CardSubtitle>
<CardText>
Typ:
@if (user.Type == UserType.Unverified)
{
<span style="color: red" class="fw-bold">@user.Type</span>
}
else if (user.Type == UserType.Admin)
{
<span style="color: blue" class="fw-bold">@user.Type</span>
}
else
{
@user.Type
}
</CardText>
<div class="mb-3">
@if (user.GroupsList != null && user.GroupsList.Any())
{
@foreach(var group in user.GroupsList)
{
<Badge Color="Color.Primary" Class="me-1" Style="font-size: 0.8em;">@group.ToString()</Badge>
}
}
else
{
<span class="text-muted" style="font-style: italic; font-size: 0.8em;">Keine Gruppen</span>
}
</div>
</CardBody>
<CardFooter Class="d-flex justify-content-between">
<Button Color="Color.Primary" Size="Size.Small" Clicked="() => EditUser(user)"><Icon Name="IconName.Edit" /></Button>
<Button Color="Color.Info" Size="Size.Small" Clicked="() => SetPassword(user)"><i class="fa-solid fa-key"></i></Button>
<Button Color="Color.Secondary" Size="Size.Small" Clicked="() => SendPasswordSetupMail(user)"><Icon Name="IconName.Mail" /></Button>
@if (!(user.Type == UserType.Admin && SortedUsers.Count(x => x.Type == UserType.Admin) <= 1))
{
<Button Color="Color.Danger" Size="Size.Small" Clicked="() => RemoveUserAsync(user)"><Icon Name="IconName.Delete" /></Button>
}
</CardFooter>
</Card>
}
}
</div>
<style>
.user-grid {
display: grid;
grid-template-columns: repeat(1, 1fr);
gap: 1rem;
}
@@media (min-width: 700px) {
.user-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@@media (min-width: 1250px) {
.user-grid {
grid-template-columns: repeat(3, 1fr);
}
}
</style>
<Modal @ref="editUserModal">
<ModalContent Centered>
<ModalHeader>
<ModalTitle>@(IsEditing ? "Benutzer bearbeiten" : "Benutzer erstellen")</ModalTitle>
<CloseButton />
</ModalHeader>
<ModalBody>
@if (EditModel != null)
{
<Field>
<FieldLabel>Name</FieldLabel>
<TextEdit @bind-Text="EditModel.Name" />
</Field>
<Field>
<FieldLabel>E-Mail</FieldLabel>
<TextEdit @bind-Text="EditModel.Mail" />
</Field>
<Field>
<FieldLabel>Typ</FieldLabel>
<Select TValue="UserType" SelectedValue="EditModel.Type" SelectedValueChanged="@(v => EditModel.Type = v)" Disabled="@IsLastAdmin">
@foreach (var enumValue in Enum.GetValues<UserType>())
{
<SelectItem TValue="UserType" Value="enumValue">@enumValue</SelectItem>
}
</Select>
@if (IsLastAdmin)
{
<small class="text-danger mt-1 d-block">Das ist der letzte Administrator-Account. Der Typ kann nicht geändert werden.</small>
}
</Field>
<Field>
<FieldLabel>Gruppen</FieldLabel>
<Autocomplete TItem="UserGroup"
TValue="UserGroup"
Data="@UserGroups"
TextField="@(( item ) => item.ToString())"
ValueField="@(( item ) => item)"
SelectionMode="AutocompleteSelectionMode.Multiple"
SelectedValues="@EditModel.GroupsList"
SelectedValuesChanged="@(v => { EditModel.GroupsList = v.ToList(); })"
@bind-SelectedTexts="SelectedGroupTexts">
</Autocomplete>
<small>Verfügbar: @string.Join(", ", Enum.GetValues<UserGroup>())</small>
</Field>
}
</ModalBody>
<ModalFooter>
<Button Color="Color.Secondary" Clicked="() => editUserModal?.Hide()">Abbrechen</Button>
<Button Color="Color.Primary" Clicked="SaveUser">Speichern</Button>
</ModalFooter>
</ModalContent>
</Modal>
<SetPasswordModal @ref="PasswordModal" OnPasswortSet="OnPasswordSet"></SetPasswordModal>