diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Helpers/GameHelper.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Helpers/GameHelper.cs
index 27df03e..9778a14 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Helpers/GameHelper.cs
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Helpers/GameHelper.cs
@@ -20,6 +20,20 @@ public static class GameHelper
game.CreationDate = DateTime.Now;
}
+ public static void UpdateTrackingDto(GameDetailDto game, AuthenticationState authState)
+ {
+ if (authState == null)
+ {
+ throw new ArgumentNullException(nameof(authState), "Authentication state missing");
+ }
+
+ var userId = authState.User.FindFirstValue(ClaimTypes.Sid)
+ ?? throw new ArgumentNullException(nameof(authState), "user state missing");
+
+ game.ModificationUserId = userId;
+ game.ModificationDate = DateTime.Now;
+ }
+
public static string GetInterestColor(int interest, int maxInterest)
{
int firstTier = (int)Math.Floor(0.33 * maxInterest);
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 f5e8bfa..9e28609 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Detail/GameDetail.razor.cs
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Detail/GameDetail.razor.cs
@@ -1,6 +1,9 @@
using GameIdeas.BlazorApp.Shared.Components;
+using GameIdeas.BlazorApp.Shared.Exceptions;
+using GameIdeas.Resources;
using GameIdeas.Shared.Dto;
using Microsoft.AspNetCore.Components;
+using System.Linq.Expressions;
namespace GameIdeas.BlazorApp.Pages.Detail;
@@ -13,7 +16,7 @@ public partial class GameDetail : GameBaseComponent
protected override async Task OnInitializedAsync()
{
- Game = await GameGateway.GetGameById(GameId);
+ await FetchGameDetail();
await base.OnInitializedAsync();
}
@@ -21,4 +24,22 @@ public partial class GameDetail : GameBaseComponent
{
NavigationManager.NavigateTo("/");
}
+
+ private async Task FetchGameDetail()
+ {
+ try
+ {
+ IsLoading = true;
+
+ Game = await GameGateway.GetGameById(GameId);
+ }
+ catch (Exception)
+ {
+ throw new FetchGameDetailException(ResourcesKey.ErrorFetchDetail);
+ }
+ finally
+ {
+ IsLoading = false;
+ }
+ }
}
\ No newline at end of file
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Components/GameCreationForm.razor b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Components/GameCreationForm.razor
index c9e1028..95b05d1 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Components/GameCreationForm.razor
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Components/GameCreationForm.razor
@@ -11,7 +11,7 @@
-
+
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 2020cdf..f4f0d66 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Games.razor.cs
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Games.razor.cs
@@ -1,3 +1,4 @@
+using GameIdeas.BlazorApp.Pages.Games.Components;
using GameIdeas.BlazorApp.Pages.Games.Filter;
using GameIdeas.BlazorApp.Shared.Components;
using GameIdeas.BlazorApp.Shared.Components.Popup;
@@ -15,6 +16,7 @@ public partial class Games : GameBaseComponent
private int CurrentPage;
private Popup? DeletePopup;
private GameDto? GameToDelete;
+ private int? GameIdToUpdate;
protected override async Task OnInitializedAsync()
{
@@ -64,9 +66,16 @@ public partial class Games : GameBaseComponent
GameToDelete = null;
}
- private Task HandleEditGame(GameDto args)
+ private void HandleEditGame(GameDto args)
{
- throw new NotImplementedException();
+ if (args.Id == null)
+ {
+ return;
+ }
+
+ GameIdToUpdate = args.Id;
+
+ ManualAddPopup?.Open();
}
private async Task HandleRemoveGame()
@@ -87,7 +96,6 @@ public partial class Games : GameBaseComponent
}
catch (Exception)
{
-
throw;
}
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 79f4cef..0affe3f 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Gateways/GameGateway.cs
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Gateways/GameGateway.cs
@@ -88,4 +88,16 @@ public class GameGateway(IHttpClientService httpClientService) : IGameGateway
throw new GameDeletionException(ResourcesKey.ErrorDeleteGame);
}
}
+
+ public async Task UpdateGame(GameDetailDto gameDto)
+ {
+ try
+ {
+ return await httpClientService.PutAsync(Endpoints.Game.Update, gameDto);
+ }
+ catch (Exception)
+ {
+ throw new GameUpdateException(ResourcesKey.ErrorUpdateGame);
+ }
+ }
}
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 193852c..ac8cb99 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Gateways/IGameGateway.cs
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Gateways/IGameGateway.cs
@@ -10,4 +10,5 @@ public interface IGameGateway
Task> FetchGames(GameFilterParams filter, int currentPage);
Task GetGameById(int gameId);
Task DeleteGame(int gameIdToDelete);
+ Task UpdateGame(GameDetailDto gameDto);
}
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/GameBaseComponent.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/GameBaseComponent.cs
index c06b794..8839cdd 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/GameBaseComponent.cs
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/GameBaseComponent.cs
@@ -1,5 +1,4 @@
-using GameIdeas.BlazorApp.Pages.Games.Filter;
-using GameIdeas.BlazorApp.Pages.Games.Gateways;
+using GameIdeas.BlazorApp.Pages.Games.Gateways;
using GameIdeas.BlazorApp.Shared.Models;
using GameIdeas.Shared.Dto;
using Microsoft.AspNetCore.Components;
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Constants/Endpoints.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Constants/Endpoints.cs
index cbb8905..1447fb6 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Constants/Endpoints.cs
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Constants/Endpoints.cs
@@ -11,6 +11,7 @@ public static class Endpoints
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 const string Update = "api/Game/Update";
}
public static class Category
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Exceptions/FetchGameDetailException.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Exceptions/FetchGameDetailException.cs
new file mode 100644
index 0000000..94e49d5
--- /dev/null
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Exceptions/FetchGameDetailException.cs
@@ -0,0 +1,3 @@
+namespace GameIdeas.BlazorApp.Shared.Exceptions;
+
+public class FetchGameDetailException(string message) : Exception(message);
\ No newline at end of file
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Exceptions/GameUpdateException.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Exceptions/GameUpdateException.cs
new file mode 100644
index 0000000..628a3bb
--- /dev/null
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Exceptions/GameUpdateException.cs
@@ -0,0 +1,3 @@
+namespace GameIdeas.BlazorApp.Shared.Exceptions;
+
+public class GameUpdateException(string message) : Exception(message);
diff --git a/src/GameIdeas/GameIdeas.Resources/CreateStaticResourceKey.cs b/src/GameIdeas/GameIdeas.Resources/CreateStaticResourceKey.cs
index 6a39b08..59d4532 100644
--- a/src/GameIdeas/GameIdeas.Resources/CreateStaticResourceKey.cs
+++ b/src/GameIdeas/GameIdeas.Resources/CreateStaticResourceKey.cs
@@ -40,10 +40,12 @@ public class Translations (TranslationService translationService)
public string PlaceholderAdd => translationService.Translate(nameof(PlaceholderAdd));
public string ErrorCreateGame => translationService.Translate(nameof(ErrorCreateGame));
public string ErrorDeleteGame => translationService.Translate(nameof(ErrorDeleteGame));
+ public string ErrorUpdateGame => translationService.Translate(nameof(ErrorUpdateGame));
public string InvalidTitle => translationService.Translate(nameof(InvalidTitle));
public string InvalidInterest => translationService.Translate(nameof(InvalidInterest));
public string Unknown => translationService.Translate(nameof(Unknown));
public string ErrorFetchGames => translationService.Translate(nameof(ErrorFetchGames));
+ public string ErrorFetchDetail => translationService.Translate(nameof(ErrorFetchDetail));
public string Ascending => translationService.Translate(nameof(Ascending));
public string Descending => translationService.Translate(nameof(Descending));
public string ErrorStorageSpaceLabel => translationService.Translate(nameof(ErrorStorageSpaceLabel));
@@ -120,10 +122,12 @@ public static class ResourcesKey
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 ErrorUpdateGame => _instance?.ErrorUpdateGame ?? throw new InvalidOperationException("ResourcesKey.ErrorUpdateGame 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.");
public static string ErrorFetchGames => _instance?.ErrorFetchGames ?? throw new InvalidOperationException("ResourcesKey.ErrorFetchGames is not initialized.");
+ public static string ErrorFetchDetail => _instance?.ErrorFetchDetail ?? throw new InvalidOperationException("ResourcesKey.ErrorFetchDetail is not initialized.");
public static string Ascending => _instance?.Ascending ?? throw new InvalidOperationException("ResourcesKey.Ascending is not initialized.");
public static string Descending => _instance?.Descending ?? throw new InvalidOperationException("ResourcesKey.Descending is not initialized.");
public static string ErrorStorageSpaceLabel => _instance?.ErrorStorageSpaceLabel ?? throw new InvalidOperationException("ResourcesKey.ErrorStorageSpaceLabel 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 7c2b521..631c233 100644
--- a/src/GameIdeas/Server/GameIdeas.WebAPI/Files/GameIdeas.fr.json
+++ b/src/GameIdeas/Server/GameIdeas.WebAPI/Files/GameIdeas.fr.json
@@ -36,10 +36,12 @@
"PlaceholderAdd": "Ajouter un nouveau",
"ErrorCreateGame": "Erreur lors de la création d'un jeu",
"ErrorDeleteGame": "Erreur lors de la suppression d'un jeu",
+ "ErrorUpdateGame": "Erreur lors de la modification 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",
+ "ErrorFetchDetail": "Erreur lors de la récupération des détails d'un jeu",
"Ascending": "Ascendant",
"Descending": "Descendant",
"ErrorStorageSpaceLabel": "Erreur lors de la génération des label de l'espace de stockage",