@page "/expenses" @attribute [Authorize(Policy = "ClubViewer")] @inherits Fluxor.Blazor.Web.Components.FluxorComponent @using Fluxor @using Koogle.Application.DTOs @using Koogle.Domain.Enums @using Koogle.Web.Store.ExpenseState @using Microsoft.AspNetCore.Authorization @inject IState ExpenseState @inject IDispatcher Dispatcher @inject ISnackbar Snackbar @inject IDialogService DialogService Strafen-Vorlagen Strafen-Vorlagen @if (ExpenseState.Value.Error is not null) { @ExpenseState.Value.Error } Geldstrafe Sachleistung Neue Vorlage Name Preis Typ Optionen Aktionen @context.Name @context.Price.ToString("C") @GetTypeLabel(context.ExpenseType) @if (context.IsOneClick) { } @if (context.IsInverse) { } @if (context.IsVariable) { } Keine Kosten-Vorlagen gefunden @code { private string _searchString = ""; private ExpenseType? _typeFilter; private IEnumerable FilteredExpenses => _typeFilter.HasValue ? ExpenseState.Value.Expenses.Where(e => e.ExpenseType == _typeFilter.Value) : ExpenseState.Value.Expenses; protected override void OnInitialized() { base.OnInitialized(); Dispatcher.Dispatch(new LoadExpensesAction()); } private bool FilterFunc(ExpenseDto expense) { if (string.IsNullOrWhiteSpace(_searchString)) return true; return expense.Name.Contains(_searchString, StringComparison.OrdinalIgnoreCase) || expense.Description.Contains(_searchString, StringComparison.OrdinalIgnoreCase); } private void ClearError() { Dispatcher.Dispatch(new ClearExpenseErrorAction()); } private static string GetTypeLabel(ExpenseType type) => type switch { ExpenseType.Monetary => "Geldstrafe", ExpenseType.Material => "Sachleistung", _ => type.ToString() }; private static Color GetTypeColor(ExpenseType type) => type switch { ExpenseType.Monetary => Color.Warning, ExpenseType.Material => Color.Info, _ => Color.Default }; private async Task OpenCreateDialog() { var dialog = await DialogService.ShowAsync("Neue Strafen-Vorlage"); var result = await dialog.Result; if (result != null && !result.Canceled && result.Data is CreateExpenseDto dto) { Dispatcher.Dispatch(new CreateExpenseAction(dto)); Snackbar.Add("Vorlage wird erstellt...", Severity.Info); } } private async Task OpenEditDialog(ExpenseDto expense) { var parameters = new DialogParameters { { "Expense", expense } }; var dialog = await DialogService.ShowAsync("Kosten-Vorlage bearbeiten", parameters); var result = await dialog.Result; if (result != null && !result.Canceled && result.Data is UpdateExpenseDto dto) { Dispatcher.Dispatch(new UpdateExpenseAction(dto)); Snackbar.Add("Vorlage wird aktualisiert...", Severity.Info); } } private async Task ConfirmDelete(ExpenseDto expense) { var parameters = new DialogParameters { { "ContentText", $"Möchten Sie \"{expense.Name}\" wirklich löschen? Diese Aktion kann nicht rückgängig gemacht werden." }, { "ButtonText", "Löschen" }, { "Color", Color.Error } }; var dialog = await DialogService.ShowAsync("Kosten-Vorlage löschen", parameters); var result = await dialog.Result; if (result != null && !result.Canceled) { Dispatcher.Dispatch(new DeleteExpenseAction(expense.Id)); Snackbar.Add("Vorlage wird gelöscht...", Severity.Info); } } }