Skip to content
This repository has been archived by the owner on Apr 8, 2023. It is now read-only.

Allow for teams to be fined. #163

Merged
merged 6 commits into from
Nov 7, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Client/Features/Admin/AddPlayer.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public sealed partial class AddPlayer : IDisposable
private TeamNameListResult _teamList = new();
private AddPlayerRequest _addPlayerForm = new();
private AddPlayerRequestValidator _validator = null!;
private PlayerPreviewRequest _playerPreviewForm = new();
private readonly PlayerPreviewRequest _playerPreviewForm = new();
private string _previewHeadshotUrl = string.Empty;
private bool _isPreviewButtonDisabled;
private bool _isProcessingForm;
Expand Down
7 changes: 5 additions & 2 deletions src/Client/Features/Fines/List.razor
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<MudTh>Actions</MudTh>
</Authorized>
</AuthorizeView>
<MudTh><MudTableSortLabel SortBy="new Func<FineItem,object>(x=> x.PlayerName)">Name</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<FineItem,object?>(x=> x.PlayerName)">Name</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<FineItem,object>(x=> x.TeamName)">Team</MudTableSortLabel></MudTh>
<MudTh>Reason</MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<FineItem,object>(x=> x.Amount)">Amount</MudTableSortLabel></MudTh>
Expand All @@ -35,7 +35,10 @@
</Authorized>
</AuthorizeView>
<MudTd DataLabel=Name>
<NameWithImage Name="@fineItem.PlayerName" ImageUrl="@fineItem.PlayerHeadShotUrl" />
@if(fineItem.PlayerName != null)
{
<NameWithImage Name="@fineItem.PlayerName" ImageUrl="@fineItem.PlayerHeadShotUrl" />
}
</MudTd>
<MudTd DataLabel=Team>
<NameWithImage Name="@fineItem.TeamName" ImageUrl="@fineItem.TeamLogoUrl" />
Expand Down
2 changes: 1 addition & 1 deletion src/Client/Features/Players/AddFine.razor
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{
<MudDialog>
<DialogContent>
<MudSkeleton SkeletonType=SkeletonType.Text Width=300px Height=60px/>
<MudSkeleton SkeletonType=SkeletonType.Text Width=100% Height=60px/>
<MudSkeleton SkeletonType=SkeletonType.Rectangle Width=100% Height=100px />
</DialogContent>
<DialogActions>
Expand Down
6 changes: 3 additions & 3 deletions src/Client/Features/Players/AddFine.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ public sealed partial class AddFine : IDisposable
[CascadingParameter] MudDialogInstance MudDialogInstance { get; set; } = null!;
[Parameter, EditorRequired] public int PlayerId { get; set; }

private AddFineRequest _form = null!;
private AddPlayerFineRequest _form = null!;
private FineDetailResult? _fineDetail;
private bool _processingForm;
private readonly CancellationTokenSource _cts = new();

protected override async Task OnInitializedAsync()
{
_form = new AddFineRequest { PlayerId = PlayerId };
_form = new AddPlayerFineRequest { PlayerId = PlayerId };

await GetPlayerFineDetailsAsync();
}
Expand All @@ -30,7 +30,7 @@ private async Task OnValidSubmitAsync()
{
_processingForm = true;

var response = await HttpClient.PostAsJsonAsync(AddFineRouteFactory.Uri, _form);
var response = await HttpClient.PostAsJsonAsync(AddPlayerFineRouteFactory.Uri, _form);

if (response.IsSuccessStatusCode)
{
Expand Down
12 changes: 12 additions & 0 deletions src/Client/Features/Teams/AddFine.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<EditForm Model=_form OnValidSubmit=OnValidSubmitAsync>
<FluentValidationValidator />
<MudDialog>
<DialogContent>
<MudTextField Label="Fine Reason" HelperText="Enter a fine reason..." @bind-Value="_form.FineReason" For="@(() => _form.FineReason)" Lines=5/>
<MudTextField Label="Fine Amount" HelperText="Enter a fine amount..." @bind-Value="_form.Amount" For="@(() => _form.Amount)" InputType=InputType.Number/>
</DialogContent>
<DialogActions>
<LoadingButton @bind-IsLoading="_processingForm"/>
</DialogActions>
</MudDialog>
</EditForm>
45 changes: 45 additions & 0 deletions src/Client/Features/Teams/AddFine.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using DynamoLeagueBlazor.Shared.Features.Teams;

namespace DynamoLeagueBlazor.Client.Features.Teams;

public sealed partial class AddFine : IDisposable
{
[Inject] private HttpClient HttpClient { get; set; } = null!;
[Inject] private ISnackbar SnackBar { get; set; } = null!;
[CascadingParameter] MudDialogInstance MudDialogInstance { get; set; } = null!;
[Parameter, EditorRequired] public int TeamId { get; set; }

private AddTeamFineRequest _form = null!;
private bool _processingForm;
private readonly CancellationTokenSource _cts = new();

protected override void OnInitialized()
{
_form = new AddTeamFineRequest { TeamId = TeamId };
}

private async Task OnValidSubmitAsync()
{
_processingForm = true;

var response = await HttpClient.PostAsJsonAsync(AddTeamFineRouteFactory.Uri, _form);

if (response.IsSuccessStatusCode)
{
SnackBar.Add("Successfully added a fine.", Severity.Success);
}
else
{
SnackBar.Add("Something went wrong...", Severity.Error);
}

_processingForm = false;
MudDialogInstance.Close();
}

public void Dispose()
{
_cts.Cancel();
_cts.Dispose();
}
}
7 changes: 7 additions & 0 deletions src/Client/Features/Teams/Detail.razor
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ else
<MudText Typo="Typo.h4" Align=Align.Center>@_result.Name</MudText>
<MudText Typo=Typo.h6>Remaining Cap Space</MudText>
<MudText Typo=Typo.h6 Color=Color.Success>@_result.CapSpace</MudText>
<AuthorizeView Roles="Admin">
<Authorized>
<MudButton Color="Color.Error" StartIcon="@Icons.Material.Filled.MoneyOff" OnClick="(e) => OpenAddFineDialog(TeamId)" FullWidth=true>
Fine This Team
</MudButton>
</Authorized>
</AuthorizeView>
<MudDivider Class="mt-2" Style="max-width:250px; width: 100%"/>
<MudBadge Origin=Origin.CenterRight Content=_result.RosteredPlayers.Count() Color=Color.Tertiary>
<MudButton Variant="Variant.Text" Color="Color.Tertiary" [email protected] OnClick=ShowRosteredPlayers>
Expand Down
10 changes: 10 additions & 0 deletions src/Client/Features/Teams/Detail.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,16 @@ private async Task OpenSignPlayerDialogAsync(int playerId)
}
}

private void OpenAddFineDialog(int playerId)
{
var parameters = new DialogParameters
{
{ nameof(AddFine.TeamId), playerId }
};

DialogService.Show<AddFine>("Add A New Fine", parameters);
}

public void Dispose()
{
_cts.Cancel();
Expand Down
1 change: 1 addition & 0 deletions src/Server/DynamoLeagueBlazor.Server.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.8" />
<PackageReference Include="Serilog.AspNetCore" Version="5.0.0" />
<PackageReference Include="Serilog.AspNetCore.Ingestion" Version="1.0.0-dev-00021" />
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.2.0" />
<PackageReference Include="Serilog.Sinks.Trace" Version="3.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="stateless" Version="5.11.0" />
Expand Down
4 changes: 2 additions & 2 deletions src/Server/Features/Fines/List.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ public ListMappingProfile()
{
CreateMap<Fine, FineListResult.FineItem>()
.ForMember(d => d.Status, mo => mo.MapFrom(s => s.Status ? "Approved" : "Pending"))
.ForMember(d => d.PlayerName, mo => mo.MapFrom(s => s.Player.Name))
.ForMember(d => d.PlayerHeadShotUrl, mo => mo.MapFrom(s => s.Player.HeadShotUrl))
.ForMember(d => d.PlayerName, mo => mo.MapFrom(s => s.Player != null ? s.Player.Name : null))
.ForMember(d => d.PlayerHeadShotUrl, mo => mo.MapFrom(s => s.Player != null ? s.Player.HeadShotUrl : null))
.ForMember(d => d.TeamName, mo => mo.MapFrom(s => s.Team.Name))
.ForMember(d => d.TeamLogoUrl, mo => mo.MapFrom(s => s.Team.LogoUrl))
.ForMember(d => d.Amount, mo => mo.MapFrom(s => s.Amount));
Expand Down
24 changes: 12 additions & 12 deletions src/Server/Features/Players/AddFine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,40 @@

namespace DynamoLeagueBlazor.Server.Features.Fines;

[Route(AddFineRouteFactory.Uri)]
[Route(AddPlayerFineRouteFactory.Uri)]
[ApiController]
public class AddFineController : ControllerBase
public class AddPlayerFineController : ControllerBase
{
private readonly IMediator _mediator;
private readonly IMapper _mapper;

public AddFineController(IMediator mediator, IMapper mapper)
public AddPlayerFineController(IMediator mediator, IMapper mapper)
{
_mediator = mediator;
_mapper = mapper;
}

[HttpPost]
public async Task<int> PostAsync([FromBody] AddFineRequest request, CancellationToken cancellationToken)
public async Task<int> PostAsync([FromBody] AddPlayerFineRequest request, CancellationToken cancellationToken)
{
var query = _mapper.Map<AddFineCommand>(request);
var query = _mapper.Map<AddPlayerFineCommand>(request);

return await _mediator.Send(query, cancellationToken);
}
}

public record AddFineCommand(int PlayerId, string FineReason) : IRequest<int> { }
public record AddPlayerFineCommand(int PlayerId, string FineReason) : IRequest<int> { }

public class AddFineHandler : IRequestHandler<AddFineCommand, int>
public class AddPlayerFineHandler : IRequestHandler<AddPlayerFineCommand, int>
{
private readonly ApplicationDbContext _dbContext;

public AddFineHandler(ApplicationDbContext dbContext)
public AddPlayerFineHandler(ApplicationDbContext dbContext)
{
_dbContext = dbContext;
}

public async Task<int> Handle(AddFineCommand request, CancellationToken cancellationToken)
public async Task<int> Handle(AddPlayerFineCommand request, CancellationToken cancellationToken)
{
var player = (await _dbContext.Players
.AsTracking()
Expand All @@ -52,10 +52,10 @@ public async Task<int> Handle(AddFineCommand request, CancellationToken cancella
}
}

public class AddFineMappingProfile : Profile
public class AddPlayerFineMappingProfile : Profile
{
public AddFineMappingProfile()
public AddPlayerFineMappingProfile()
{
CreateMap<AddFineRequest, AddFineCommand>();
CreateMap<AddPlayerFineRequest, AddPlayerFineCommand>();
}
}
58 changes: 58 additions & 0 deletions src/Server/Features/Teams/AddFine.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using DynamoLeagueBlazor.Shared.Features.Teams;

namespace DynamoLeagueBlazor.Server.Features.Teams;

[Route(AddTeamFineRouteFactory.Uri)]
[ApiController]
public class AddTeamFineController : ControllerBase
{
private readonly IMediator _mediator;
private readonly IMapper _mapper;

public AddTeamFineController(IMediator mediator, IMapper mapper)
{
_mediator = mediator;
_mapper = mapper;
}

[HttpPost]
public async Task PostAsync([FromBody] AddTeamFineRequest request, CancellationToken cancellationToken)
{
var query = _mapper.Map<AddTeamFineCommand>(request);

await _mediator.Send(query, cancellationToken);
}
}

public record AddTeamFineCommand(int TeamId, string FineReason, decimal Amount) : IRequest { }

public class AddTeamFineHandler : IRequestHandler<AddTeamFineCommand>
{
private readonly ApplicationDbContext _dbContext;

public AddTeamFineHandler(ApplicationDbContext dbContext)
{
_dbContext = dbContext;
}

public async Task<Unit> Handle(AddTeamFineCommand request, CancellationToken cancellationToken)
{
var team = (await _dbContext.Teams
.AsTracking()
.SingleAsync(p => p.Id == request.TeamId, cancellationToken));

team.AddFine(request.Amount, request.FineReason);

await _dbContext.SaveChangesAsync(cancellationToken);

return Unit.Value;
}
}

public class AddTeamFineMappingProfile : Profile
{
public AddTeamFineMappingProfile()
{
CreateMap<AddTeamFineRequest, AddTeamFineCommand>();
}
}
Loading