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 Microsoft.AspNetCore.Components;
namespace GameIdeas.BlazorApp.Pages.Detail;
public partial class GameDetail
public partial class GameDetail : GameBaseComponent
{
[Inject] private NavigationManager NavigationManager { get; set; } = default!;
[Parameter] public int GameId { get; set; }

View File

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

View File

@@ -5,6 +5,7 @@
@using GameIdeas.BlazorApp.Shared.Components.ButtonAdd
@using GameIdeas.BlazorApp.Shared.Components.Header
@using GameIdeas.BlazorApp.Shared.Components.Popup
@using GameIdeas.BlazorApp.Shared.Components.Popup.Components
@using GameIdeas.Resources
@inherits GameBaseComponent
@layout MainLayout
@@ -24,7 +25,7 @@
{
@foreach (var game in GamesDto)
{
<GameRow GameDto="game" />
<GameRow GameDto="game" OnDelete="HandleDeleteGame" OnEdit="HandleEditGame" />
}
}
else
@@ -43,3 +44,7 @@
<Popup @ref=ManualAddPopup BackdropFilterClicked="HandleBackdropManualAddClicked" Closable=false>
<GameCreationForm Categories="Categories" OnSubmit="() => HandleFetchDatas()" />
</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.Shared.Components;
using GameIdeas.BlazorApp.Shared.Components.Popup;
using GameIdeas.BlazorApp.Shared.Models;
using GameIdeas.Shared.Dto;
using GameIdeas.Shared.Enum;
@@ -12,6 +13,8 @@ public partial class Games : GameBaseComponent
private GameFilterParams GameFilter = new();
private IEnumerable<GameDto> GamesDto = [];
private int CurrentPage;
private Popup? DeletePopup;
private GameDto? GameToDelete;
protected override async Task OnInitializedAsync()
{
@@ -48,4 +51,46 @@ public partial class Games : GameBaseComponent
GameFilter = args;
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);
}
}
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<IEnumerable<GameDto>> FetchGames(GameFilterParams filter, int currentPage);
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 static string Fetch(GameFilterDto filter) => $"api/Game?{UrlHelper.BuildUrlParams(filter)}";
public static string FetchById(int gameId) => $"api/Game/{gameId}";
public static string Delete(int gameId) => $"api/Game/Delete/{gameId}";
}
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 {
font-weight: 400;
font-size: 14px;
display: block;
}
.header-1, .header-2, span, a {
.header-1, .header-2 {
display: block;
color: var(--white);
margin: 0;

View File

@@ -39,6 +39,7 @@ public class Translations (TranslationService translationService)
public string ErrorFetchCategories => translationService.Translate(nameof(ErrorFetchCategories));
public string PlaceholderAdd => translationService.Translate(nameof(PlaceholderAdd));
public string ErrorCreateGame => translationService.Translate(nameof(ErrorCreateGame));
public string ErrorDeleteGame => translationService.Translate(nameof(ErrorDeleteGame));
public string InvalidTitle => translationService.Translate(nameof(InvalidTitle));
public string InvalidInterest => translationService.Translate(nameof(InvalidInterest));
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 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 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 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.");

View File

@@ -1,70 +1,71 @@
{
"GamesIdeas": "Game Ideas",
"ManualAdd": "Manuel",
"AutoAdd": "Automatique",
"Login": "Se connecter",
"Logout": "Se déconnecter",
"EnterUsername": "Nom d'utilisateur",
"EnterPassword": "Mot de passe",
"UserManager": "Gestion des utilisateurs",
"CategoriesManager": "Gestion des catégories",
"Filters": "Les filtres",
"LastAdd": "Les ajouts récents",
"Research": "Rechercher",
"Platforms": "Plateformes",
"Tags": "Genres",
"Publisher": "Editeur",
"Developer": "Développeur",
"StorageSize": "Taille d'espace",
"StorageSizeMo": "Taille d'espace en Mo",
"LastModification": "Dernière modifications",
"ReleaseDate": "Date de parution",
"CreateDate": "Date de création",
"UpdateDate": "Date de modification",
"Title": "Titre",
"Interest": "Intérêt",
"Properties": "Propriétés",
"Description": "Description",
"Save": "Enregister",
"Reset": "Annuler",
"ErrorWhenPostingData": "Erreur lors de la requête POST",
"ErrorWhenPutingData": "Erreur lors de la requête PUT",
"ErrorWhenDeletingData": "Erreur lors de la requête DELETE",
"ErrorWhenFetchingData": "Erreur lors de la requête GET",
"RequestFailedStatusFormat": "Erreur lors de la réponse, code {0}",
"ErrorFetchCategories": "Erreur lors de la récupération des catégories",
"PlaceholderAdd": "Ajouter un nouveau",
"ErrorCreateGame": "Erreur lors de la création d'un jeu",
"InvalidTitle": "Le titre est incorrect",
"InvalidInterest": "L'interêt est incorrect",
"Unknown": "Inconnu",
"ErrorFetchGames": "Erreur lors de la récupération des jeux",
"Ascending": "Ascendant",
"Descending": "Descendant",
"ErrorStorageSpaceLabel": "Erreur lors de la génération des label de l'espace de stockage",
"MinStorageSpaceFormat": "Jusqu'à {0}",
"MaxStorageSpaceFormat": "Plus de {0}",
"MinMaxStorageSpaceFormat": "{0} à {1}",
"UserArgumentsNull": "Nom d'utilisateur ou mot de passe invalide",
"InvalidToken": "Le token JWT est invalide",
"UserUnauthorized": "Utilisateur non authorisé",
"UserLoginFailed": "Authentification de l'utilisateur échoué",
"UserLogoutFailed": "Déconnection de l'utilisateur échoué",
"Roles": "Rôles",
"ErrorFetchUsers": "Erreur lors de la récupération des utilisateurs",
"ErrorFetchRoles": "Erreur lors de la récupération des rôles",
"MissingField": "Un champs est manquant",
"ErrorCreateUser": "Erreur lors de la création d'un utilisateur",
"ErrorUpdateUser": "Erreur lors de la mise à jour d'un utilisateur",
"ErrorDeleteUser": "Erreur lors de la suppression d'un utilisateur",
"Cancel": "Annuler",
"Confirm": "Confirmer",
"ConfirmDeleteDescription": "Êtes-vous sur de vouloir supprimer cet élément ?",
"Informations": "Informations",
"About": "À propos",
"ReadMore": "Afficher",
"ReadLess": "Réduire",
"Detail": "Détail",
"Edit": "Modifier",
"Delete": "Supprimer"
"GamesIdeas": "Game Ideas",
"ManualAdd": "Manuel",
"AutoAdd": "Automatique",
"Login": "Se connecter",
"Logout": "Se déconnecter",
"EnterUsername": "Nom d'utilisateur",
"EnterPassword": "Mot de passe",
"UserManager": "Gestion des utilisateurs",
"CategoriesManager": "Gestion des catégories",
"Filters": "Les filtres",
"LastAdd": "Les ajouts récents",
"Research": "Rechercher",
"Platforms": "Plateformes",
"Tags": "Genres",
"Publisher": "Editeur",
"Developer": "Développeur",
"StorageSize": "Taille d'espace",
"StorageSizeMo": "Taille d'espace en Mo",
"LastModification": "Dernière modifications",
"ReleaseDate": "Date de parution",
"CreateDate": "Date de création",
"UpdateDate": "Date de modification",
"Title": "Titre",
"Interest": "Intérêt",
"Properties": "Propriétés",
"Description": "Description",
"Save": "Enregister",
"Reset": "Annuler",
"ErrorWhenPostingData": "Erreur lors de la requête POST",
"ErrorWhenPutingData": "Erreur lors de la requête PUT",
"ErrorWhenDeletingData": "Erreur lors de la requête DELETE",
"ErrorWhenFetchingData": "Erreur lors de la requête GET",
"RequestFailedStatusFormat": "Erreur lors de la réponse, code {0}",
"ErrorFetchCategories": "Erreur lors de la récupération des catégories",
"PlaceholderAdd": "Ajouter un nouveau",
"ErrorCreateGame": "Erreur lors de la création d'un jeu",
"ErrorDeleteGame": "Erreur lors de la suppression d'un jeu",
"InvalidTitle": "Le titre est incorrect",
"InvalidInterest": "L'interêt est incorrect",
"Unknown": "Inconnu",
"ErrorFetchGames": "Erreur lors de la récupération des jeux",
"Ascending": "Ascendant",
"Descending": "Descendant",
"ErrorStorageSpaceLabel": "Erreur lors de la génération des label de l'espace de stockage",
"MinStorageSpaceFormat": "Jusqu'à {0}",
"MaxStorageSpaceFormat": "Plus de {0}",
"MinMaxStorageSpaceFormat": "{0} à {1}",
"UserArgumentsNull": "Nom d'utilisateur ou mot de passe invalide",
"InvalidToken": "Le token JWT est invalide",
"UserUnauthorized": "Utilisateur non authorisé",
"UserLoginFailed": "Authentification de l'utilisateur échoué",
"UserLogoutFailed": "Déconnection de l'utilisateur échoué",
"Roles": "Rôles",
"ErrorFetchUsers": "Erreur lors de la récupération des utilisateurs",
"ErrorFetchRoles": "Erreur lors de la récupération des rôles",
"MissingField": "Un champs est manquant",
"ErrorCreateUser": "Erreur lors de la création d'un utilisateur",
"ErrorUpdateUser": "Erreur lors de la mise à jour d'un utilisateur",
"ErrorDeleteUser": "Erreur lors de la suppression d'un utilisateur",
"Cancel": "Annuler",
"Confirm": "Confirmer",
"ConfirmDeleteDescription": "Êtes-vous sur de vouloir supprimer cet élément ?",
"Informations": "Informations",
"About": "À propos",
"ReadMore": "Afficher",
"ReadLess": "Réduire",
"Detail": "Détail",
"Edit": "Modifier",
"Delete": "Supprimer"
}