added club-settings:

Neue Datei: src/Koogle.Web/Components/Pages/Settings.razor
  - Route /settings mit ClubAdmin-Policy
  - Zeigt Name, LoginName, Kostenberechnung
  - "Bearbeiten" Button öffnet bestehenden ClubEditDialog
  - Kein Löschen, keine Neuanlage

  Geändert: src/Koogle.Web/Components/Layout/NavMenu.razor
  - Neuer Link "Vereins-Einstellungen" in "Stammdaten"-Gruppe (Icon: Tune)
This commit is contained in:
beo3000 2026-01-01 14:34:02 +01:00
parent 4666056e24
commit fc9dfcaca0
2 changed files with 146 additions and 3 deletions

View File

@ -44,7 +44,7 @@
<MudNavLink Href="/expensetriggers" <MudNavLink Href="/expensetriggers"
Match="NavLinkMatch.Prefix" Match="NavLinkMatch.Prefix"
Icon="@Icons.Material.Filled.FlashOn"> Icon="@Icons.Material.Filled.FlashOn">
Auslöser Ausl<EFBFBD>ser
</MudNavLink> </MudNavLink>
<MudNavLink Href="/admin/gifs" <MudNavLink Href="/admin/gifs"
@ -52,7 +52,13 @@
Icon="@Icons.Material.Filled.VideoFile"> Icon="@Icons.Material.Filled.VideoFile">
Gifs Gifs
</MudNavLink> </MudNavLink>
<MudNavLink Href="/settings"
Match="NavLinkMatch.All"
Icon="@Icons.Material.Filled.Tune">
Vereins-Einstellungen
</MudNavLink>
</MudNavGroup> </MudNavGroup>
} }
} }
@ -79,7 +85,7 @@
<MudNavLink Href="/admin/triggers" <MudNavLink Href="/admin/triggers"
Match="NavLinkMatch.Prefix" Match="NavLinkMatch.Prefix"
Icon="@Icons.Material.Filled.FlashOn"> Icon="@Icons.Material.Filled.FlashOn">
Auslöser Ausl<EFBFBD>ser
</MudNavLink> </MudNavLink>
} }
</MudNavGroup> </MudNavGroup>

View File

@ -0,0 +1,137 @@
@page "/settings"
@attribute [Authorize(Policy = "ClubAdmin")]
@inherits Fluxor.Blazor.Web.Components.FluxorComponent
@using Fluxor
@using Koogle.Application.DTOs
@using Koogle.Application.Interfaces
@using Koogle.Domain.Enums
@using Koogle.Web.Store.ClubState
@using Koogle.Web.Components.Pages.Admin
@using Microsoft.AspNetCore.Authorization
@inject IClubService ClubService
@inject ICurrentClubContext CurrentClubContext
@inject IState<ClubState> ClubState
@inject IDispatcher Dispatcher
@inject ISnackbar Snackbar
@inject IDialogService DialogService
<PageTitle>Vereins-Einstellungen</PageTitle>
<MudText Typo="Typo.h4" Class="mb-4">Vereins-Einstellungen</MudText>
@if (ClubState.Value.Error is not null)
{
<MudAlert Severity="Severity.Error" Class="mb-4" ShowCloseIcon="true" CloseIconClicked="ClearError">
@ClubState.Value.Error
</MudAlert>
}
@if (_isLoading)
{
<MudProgressCircular Indeterminate="true" />
}
else if (_club is null)
{
<MudAlert Severity="Severity.Warning">Kein Club ausgewählt</MudAlert>
}
else
{
<MudCard>
<MudCardContent>
<MudGrid>
<MudItem xs="12" sm="6">
<MudText Typo="Typo.caption" Color="Color.Secondary">Name</MudText>
<MudText Typo="Typo.body1">@_club.Name</MudText>
</MudItem>
<MudItem xs="12" sm="6">
<MudText Typo="Typo.caption" Color="Color.Secondary">Login-Name</MudText>
<MudText Typo="Typo.body1">@_club.LoginName</MudText>
</MudItem>
<MudItem xs="12">
<MudText Typo="Typo.caption" Color="Color.Secondary">Kostenberechnung</MudText>
<MudChip T="string" Size="Size.Small" Color="GetCalculationColor(_club.ExpenseCalculation)">
@GetCalculationLabel(_club.ExpenseCalculation)
</MudChip>
</MudItem>
</MudGrid>
</MudCardContent>
<MudCardActions>
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@Icons.Material.Filled.Edit"
OnClick="OpenEditDialog">
Bearbeiten
</MudButton>
</MudCardActions>
</MudCard>
}
@code {
private ClubDto? _club;
private bool _isLoading = true;
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
await LoadClubAsync();
}
private async Task LoadClubAsync()
{
_isLoading = true;
try
{
var clubId = CurrentClubContext.ClubId;
if (clubId != Guid.Empty)
{
_club = await ClubService.GetByIdAsync(clubId);
}
}
finally
{
_isLoading = false;
}
}
private void ClearError()
{
Dispatcher.Dispatch(new ClearClubErrorAction());
}
private static string GetCalculationLabel(ExpenseCalculation calculation) => calculation switch
{
ExpenseCalculation.None => "Keine",
ExpenseCalculation.Average => "Durchschnitt",
ExpenseCalculation.Maximum => "Maximum",
_ => calculation.ToString()
};
private static Color GetCalculationColor(ExpenseCalculation calculation) => calculation switch
{
ExpenseCalculation.None => Color.Default,
ExpenseCalculation.Average => Color.Info,
ExpenseCalculation.Maximum => Color.Warning,
_ => Color.Default
};
private async Task OpenEditDialog()
{
if (_club is null) return;
var parameters = new DialogParameters
{
{ "Club", _club }
};
var dialog = await DialogService.ShowAsync<ClubEditDialog>("Vereins-Einstellungen bearbeiten", parameters);
var result = await dialog.Result;
if (result != null && !result.Canceled && result.Data is UpdateClubDto dto)
{
Dispatcher.Dispatch(new UpdateClubAction(dto));
Snackbar.Add("Einstellungen werden gespeichert...", Severity.Info);
await LoadClubAsync();
}
}
}