Fetch games

This commit is contained in:
Maxime Adler
2025-04-16 14:52:43 +02:00
parent 6180be8ee7
commit c768c92397
14 changed files with 110 additions and 35 deletions

View File

@@ -13,14 +13,6 @@ public class GameBase : ComponentBase
NavigationManager.NavigateTo($"/Game/Detail/{GameDto.Id}");
}
protected void HandlePlatformClicked(PlatformDto platform)
{
if (platform.Url != null)
{
NavigationManager.NavigateTo(platform.Url);
}
}
protected string GetFormatedStorageSpace()
{
if (GameDto.StorageSpace == null)
@@ -28,15 +20,11 @@ public class GameBase : ComponentBase
return string.Empty;
}
int quotien = (int)Math.Round((decimal)GameDto.StorageSpace) / 1000;
string unit = quotien switch
return GameDto.StorageSpace switch
{
0 => "Mo",
1 => "Go",
2 => "To",
_ => string.Empty
> 1000000 => $"{GameDto.StorageSpace / 1000000:f1} To",
> 1000 => $"{GameDto.StorageSpace / 1000:f1} Go",
_ => $"{GameDto.StorageSpace:f1} Mo"
};
return $"{GameDto.StorageSpace % 1000:g1} {unit}";
}
}

View File

@@ -6,22 +6,22 @@
<span class="title">@GameDto.Title</span>
<span class="release-date">@GameDto.ReleaseDate?.ToShortDateString() ?? @ResourcesKey.Unknown</span>
<span class="release-date">@(GameDto.ReleaseDate?.ToShortDateString() ?? @ResourcesKey.Unknown)</span>
<div class="platforms">
@foreach (var platform in GameDto.Platforms ?? [])
{
<div class="platform-pill pill"
@onclick=@(_ => HandlePlatformClicked(platform))>
<a href="@platform.Url"
class="pill @(string.IsNullOrEmpty(platform.Url) ? "" : "platform-pill")">
@platform.Label
</div>
</a>
}
</div>
<div class="tags">
@foreach (var tag in GameDto.Tags ?? [])
{
<div class="tag-pill pill">
<div class="pill">
@tag.Label
</div>
}

View File

@@ -1 +1,39 @@

.row {
display: grid;
grid-template-columns: 48px 5fr 70px 2fr 3fr 60px 30px 30px;
text-wrap: nowrap;
height: 64px;
background: var(--input-secondary);
box-shadow: var(--drop-shadow);
border-radius: var(--big-radius);
overflow: hidden;
align-content: center;
align-items:center;
}
.title {
font-weight: bold;
}
.pill {
width: fit-content;
height: 24px;
padding: 0 6px;
background: rgb(255, 255, 255, 0.2);
border-radius: var(--small-radius);
align-content: center;
}
.platforms, .tags {
display: flex;
gap: 4px;
}
.platform-pill {
color: var(--violet);
cursor: pointer;
}
.platform-pill:hover {
text-decoration: underline;
}

View File

@@ -6,7 +6,7 @@
padding-left: 10px;
height: 100%;
box-sizing: border-box;
width: 240px;
width: 100%;
border-left: 2px solid var(--line);
z-index: var(--index-content);
}

View File

@@ -13,17 +13,21 @@
<GameHeader AddTypeChanged="HandleAddClicked">
<GameFilter Categories="Categories"
@bind-DisplayType=DisplayType
@bind-Value=GameFilter/>
@bind-DisplayType=DisplayType
@bind-Value=GameFilter/>
</GameHeader>
<div class="container">
<div class="content">
@foreach (var game in GamesDto)
{
<GameRow GameDto="game" />
}
</div>
<AdvancedGameFilter @bind-GameFilter=GameFilter Categories="Categories" />
</div>
<Popup @ref=ManualAddPopup BackdropFilterClicked="HandleBackdropManualAddClicked" Closable=false>
<GameCreationForm Categories="Categories" OnSubmit="HandleFetchCategories" />
<GameCreationForm Categories="Categories" OnSubmit="HandleFetchDatas" />
</Popup>

View File

@@ -3,6 +3,7 @@ using GameIdeas.BlazorApp.Shared.Components.Popup;
using GameIdeas.BlazorApp.Shared.Models;
using GameIdeas.Shared.Dto;
using Microsoft.AspNetCore.Components;
using System.Net.Http.Headers;
namespace GameIdeas.BlazorApp.Pages.Games;
@@ -13,11 +14,13 @@ public partial class Game
private DisplayType DisplayType = DisplayType.List;
private GameFilterDto GameFilter = new();
private Popup? ManualAddPopup;
private bool IsLoading;
private CategoriesDto? Categories;
private IEnumerable<GameDto> GamesDto = [];
protected override async Task OnInitializedAsync()
{
await HandleFetchCategories();
await HandleFetchDatas();
await base.OnInitializedAsync();
}
private void HandleAddClicked(AddType addType)
@@ -37,8 +40,22 @@ public partial class Game
{
ManualAddPopup?.Close();
}
private async Task HandleFetchCategories()
private async Task HandleFetchDatas()
{
Categories = await GameGateway.FetchCategories();
try
{
IsLoading = true;
Categories = await GameGateway.FetchCategories();
GamesDto = await GameGateway.FetchGames(new PaggingDto() { CurrentPage = 1, NumberPerPage = 50 });
}
catch (Exception)
{
throw;
}
finally
{
IsLoading = false;
}
}
}

View File

@@ -1,12 +1,15 @@
.container {
display: grid;
grid-template-columns: 1fr 240px;
margin-top: 20px;
margin-bottom: 10px;
justify-content: space-between;
display: flex;
flex-direction: row;
height: 100%;
}
.content {
z-index: var(--index-content);
margin: 0 20px;
display: flex;
flex-direction: column;
gap: 20px;
}

View File

@@ -33,4 +33,17 @@ public class GameGateway(IHttpClientService httpClientService) : IGameGateway
throw new CategoryNotFoundException(ResourcesKey.ErrorFetchCategories);
}
}
public async Task<IEnumerable<GameDto>> FetchGames(PaggingDto pagging)
{
try
{
var result = await httpClientService.FetchDataAsync<IEnumerable<GameDto>>(Endpoints.Game.Fetch(pagging));
return result ?? throw new InvalidOperationException(ResourcesKey.ErrorFetchGames);
}
catch (Exception)
{
throw new CategoryNotFoundException(ResourcesKey.ErrorFetchGames);
}
}
}

View File

@@ -6,4 +6,5 @@ public interface IGameGateway
{
Task<CategoriesDto> FetchCategories();
Task<int> CreateGame(GameDto game);
Task<IEnumerable<GameDto>> FetchGames(PaggingDto pagging);
}

View File

@@ -1,10 +1,14 @@
namespace GameIdeas.BlazorApp.Shared.Constants;
using GameIdeas.Shared.Dto;
namespace GameIdeas.BlazorApp.Shared.Constants;
public static class Endpoints
{
public static class Game
{
public static readonly string Create = "api/Game/Create";
public static string Fetch(PaggingDto pagging) =>
$"api/Game?{nameof(pagging.CurrentPage)}={pagging.CurrentPage}&{nameof(pagging.NumberPerPage)}={pagging.NumberPerPage}";
}
public static class Category

View File

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

View File

@@ -39,6 +39,7 @@ public class Translations (TranslationService translationService)
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 static class ResourcesKey
@@ -86,4 +87,5 @@ public static class ResourcesKey
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.");
}

View File

@@ -12,7 +12,7 @@ public class GameController(IGameService gameService, ILoggerFactory loggerFacto
private readonly ILogger<GameController> logger = loggerFactory.CreateLogger<GameController>();
[HttpGet]
public async Task<ActionResult<IEnumerable<GameDto>>> SearchGames([FromQuery] PaggingDto pagging)
public async Task<ActionResult<IEnumerable<GameDto>>> GetGames([FromQuery] PaggingDto pagging)
{
try
{

View File

@@ -34,5 +34,7 @@
"ErrorCreateGame": "Erreur lors de la Création d'un jeu",
"InvalidTitle": "Le titre est incorrect",
"InvalidInterest": "L'interêt est incorrect",
"Unknown": "Inconnu"
"Unknown": "Inconnu",
"ErrorFetchGames": "Erreur lors de la récupération des jeux"
}