194 lines
6.8 KiB
Plaintext
194 lines
6.8 KiB
Plaintext
@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> ExpenseState
|
|
@inject IDispatcher Dispatcher
|
|
@inject ISnackbar Snackbar
|
|
@inject IDialogService DialogService
|
|
|
|
<PageTitle>Strafen-Vorlagen</PageTitle>
|
|
|
|
<MudText Typo="Typo.h4" Class="mb-4">Strafen-Vorlagen</MudText>
|
|
|
|
@if (ExpenseState.Value.Error is not null)
|
|
{
|
|
<MudAlert Severity="Severity.Error" Class="mb-4" ShowCloseIcon="true" CloseIconClicked="ClearError">
|
|
@ExpenseState.Value.Error
|
|
</MudAlert>
|
|
}
|
|
|
|
<MudTable Items="FilteredExpenses" Dense="true" Hover="true" Loading="ExpenseState.Value.IsLoading"
|
|
Filter="FilterFunc">
|
|
<ToolBarContent>
|
|
<MudTextField @bind-Value="_searchString"
|
|
Placeholder="Suchen..."
|
|
Adornment="Adornment.Start"
|
|
AdornmentIcon="@Icons.Material.Filled.Search"
|
|
IconSize="Size.Medium"
|
|
Class="mt-0" />
|
|
<MudSpacer />
|
|
<MudSelect T="ExpenseType?" @bind-Value="_typeFilter" Label="Typ" Clearable="true" Class="mr-4" Style="width: 150px;">
|
|
<MudSelectItem Value="@((ExpenseType?)ExpenseType.Monetary)">Geldstrafe</MudSelectItem>
|
|
<MudSelectItem Value="@((ExpenseType?)ExpenseType.Material)">Sachleistung</MudSelectItem>
|
|
</MudSelect>
|
|
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@Icons.Material.Filled.Add"
|
|
OnClick="OpenCreateDialog">
|
|
Neue Vorlage
|
|
</MudButton>
|
|
</ToolBarContent>
|
|
<HeaderContent>
|
|
<MudTh>Name</MudTh>
|
|
<MudTh>Preis</MudTh>
|
|
<MudTh>Typ</MudTh>
|
|
<MudTh>Optionen</MudTh>
|
|
<MudTh>Aktionen</MudTh>
|
|
</HeaderContent>
|
|
<RowTemplate>
|
|
<MudTd DataLabel="Name">@context.Name</MudTd>
|
|
<MudTd DataLabel="Preis">@context.Price.ToString("C")</MudTd>
|
|
<MudTd DataLabel="Typ">
|
|
<MudChip T="string" Size="Size.Small" Color="GetTypeColor(context.ExpenseType)">
|
|
@GetTypeLabel(context.ExpenseType)
|
|
</MudChip>
|
|
</MudTd>
|
|
<MudTd DataLabel="Optionen">
|
|
@if (context.IsOneClick)
|
|
{
|
|
<MudTooltip Text="One-Click: Schnellauswahl">
|
|
<MudIcon Icon="@Icons.Material.Filled.TouchApp" Size="Size.Small" Class="mr-1" />
|
|
</MudTooltip>
|
|
}
|
|
@if (context.IsInverse)
|
|
{
|
|
<MudTooltip Text="Invers: Alle außer einer Person">
|
|
<MudIcon Icon="@Icons.Material.Filled.GroupRemove" Size="Size.Small" Class="mr-1" />
|
|
</MudTooltip>
|
|
}
|
|
@if (context.IsVariable)
|
|
{
|
|
<MudTooltip Text="Variabel: Preis anpassbar">
|
|
<MudIcon Icon="@Icons.Material.Filled.Edit" Size="Size.Small" />
|
|
</MudTooltip>
|
|
}
|
|
</MudTd>
|
|
<MudTd DataLabel="Aktionen">
|
|
<MudTooltip Text="Bearbeiten">
|
|
<MudIconButton Icon="@Icons.Material.Filled.Edit"
|
|
Size="Size.Small"
|
|
OnClick="@(() => OpenEditDialog(context))"/>
|
|
</MudTooltip>
|
|
<MudTooltip Text="Löschen">
|
|
<MudIconButton Icon="@Icons.Material.Filled.Delete"
|
|
Size="Size.Small"
|
|
Color="Color.Error"
|
|
OnClick="@(() => ConfirmDelete(context))"/>
|
|
</MudTooltip>
|
|
</MudTd>
|
|
</RowTemplate>
|
|
<PagerContent>
|
|
<MudTablePager />
|
|
</PagerContent>
|
|
<NoRecordsContent>
|
|
<MudText>Keine Kosten-Vorlagen gefunden</MudText>
|
|
</NoRecordsContent>
|
|
</MudTable>
|
|
|
|
@code {
|
|
private string _searchString = "";
|
|
private ExpenseType? _typeFilter;
|
|
|
|
private IEnumerable<ExpenseDto> 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<ExpenseEditDialog>("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<ExpenseEditDialog>("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<Koogle.Web.Components.Shared.ConfirmDialog>("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);
|
|
}
|
|
}
|
|
}
|