Delete game
All checks were successful
Game Ideas build for PR / build_test (pull_request) Successful in 43s

This commit is contained in:
Maxime Adler
2025-05-12 13:08:23 +02:00
parent bb42aa6dc1
commit 14dc1928bc
11 changed files with 144 additions and 73 deletions

View File

@@ -1,10 +1,10 @@
using GameIdeas.BlazorApp.Pages.Games.Gateways; using GameIdeas.BlazorApp.Shared.Components;
using GameIdeas.Shared.Dto; using GameIdeas.Shared.Dto;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
namespace GameIdeas.BlazorApp.Pages.Detail; namespace GameIdeas.BlazorApp.Pages.Detail;
public partial class GameDetail public partial class GameDetail : GameBaseComponent
{ {
[Inject] private NavigationManager NavigationManager { get; set; } = default!; [Inject] private NavigationManager NavigationManager { get; set; } = default!;
[Parameter] public int GameId { get; set; } [Parameter] public int GameId { get; set; }

View File

@@ -29,7 +29,7 @@ public class GameBase : ComponentBase
switch (option) switch (option)
{ {
case DetailOptions.Detail: case DetailOptions.Detail:
NavigationManager.NavigateTo($"/Games/Detail/{GameDto.Id}"); NavigationManager.NavigateTo($"/Detail/{GameDto.Id}");
break; break;
case DetailOptions.Edit: case DetailOptions.Edit:
await OnEdit.InvokeAsync(GameDto); await OnEdit.InvokeAsync(GameDto);

View File

@@ -5,6 +5,7 @@
@using GameIdeas.BlazorApp.Shared.Components.ButtonAdd @using GameIdeas.BlazorApp.Shared.Components.ButtonAdd
@using GameIdeas.BlazorApp.Shared.Components.Header @using GameIdeas.BlazorApp.Shared.Components.Header
@using GameIdeas.BlazorApp.Shared.Components.Popup @using GameIdeas.BlazorApp.Shared.Components.Popup
@using GameIdeas.BlazorApp.Shared.Components.Popup.Components
@using GameIdeas.Resources @using GameIdeas.Resources
@inherits GameBaseComponent @inherits GameBaseComponent
@layout MainLayout @layout MainLayout
@@ -24,7 +25,7 @@
{ {
@foreach (var game in GamesDto) @foreach (var game in GamesDto)
{ {
<GameRow GameDto="game" /> <GameRow GameDto="game" OnDelete="HandleDeleteGame" OnEdit="HandleEditGame" />
} }
} }
else else
@@ -43,3 +44,7 @@
<Popup @ref=ManualAddPopup BackdropFilterClicked="HandleBackdropManualAddClicked" Closable=false> <Popup @ref=ManualAddPopup BackdropFilterClicked="HandleBackdropManualAddClicked" Closable=false>
<GameCreationForm Categories="Categories" OnSubmit="() => HandleFetchDatas()" /> <GameCreationForm Categories="Categories" OnSubmit="() => HandleFetchDatas()" />
</Popup> </Popup>
<Popup @ref=DeletePopup Closable=false>
<ConfirmDelete OnCancel="HandleCancelPopupClicked" OnConfirm="HandleRemoveGame" />
</Popup>

View File

@@ -1,5 +1,6 @@
using GameIdeas.BlazorApp.Pages.Games.Filter; using GameIdeas.BlazorApp.Pages.Games.Filter;
using GameIdeas.BlazorApp.Shared.Components; using GameIdeas.BlazorApp.Shared.Components;
using GameIdeas.BlazorApp.Shared.Components.Popup;
using GameIdeas.BlazorApp.Shared.Models; using GameIdeas.BlazorApp.Shared.Models;
using GameIdeas.Shared.Dto; using GameIdeas.Shared.Dto;
using GameIdeas.Shared.Enum; using GameIdeas.Shared.Enum;
@@ -12,6 +13,8 @@ public partial class Games : GameBaseComponent
private GameFilterParams GameFilter = new(); private GameFilterParams GameFilter = new();
private IEnumerable<GameDto> GamesDto = []; private IEnumerable<GameDto> GamesDto = [];
private int CurrentPage; private int CurrentPage;
private Popup? DeletePopup;
private GameDto? GameToDelete;
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
@@ -48,4 +51,46 @@ public partial class Games : GameBaseComponent
GameFilter = args; GameFilter = args;
await HandleFetchDatas(false); await HandleFetchDatas(false);
} }
private void HandleDeleteGame(GameDto args)
{
DeletePopup?.Open();
GameToDelete = args;
}
private void HandleCancelPopupClicked()
{
DeletePopup?.Close();
GameToDelete = null;
}
private Task HandleEditGame(GameDto args)
{
throw new NotImplementedException();
}
private async Task HandleRemoveGame()
{
DeletePopup?.Close();
if (GameToDelete?.Id == null)
{
return;
}
try
{
IsLoading = true;
await GameGateway.DeleteGame(GameToDelete?.Id ?? 0);
await HandleFetchDatas(false);
}
catch (Exception)
{
throw;
}
GameToDelete = null;
}
} }

View File

@@ -76,4 +76,16 @@ public class GameGateway(IHttpClientService httpClientService) : IGameGateway
throw new CategoryNotFoundException(ResourcesKey.ErrorFetchGames); throw new CategoryNotFoundException(ResourcesKey.ErrorFetchGames);
} }
} }
public async Task<bool> DeleteGame(int gameIdToDelete)
{
try
{
return await httpClientService.DeleteAsync<bool>(Endpoints.Game.Delete(gameIdToDelete));
}
catch (Exception)
{
throw new GameDeletionException(ResourcesKey.ErrorDeleteGame);
}
}
} }

View File

@@ -9,4 +9,5 @@ public interface IGameGateway
Task<int> CreateGame(GameDetailDto game); Task<int> CreateGame(GameDetailDto game);
Task<IEnumerable<GameDto>> FetchGames(GameFilterParams filter, int currentPage); Task<IEnumerable<GameDto>> FetchGames(GameFilterParams filter, int currentPage);
Task<GameDetailDto> GetGameById(int gameId); Task<GameDetailDto> GetGameById(int gameId);
Task<bool> DeleteGame(int gameIdToDelete);
} }

View File

@@ -10,6 +10,7 @@ public static class Endpoints
public const string Create = "api/Game/Create"; public const string Create = "api/Game/Create";
public static string Fetch(GameFilterDto filter) => $"api/Game?{UrlHelper.BuildUrlParams(filter)}"; public static string Fetch(GameFilterDto filter) => $"api/Game?{UrlHelper.BuildUrlParams(filter)}";
public static string FetchById(int gameId) => $"api/Game/{gameId}"; public static string FetchById(int gameId) => $"api/Game/{gameId}";
public static string Delete(int gameId) => $"api/Game/Delete/{gameId}";
} }
public static class Category public static class Category

View File

@@ -0,0 +1,3 @@
namespace GameIdeas.BlazorApp.Shared.Exceptions;
public class GameDeletionException(string message) : Exception(message);

View File

@@ -147,9 +147,10 @@ code {
.body-lg { .body-lg {
font-weight: 400; font-weight: 400;
font-size: 14px; font-size: 14px;
display: block;
} }
.header-1, .header-2, span, a { .header-1, .header-2 {
display: block; display: block;
color: var(--white); color: var(--white);
margin: 0; margin: 0;

View File

@@ -39,6 +39,7 @@ public class Translations (TranslationService translationService)
public string ErrorFetchCategories => translationService.Translate(nameof(ErrorFetchCategories)); public string ErrorFetchCategories => translationService.Translate(nameof(ErrorFetchCategories));
public string PlaceholderAdd => translationService.Translate(nameof(PlaceholderAdd)); public string PlaceholderAdd => translationService.Translate(nameof(PlaceholderAdd));
public string ErrorCreateGame => translationService.Translate(nameof(ErrorCreateGame)); public string ErrorCreateGame => translationService.Translate(nameof(ErrorCreateGame));
public string ErrorDeleteGame => translationService.Translate(nameof(ErrorDeleteGame));
public string InvalidTitle => translationService.Translate(nameof(InvalidTitle)); public string InvalidTitle => translationService.Translate(nameof(InvalidTitle));
public string InvalidInterest => translationService.Translate(nameof(InvalidInterest)); public string InvalidInterest => translationService.Translate(nameof(InvalidInterest));
public string Unknown => translationService.Translate(nameof(Unknown)); public string Unknown => translationService.Translate(nameof(Unknown));
@@ -118,6 +119,7 @@ public static class ResourcesKey
public static string ErrorFetchCategories => _instance?.ErrorFetchCategories ?? throw new InvalidOperationException("ResourcesKey.ErrorFetchCategories is not initialized."); public static string ErrorFetchCategories => _instance?.ErrorFetchCategories ?? throw new InvalidOperationException("ResourcesKey.ErrorFetchCategories is not initialized.");
public static string PlaceholderAdd => _instance?.PlaceholderAdd ?? throw new InvalidOperationException("ResourcesKey.PlaceholderAdd is not initialized."); public static string PlaceholderAdd => _instance?.PlaceholderAdd ?? throw new InvalidOperationException("ResourcesKey.PlaceholderAdd is not initialized.");
public static string ErrorCreateGame => _instance?.ErrorCreateGame ?? throw new InvalidOperationException("ResourcesKey.ErrorCreateGame is not initialized."); public static string ErrorCreateGame => _instance?.ErrorCreateGame ?? throw new InvalidOperationException("ResourcesKey.ErrorCreateGame is not initialized.");
public static string ErrorDeleteGame => _instance?.ErrorDeleteGame ?? throw new InvalidOperationException("ResourcesKey.ErrorDeleteGame is not initialized.");
public static string InvalidTitle => _instance?.InvalidTitle ?? throw new InvalidOperationException("ResourcesKey.InvalidTitle is not initialized."); public static string InvalidTitle => _instance?.InvalidTitle ?? throw new InvalidOperationException("ResourcesKey.InvalidTitle is not initialized.");
public static string InvalidInterest => _instance?.InvalidInterest ?? throw new InvalidOperationException("ResourcesKey.InvalidInterest is not initialized."); public static string InvalidInterest => _instance?.InvalidInterest ?? throw new InvalidOperationException("ResourcesKey.InvalidInterest is not initialized.");
public static string Unknown => _instance?.Unknown ?? throw new InvalidOperationException("ResourcesKey.Unknown is not initialized."); public static string Unknown => _instance?.Unknown ?? throw new InvalidOperationException("ResourcesKey.Unknown is not initialized.");

View File

@@ -35,6 +35,7 @@
"ErrorFetchCategories": "Erreur lors de la récupération des catégories", "ErrorFetchCategories": "Erreur lors de la récupération des catégories",
"PlaceholderAdd": "Ajouter un nouveau", "PlaceholderAdd": "Ajouter un nouveau",
"ErrorCreateGame": "Erreur lors de la création d'un jeu", "ErrorCreateGame": "Erreur lors de la création d'un jeu",
"ErrorDeleteGame": "Erreur lors de la suppression d'un jeu",
"InvalidTitle": "Le titre est incorrect", "InvalidTitle": "Le titre est incorrect",
"InvalidInterest": "L'interêt est incorrect", "InvalidInterest": "L'interêt est incorrect",
"Unknown": "Inconnu", "Unknown": "Inconnu",