diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Detail/GameDetail.razor.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Detail/GameDetail.razor.cs
index 6fc36a7..f5e8bfa 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Detail/GameDetail.razor.cs
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Detail/GameDetail.razor.cs
@@ -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; }
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Components/GameBase.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Components/GameBase.cs
index a04dd88..b5c9615 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Components/GameBase.cs
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Components/GameBase.cs
@@ -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);
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Games.razor b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Games.razor
index f64a2ae..4e85548 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Games.razor
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Games.razor
@@ -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)
{
-
+
}
}
else
@@ -43,3 +44,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Games.razor.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Games.razor.cs
index 73e72b5..2020cdf 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Games.razor.cs
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Games.razor.cs
@@ -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 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;
+ }
}
\ No newline at end of file
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Gateways/GameGateway.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Gateways/GameGateway.cs
index 12f57d2..79f4cef 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Gateways/GameGateway.cs
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Gateways/GameGateway.cs
@@ -76,4 +76,16 @@ public class GameGateway(IHttpClientService httpClientService) : IGameGateway
throw new CategoryNotFoundException(ResourcesKey.ErrorFetchGames);
}
}
+
+ public async Task DeleteGame(int gameIdToDelete)
+ {
+ try
+ {
+ return await httpClientService.DeleteAsync(Endpoints.Game.Delete(gameIdToDelete));
+ }
+ catch (Exception)
+ {
+ throw new GameDeletionException(ResourcesKey.ErrorDeleteGame);
+ }
+ }
}
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Gateways/IGameGateway.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Gateways/IGameGateway.cs
index 9bc4fc4..193852c 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Gateways/IGameGateway.cs
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Gateways/IGameGateway.cs
@@ -9,4 +9,5 @@ public interface IGameGateway
Task CreateGame(GameDetailDto game);
Task> FetchGames(GameFilterParams filter, int currentPage);
Task GetGameById(int gameId);
+ Task DeleteGame(int gameIdToDelete);
}
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Constants/Endpoints.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Constants/Endpoints.cs
index c16d19b..cbb8905 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Constants/Endpoints.cs
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Constants/Endpoints.cs
@@ -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
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Exceptions/GameDeletionException.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Exceptions/GameDeletionException.cs
new file mode 100644
index 0000000..50f5175
--- /dev/null
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Exceptions/GameDeletionException.cs
@@ -0,0 +1,3 @@
+namespace GameIdeas.BlazorApp.Shared.Exceptions;
+
+public class GameDeletionException(string message) : Exception(message);
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/wwwroot/css/app.css b/src/GameIdeas/Client/GameIdeas.BlazorApp/wwwroot/css/app.css
index c443f39..e3bf462 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/wwwroot/css/app.css
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/wwwroot/css/app.css
@@ -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;
diff --git a/src/GameIdeas/GameIdeas.Resources/CreateStaticResourceKey.cs b/src/GameIdeas/GameIdeas.Resources/CreateStaticResourceKey.cs
index c8f4b8e..6a39b08 100644
--- a/src/GameIdeas/GameIdeas.Resources/CreateStaticResourceKey.cs
+++ b/src/GameIdeas/GameIdeas.Resources/CreateStaticResourceKey.cs
@@ -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.");
diff --git a/src/GameIdeas/Server/GameIdeas.WebAPI/Files/GameIdeas.fr.json b/src/GameIdeas/Server/GameIdeas.WebAPI/Files/GameIdeas.fr.json
index 2c846b8..7c2b521 100644
--- a/src/GameIdeas/Server/GameIdeas.WebAPI/Files/GameIdeas.fr.json
+++ b/src/GameIdeas/Server/GameIdeas.WebAPI/Files/GameIdeas.fr.json
@@ -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"
}
\ No newline at end of file