Update and delete games (#48)
All checks were successful
Game Ideas deploy / build-test-deploy (push) Successful in 1m27s
All checks were successful
Game Ideas deploy / build-test-deploy (push) Successful in 1m27s
Co-authored-by: Maxime Adler <madler@sqli.com> Reviewed-on: #48
This commit was merged in pull request #48.
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
namespace GameIdeas.BlazorApp.Pages.Games.Components;
|
||||
|
||||
public enum DetailOptions
|
||||
{
|
||||
Detail,
|
||||
Edit,
|
||||
Delete
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
using GameIdeas.Shared.Dto;
|
||||
using GameIdeas.BlazorApp.Shared.Components.Select;
|
||||
using GameIdeas.BlazorApp.Shared.Components.Select.Models;
|
||||
using GameIdeas.Resources;
|
||||
using GameIdeas.Shared.Dto;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace GameIdeas.BlazorApp.Pages.Games.Components;
|
||||
@@ -6,10 +9,51 @@ namespace GameIdeas.BlazorApp.Pages.Games.Components;
|
||||
public class GameBase : ComponentBase
|
||||
{
|
||||
[Parameter] public GameDto GameDto { get; set; } = new();
|
||||
[Parameter] public EventCallback<GameDto> OnDelete { get; set; } = new();
|
||||
[Parameter] public EventCallback<GameDto> OnEdit { get; set; } = new();
|
||||
[Inject] public NavigationManager NavigationManager { get; set; } = default!;
|
||||
|
||||
protected void HandleDetailClicked()
|
||||
protected SelectParams<DetailOptions, object> SelectParams = default!;
|
||||
protected Select<DetailOptions, object>? SelectOption;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
NavigationManager.NavigateTo($"/Games/Detail/{GameDto.Id}");
|
||||
SelectParams = new()
|
||||
{
|
||||
Items = [DetailOptions.Detail, DetailOptions.Edit, DetailOptions.Delete],
|
||||
GetItemLabel = GetDetailOptionsLabel
|
||||
};
|
||||
}
|
||||
|
||||
protected async Task HandlerSelectValuesChanged(IEnumerable<DetailOptions> detailOptions)
|
||||
{
|
||||
var option = detailOptions.First();
|
||||
switch (option)
|
||||
{
|
||||
case DetailOptions.Detail:
|
||||
NavigationManager.NavigateTo($"/Detail/{GameDto.Id}");
|
||||
break;
|
||||
case DetailOptions.Edit:
|
||||
await OnEdit.InvokeAsync(GameDto);
|
||||
break;
|
||||
case DetailOptions.Delete:
|
||||
await OnDelete.InvokeAsync(GameDto);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
SelectOption?.Close();
|
||||
}
|
||||
|
||||
private string GetDetailOptionsLabel(DetailOptions options)
|
||||
{
|
||||
return options switch
|
||||
{
|
||||
DetailOptions.Detail => ResourcesKey.Detail,
|
||||
DetailOptions.Edit => ResourcesKey.Edit,
|
||||
DetailOptions.Delete => ResourcesKey.Delete,
|
||||
_ => ResourcesKey.Unknown
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<div class="container">
|
||||
<div class="input-game">
|
||||
<div id="first-label" class="label">@ResourcesKey.Title :</div>
|
||||
<InputText class="title" @bind-Value=GameDto.Title/>
|
||||
<InputText class="title" @bind-Value=GameDto.Title/>
|
||||
</div>
|
||||
<div class="input-game">
|
||||
<div class="label">@ResourcesKey.ReleaseDate :</div>
|
||||
@@ -24,13 +24,13 @@
|
||||
<div class="input-game">
|
||||
<div class="label">@ResourcesKey.Developer :</div>
|
||||
<SelectSearch TItem="DeveloperDto" Theme="Theme" GetLabel="@(i => i.Name)" QuickAdd=true
|
||||
Items="Categories?.Developers" ValuesChanged="HandleDeveloperChanged"
|
||||
Items="Categories?.Developers" ValuesChanged="HandleDeveloperChanged" Values="@(GameDto.Developer != null ? [GameDto.Developer] : [])"
|
||||
AddItem="@(str => new DeveloperDto() { Name = str })" SelectType="SelectType.Single" />
|
||||
</div>
|
||||
<div class="input-game">
|
||||
<div class="label">@ResourcesKey.Publisher :</div>
|
||||
<SelectSearch TItem="PublisherDto" Theme="Theme" GetLabel="@(i => i.Name)" QuickAdd=true
|
||||
Items="Categories?.Publishers" ValuesChanged="HandlePublisherChanged"
|
||||
Items="Categories?.Publishers" ValuesChanged="HandlePublisherChanged" Values="@(GameDto.Publisher != null ? [GameDto.Publisher] : [])"
|
||||
AddItem="@(str => new PublisherDto() { Name = str })" SelectType="SelectType.Single" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -44,21 +44,21 @@
|
||||
<div class="input-game">
|
||||
<div class="label">@ResourcesKey.Properties :</div>
|
||||
<SelectSearch TItem="PropertyDto" Theme="Theme" GetLabel="@(i => i.Label)" QuickAdd=true
|
||||
Items="Categories?.Properties" @bind-Values=GameDto.Properties
|
||||
AddItem="@(str => new PropertyDto() { Label = str })" />
|
||||
Items="Categories?.Properties" @bind-Values=GameDto.Properties
|
||||
AddItem="@(str => new PropertyDto() { Label = str })" />
|
||||
</div>
|
||||
<div class="input-game">
|
||||
<div class="label">@ResourcesKey.Tags :</div>
|
||||
<SelectSearch TItem="TagDto" Theme="Theme" GetLabel="@(i => i.Label)" QuickAdd=true
|
||||
Items="Categories?.Tags" @bind-Values=GameDto.Tags
|
||||
AddItem="@(str => new TagDto() { Label = str })" />
|
||||
Items="Categories?.Tags" @bind-Values=GameDto.Tags
|
||||
AddItem="@(str => new TagDto() { Label = str })" />
|
||||
|
||||
</div>
|
||||
<div class="input-game">
|
||||
<div class="label">@ResourcesKey.Platforms :</div>
|
||||
<SelectSearch TItem="PlatformDto" Theme="Theme" GetLabel="@(i => i.Label)" QuickAdd=true
|
||||
Items="Categories?.Platforms" @bind-Values=GameDto.Platforms
|
||||
AddItem="@(str => new PlatformDto() { Label = str })" />
|
||||
Items="Categories?.Platforms" @bind-Values=GameDto.Platforms
|
||||
AddItem="@(str => new PlatformDto() { Label = str })" />
|
||||
</div>
|
||||
|
||||
@foreach (var platform in GameDto.Platforms ?? [])
|
||||
|
||||
@@ -3,6 +3,8 @@ using GameIdeas.BlazorApp.Pages.Games.Gateways;
|
||||
using GameIdeas.BlazorApp.Shared.Components.Popup;
|
||||
using GameIdeas.BlazorApp.Shared.Components.Select.Models;
|
||||
using GameIdeas.BlazorApp.Shared.Components.Slider;
|
||||
using GameIdeas.BlazorApp.Shared.Exceptions;
|
||||
using GameIdeas.Resources;
|
||||
using GameIdeas.Shared.Dto;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
@@ -19,22 +21,27 @@ public partial class GameCreationForm
|
||||
[CascadingParameter] private Popup? Popup { get; set; }
|
||||
[Parameter] public CategoriesDto? Categories { get; set; }
|
||||
[Parameter] public EventCallback OnSubmit { get; set; }
|
||||
|
||||
private readonly GameDetailDto GameDto = new();
|
||||
[Parameter] public EventCallback OnRender { get; set; }
|
||||
|
||||
private GameDetailDto GameDto = new();
|
||||
private EditContext? EditContext;
|
||||
private readonly SelectTheme Theme = SelectTheme.Creation;
|
||||
private readonly SliderParams SliderParams = new() { Gap = 1, Min = 1, Max = 5 };
|
||||
private bool IsLoading = false;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
EditContext = new(GameDto);
|
||||
await base.OnInitializedAsync();
|
||||
base.OnInitialized();
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
await Js.InvokeVoidAsync("resizeGameForm");
|
||||
if (firstRender)
|
||||
{
|
||||
await OnRender.InvokeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleOnCancel()
|
||||
@@ -53,15 +60,22 @@ public partial class GameCreationForm
|
||||
{
|
||||
IsLoading = true;
|
||||
|
||||
int gameId;
|
||||
var authState = await AuthenticationState.GetAuthenticationStateAsync();
|
||||
GameHelper.WriteTrackingDto(GameDto, authState);
|
||||
|
||||
var gameId = await GameGateway.CreateGame(GameDto);
|
||||
|
||||
if (gameId != 0)
|
||||
if (GameDto.Id != null)
|
||||
{
|
||||
Popup?.Close();
|
||||
await OnSubmit.InvokeAsync();
|
||||
gameId = await GameGateway.UpdateGame(GameDto);
|
||||
}
|
||||
else
|
||||
{
|
||||
gameId = await GameGateway.CreateGame(GameDto);
|
||||
}
|
||||
|
||||
if (gameId == 0)
|
||||
{
|
||||
throw new GameCreationException(ResourcesKey.ErrorCreateGame);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
@@ -73,13 +87,40 @@ public partial class GameCreationForm
|
||||
IsLoading = false;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
Popup?.Close();
|
||||
|
||||
await OnSubmit.InvokeAsync();
|
||||
}
|
||||
|
||||
private void HandlePublisherChanged(List<PublisherDto> pubs)
|
||||
{
|
||||
GameDto.Publisher = pubs.FirstOrDefault();
|
||||
}
|
||||
|
||||
private void HandleDeveloperChanged(List<DeveloperDto> devs)
|
||||
{
|
||||
GameDto.Developer = devs.FirstOrDefault();
|
||||
}
|
||||
|
||||
public async Task SetGameToUpdateAsync(int gameId)
|
||||
{
|
||||
try
|
||||
{
|
||||
IsLoading = true;
|
||||
|
||||
GameDto = await GameGateway.GetGameById(gameId);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new FetchGameDetailException(ResourcesKey.ErrorFetchDetail);
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsLoading = false;
|
||||
}
|
||||
|
||||
EditContext = new(GameDto);
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
@@ -118,3 +118,20 @@
|
||||
.buttons button:hover {
|
||||
background: var(--violet-selected);
|
||||
}
|
||||
|
||||
@media screen and (max-width: 400px) {
|
||||
.input-game {
|
||||
grid-template-columns: auto 1fr;
|
||||
}
|
||||
|
||||
#label-description {
|
||||
width: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 700px) {
|
||||
.game-form {
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
@using GameIdeas.BlazorApp.Helpers
|
||||
@using GameIdeas.BlazorApp.Shared.Components.Interest
|
||||
@using GameIdeas.BlazorApp.Shared.Components.Select
|
||||
@using GameIdeas.BlazorApp.Shared.Components.Select.Models
|
||||
@using GameIdeas.BlazorApp.Shared.Constants
|
||||
@inherits GameBase
|
||||
|
||||
@@ -33,5 +35,8 @@
|
||||
|
||||
<Interest Value="GameDto.Interest" />
|
||||
|
||||
<button class="detail">@Icons.Triangle</button>
|
||||
<Select @ref="SelectOption" TItem="DetailOptions" THeader="object" Type="SelectType.Single" Theme="SelectTheme.RowOption"
|
||||
Params="SelectParams" ValuesChanged="HandlerSelectValuesChanged">
|
||||
@Icons.Triangle
|
||||
</Select>
|
||||
</div>
|
||||
@@ -8,7 +8,6 @@
|
||||
box-shadow: var(--drop-shadow);
|
||||
border-radius: var(--big-radius);
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.row > * {
|
||||
@@ -69,17 +68,23 @@
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.detail {
|
||||
transform: scale(0.6, 1) rotate(-90deg);
|
||||
background: none;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
::deep .button {
|
||||
width: fit-content;
|
||||
transform: rotate(-90deg);
|
||||
transition: transform 0.2s ease-in-out;
|
||||
justify-self: center;
|
||||
}
|
||||
|
||||
::deep .detail svg {
|
||||
fill: var(--white);
|
||||
}
|
||||
::deep .button svg {
|
||||
fill: var(--white);
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
transform: scale(1, 0.6);
|
||||
}
|
||||
|
||||
::deep .button:hover, ::deep .button.selected {
|
||||
transform: translate(-4px, 2px);
|
||||
}
|
||||
|
||||
@media screen and (max-width: 700px) {
|
||||
.release-date, .tags, .storage {
|
||||
|
||||
Reference in New Issue
Block a user