Create game from form (#15)
Co-authored-by: Maxime Adler <madler@sqli.com> Reviewed-on: #15
This commit was merged in pull request #15.
This commit is contained in:
@@ -0,0 +1,12 @@
|
|||||||
|
using GameIdeas.Shared.Dto;
|
||||||
|
|
||||||
|
namespace GameIdeas.BlazorApp.Helpers;
|
||||||
|
|
||||||
|
public static class GameHelper
|
||||||
|
{
|
||||||
|
public static void WriteTrackingDto(GameDto game)
|
||||||
|
{
|
||||||
|
game.CreationUserId = 100000;
|
||||||
|
game.CreationDate = DateTime.Now;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,31 +1,36 @@
|
|||||||
@using GameIdeas.BlazorApp.Shared.Components.SelectSearch
|
@using Blazored.FluentValidation
|
||||||
|
@using GameIdeas.BlazorApp.Shared.Components.CircleLoader
|
||||||
|
@using GameIdeas.BlazorApp.Shared.Components.SelectSearch
|
||||||
@using GameIdeas.BlazorApp.Shared.Components.Slider
|
@using GameIdeas.BlazorApp.Shared.Components.Slider
|
||||||
@using GameIdeas.Shared.Dto
|
@using GameIdeas.Shared.Dto
|
||||||
|
|
||||||
<EditForm EditContext="EditContext" OnSubmit="HandleOnSubmit">
|
<EditForm EditContext="EditContext" OnSubmit="HandleOnSubmit">
|
||||||
|
<FluentValidationValidator/>
|
||||||
<div class="game-form">
|
<div class="game-form">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="input-game">
|
<div class="input-game">
|
||||||
<div id="first-label" class="label">@ResourcesKey.Title :</div>
|
<div id="first-label" class="label">@ResourcesKey.Title :</div>
|
||||||
<input type="text" class="title" @bind=GameDto.Title>
|
<InputText class="title" @bind-Value=GameDto.Title/>
|
||||||
</div>
|
</div>
|
||||||
<div class="input-game">
|
<div class="input-game">
|
||||||
<div class="label">@ResourcesKey.ReleaseDate :</div>
|
<div class="label">@ResourcesKey.ReleaseDate :</div>
|
||||||
<input type="date" class="date" @bind=GameDto.ReleaseDate>
|
<InputDate TValue="DateTime?" class="date" @bind-Value=GameDto.ReleaseDate />
|
||||||
</div>
|
</div>
|
||||||
<div class="input-game">
|
<div class="input-game">
|
||||||
<div class="label">@ResourcesKey.StorageSizeMo :</div>
|
<div class="label">@ResourcesKey.StorageSizeMo :</div>
|
||||||
<input type="number" class="storage" @bind=GameDto.StorageSpace>
|
<InputNumber TValue="double?" class="storage" @bind-Value=GameDto.StorageSpace />
|
||||||
</div>
|
</div>
|
||||||
<div class="input-game">
|
<div class="input-game">
|
||||||
<div class="label">@ResourcesKey.Developers :</div>
|
<div class="label">@ResourcesKey.Developers :</div>
|
||||||
<SelectSearch TItem="DeveloperDto" Theme="Theme" GetLabel="@(i => i.Name)"
|
<SelectSearch TItem="DeveloperDto" Theme="Theme" GetLabel="@(i => i.Name)" QuickAdd=true
|
||||||
Items="Categories?.Developers" @bind-Values=GameDto.Developers />
|
Items="Categories?.Developers" @bind-Values=GameDto.Developers
|
||||||
|
AddItem="@(str => new DeveloperDto() { Name = str })" />
|
||||||
</div>
|
</div>
|
||||||
<div class="input-game">
|
<div class="input-game">
|
||||||
<div class="label">@ResourcesKey.Publishers :</div>
|
<div class="label">@ResourcesKey.Publishers :</div>
|
||||||
<SelectSearch TItem="PublisherDto" Theme="Theme" GetLabel="@(i => i.Name)"
|
<SelectSearch TItem="PublisherDto" Theme="Theme" GetLabel="@(i => i.Name)" QuickAdd=true
|
||||||
Items="Categories?.Publishers" @bind-Values=GameDto.Publishers />
|
Items="Categories?.Publishers" @bind-Values=GameDto.Publishers
|
||||||
|
AddItem="@(str => new PublisherDto() { Name = str })" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@@ -37,32 +42,52 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="input-game">
|
<div class="input-game">
|
||||||
<div class="label">@ResourcesKey.Properties :</div>
|
<div class="label">@ResourcesKey.Properties :</div>
|
||||||
<SelectSearch TItem="PropertyDto" Theme="Theme" GetLabel="@(i => i.Label)"
|
<SelectSearch TItem="PropertyDto" Theme="Theme" GetLabel="@(i => i.Label)" QuickAdd=true
|
||||||
Items="Categories?.Properties" @bind-Values=GameDto.Properties />
|
Items="Categories?.Properties" @bind-Values=GameDto.Properties
|
||||||
|
AddItem="@(str => new PropertyDto() { Label = str })" />
|
||||||
</div>
|
</div>
|
||||||
<div class="input-game">
|
<div class="input-game">
|
||||||
<div class="label">@ResourcesKey.Tags :</div>
|
<div class="label">@ResourcesKey.Tags :</div>
|
||||||
<SelectSearch TItem="TagDto" Theme="Theme" GetLabel="@(i => i.Label)"
|
<SelectSearch TItem="TagDto" Theme="Theme" GetLabel="@(i => i.Label)" QuickAdd=true
|
||||||
Items="Categories?.Tags" @bind-Values=GameDto.Tags />
|
Items="Categories?.Tags" @bind-Values=GameDto.Tags
|
||||||
|
AddItem="@(str => new TagDto() { Label = str })" />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="input-game">
|
<div class="input-game">
|
||||||
<div class="label">@ResourcesKey.Platforms :</div>
|
<div class="label">@ResourcesKey.Platforms :</div>
|
||||||
<SelectSearch TItem="PlatformDto" Theme="Theme" GetLabel="@(i => i.Label)"
|
<SelectSearch TItem="PlatformDto" Theme="Theme" GetLabel="@(i => i.Label)" QuickAdd=true
|
||||||
Items="Categories?.Platforms" @bind-Values=GameDto.Platforms />
|
Items="Categories?.Platforms" @bind-Values=GameDto.Platforms
|
||||||
|
AddItem="@(str => new PlatformDto() { Label = str })" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@foreach (var platform in GameDto.Platforms ?? [])
|
||||||
|
{
|
||||||
|
<div class="input-game">
|
||||||
|
<div class="label">@platform.Label :</div>
|
||||||
|
<InputText class="url" @bind-Value=platform.Url />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="description-container">
|
<div class="description-container">
|
||||||
<div id="label-description">@ResourcesKey.Description :</div>
|
<div id="label-description">@ResourcesKey.Description :</div>
|
||||||
<input type="text" class="description" @bind-value=GameDto.Description>
|
<InputTextArea class="description" @bind-Value=GameDto.Description />
|
||||||
</div>
|
</div>
|
||||||
<div class="buttons">
|
<div class="bottom-container">
|
||||||
<button type="reset" class="cancel" @onclick=HandleOnCancel>
|
<ValidationSummary class="invalid-content" />
|
||||||
@ResourcesKey.Reset
|
|
||||||
</button>
|
<div class="buttons">
|
||||||
<button type="submit" class="submit">
|
<button type="reset" class="cancel" @onclick=HandleOnCancel disabled="@IsLoading">
|
||||||
@ResourcesKey.Save
|
@ResourcesKey.Reset
|
||||||
</button>
|
</button>
|
||||||
|
<button type="submit" class="submit" disabled="@IsLoading">
|
||||||
|
@ResourcesKey.Save
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</EditForm>
|
</EditForm>
|
||||||
|
|
||||||
|
@if (IsLoading)
|
||||||
|
{
|
||||||
|
<CircleLoader />
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using GameIdeas.BlazorApp.Helpers;
|
||||||
|
using GameIdeas.BlazorApp.Pages.Games.Gateways;
|
||||||
using GameIdeas.BlazorApp.Shared.Components.Popup;
|
using GameIdeas.BlazorApp.Shared.Components.Popup;
|
||||||
using GameIdeas.BlazorApp.Shared.Components.Select.Models;
|
using GameIdeas.BlazorApp.Shared.Components.Select.Models;
|
||||||
using GameIdeas.BlazorApp.Shared.Components.Slider;
|
using GameIdeas.BlazorApp.Shared.Components.Slider;
|
||||||
@@ -11,29 +13,27 @@ namespace GameIdeas.BlazorApp.Pages.Games.Components;
|
|||||||
public partial class GameCreationForm
|
public partial class GameCreationForm
|
||||||
{
|
{
|
||||||
[Inject] private IJSRuntime Js { get; set; } = default!;
|
[Inject] private IJSRuntime Js { get; set; } = default!;
|
||||||
|
[Inject] private IGameGateway GameGateway { get; set; } = default!;
|
||||||
[CascadingParameter] private Popup? Popup { get; set; }
|
[CascadingParameter] private Popup? Popup { get; set; }
|
||||||
[Parameter] public CategoriesDto? Categories { get; set; }
|
[Parameter] public CategoriesDto? Categories { get; set; }
|
||||||
|
[Parameter] public EventCallback OnSubmit { get; set; }
|
||||||
|
|
||||||
private GameDto GameDto = new();
|
private GameDto GameDto = new();
|
||||||
private EditContext? EditContext;
|
private EditContext? EditContext;
|
||||||
private readonly SelectTheme Theme = SelectTheme.Creation;
|
private readonly SelectTheme Theme = SelectTheme.Creation;
|
||||||
private readonly SliderParams SliderParams = new() { Gap = 1, Min = 1, Max = 5 };
|
private readonly SliderParams SliderParams = new() { Gap = 1, Min = 1, Max = 5 };
|
||||||
|
private bool IsLoading = false;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
EditContext = new(GameDto);
|
EditContext = new(GameDto);
|
||||||
|
|
||||||
if (Popup != null)
|
|
||||||
{
|
|
||||||
Popup.StateChanged += async (_, isOpen) => await HandlePopupStateChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
await base.OnInitializedAsync();
|
await base.OnInitializedAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task HandlePopupStateChanged()
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
{
|
{
|
||||||
await Js.InvokeVoidAsync("resizeGameForm");
|
await Js.InvokeVoidAsync("resizeGameForm");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleOnCancel()
|
private void HandleOnCancel()
|
||||||
@@ -48,6 +48,26 @@ public partial class GameCreationForm
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IsLoading = true;
|
||||||
|
|
||||||
|
GameHelper.WriteTrackingDto(GameDto);
|
||||||
|
var gameId = await GameGateway.CreateGame(GameDto);
|
||||||
|
|
||||||
|
if (gameId != 0)
|
||||||
|
{
|
||||||
|
Popup?.Close();
|
||||||
|
await OnSubmit.InvokeAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IsLoading = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
.game-form {
|
.game-form {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,7 +25,7 @@
|
|||||||
grid-column: 1;
|
grid-column: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
::deep input, ::deep textarea {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: var(--input-secondary);
|
background: var(--input-secondary);
|
||||||
border: solid 1px var(--input-selected);
|
border: solid 1px var(--input-selected);
|
||||||
@@ -35,10 +36,19 @@ input {
|
|||||||
color: var(--white);
|
color: var(--white);
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="date"]::-webkit-calendar-picker-indicator {
|
::deep input[type="date"]::-webkit-calendar-picker-indicator {
|
||||||
filter: invert(1);
|
filter: invert(1);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::deep input[type="number"]::-webkit-inner-spin-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
::deep textarea {
|
||||||
|
resize: vertical;
|
||||||
|
min-height: 140px;
|
||||||
|
}
|
||||||
|
|
||||||
.description-container {
|
.description-container {
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
@@ -63,6 +73,48 @@ input {
|
|||||||
align-content: center;
|
align-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="number"]::-webkit-inner-spin-button {
|
.bottom-container {
|
||||||
-webkit-appearance: none;
|
margin-top: 8px;
|
||||||
|
height: 28px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
::deep .invalid-content {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
flex-shrink: 1;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
height: auto;
|
||||||
|
text-wrap: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
::deep .invalid-content li {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttons {
|
||||||
|
margin-left: auto;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttons button {
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
background: var(--violet);
|
||||||
|
border-radius: var(--small-radius);
|
||||||
|
color: var(--white);
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 0 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttons button:hover {
|
||||||
|
background: var(--violet-selected);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using FluentValidation;
|
||||||
|
using GameIdeas.Resources;
|
||||||
|
using GameIdeas.Shared.Dto;
|
||||||
|
|
||||||
|
namespace GameIdeas.BlazorApp.Pages.Games.Components;
|
||||||
|
|
||||||
|
public class GameValidation : AbstractValidator<GameDto>
|
||||||
|
{
|
||||||
|
public GameValidation()
|
||||||
|
{
|
||||||
|
RuleFor(g => g.Title)
|
||||||
|
.NotEmpty().WithMessage(ResourcesKey.InvalidTitle);
|
||||||
|
|
||||||
|
RuleFor(g => g.Interest)
|
||||||
|
.GreaterThanOrEqualTo(1).WithMessage(ResourcesKey.InvalidInterest)
|
||||||
|
.LessThanOrEqualTo(5).WithMessage(ResourcesKey.InvalidInterest);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,10 +36,10 @@ public partial class GameFilter
|
|||||||
{
|
{
|
||||||
Headers = SortTypes,
|
Headers = SortTypes,
|
||||||
GetHeaderLabel = header => header.Label,
|
GetHeaderLabel = header => header.Label,
|
||||||
DefaultHeader = SortTypes.FirstOrDefault(h => h.SortType == SortType.Ascending),
|
DefaultHeaders = SortTypes.Where(h => h.SortType == SortType.Ascending).ToList(),
|
||||||
Items = GameProperties,
|
Items = GameProperties,
|
||||||
GetItemLabel = item => item.Label,
|
GetItemLabel = item => item.Label,
|
||||||
DefaultItem = GameProperties.FirstOrDefault(p => p.Label == "Titre")
|
DefaultItems = GameProperties.Where(p => p.Label == "Titre").ToList()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,6 @@
|
|||||||
<AdvancedGameFilter @bind-GameFilter=GameFilter Categories="Categories" />
|
<AdvancedGameFilter @bind-GameFilter=GameFilter Categories="Categories" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Popup @ref=ManualAddPopup BackdropFilterClicked="HandleBackdropManualAddClicked">
|
<Popup @ref=ManualAddPopup BackdropFilterClicked="HandleBackdropManualAddClicked" Closable=false>
|
||||||
<GameCreationForm Categories="Categories" />
|
<GameCreationForm Categories="Categories" OnSubmit="HandleFetchCategories" />
|
||||||
</Popup>
|
</Popup>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public partial class GameBase ()
|
|||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
Categories = await GameGateway.FetchCategories();
|
await HandleFetchCategories();
|
||||||
await base.OnInitializedAsync();
|
await base.OnInitializedAsync();
|
||||||
}
|
}
|
||||||
private void HandleAddClicked(AddType addType)
|
private void HandleAddClicked(AddType addType)
|
||||||
@@ -37,4 +37,8 @@ public partial class GameBase ()
|
|||||||
{
|
{
|
||||||
ManualAddPopup?.Close();
|
ManualAddPopup?.Close();
|
||||||
}
|
}
|
||||||
|
private async Task HandleFetchCategories()
|
||||||
|
{
|
||||||
|
Categories = await GameGateway.FetchCategories();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,18 @@ namespace GameIdeas.BlazorApp.Pages.Games.Gateways;
|
|||||||
|
|
||||||
public class GameGateway(IHttpClientService httpClientService) : IGameGateway
|
public class GameGateway(IHttpClientService httpClientService) : IGameGateway
|
||||||
{
|
{
|
||||||
|
public async Task<int> CreateGame(GameDto game)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await httpClientService.PostAsync<int>(Endpoints.Game.Create, game);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw new GameCreationException(ResourcesKey.ErrorCreateGame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<CategoriesDto> FetchCategories()
|
public async Task<CategoriesDto> FetchCategories()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -5,4 +5,5 @@ namespace GameIdeas.BlazorApp.Pages.Games.Gateways;
|
|||||||
public interface IGameGateway
|
public interface IGameGateway
|
||||||
{
|
{
|
||||||
Task<CategoriesDto> FetchCategories();
|
Task<CategoriesDto> FetchCategories();
|
||||||
|
Task<int> CreateGame(GameDto game);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<Select @ref="SelectListAdd" TItem="KeyValuePair<AddType, string>" THeader="object"
|
<Select @ref="SelectListAdd" TItem="KeyValuePair<AddType, string>" THeader="object"
|
||||||
ValuesChanged=HandleAddTypeClicked Params=SelectParams
|
ValuesChanged=HandleAddTypeClicked Params=SelectParams Theme="SelectTheme.Navigation">
|
||||||
Theme="SelectTheme.Navigation">
|
|
||||||
<div class="second-button button">
|
<div class="second-button button">
|
||||||
<svg class="button-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
<svg class="button-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||||
<path d="M1 3H23L12 22" />
|
<path d="M1 3H23L12 22" />
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ public partial class GameHeader : ComponentBase
|
|||||||
{
|
{
|
||||||
Items = AddTypes.ToList(),
|
Items = AddTypes.ToList(),
|
||||||
GetItemLabel = item => item.Value,
|
GetItemLabel = item => item.Value,
|
||||||
|
DefaultItems = []
|
||||||
};
|
};
|
||||||
|
|
||||||
base.OnInitialized();
|
base.OnInitialized();
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
.backdrop-filter {
|
.backdrop-filter {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
z-index: var(--index-backdrop);
|
z-index: var(--index-backdrop);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<div class="overlay"> <div class="loader"></div> </div>
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
.overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: var(--overlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
border: 8px solid var(--violet-selected);
|
||||||
|
border-top: 8px solid var(--violet);
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,17 +2,20 @@
|
|||||||
@using GameIdeas.BlazorApp.Shared.Constants
|
@using GameIdeas.BlazorApp.Shared.Constants
|
||||||
|
|
||||||
<CascadingValue Value="this">
|
<CascadingValue Value="this">
|
||||||
<div class="popup-wrapper" style="@GetDisplayStyle()">
|
@if (IsOpen)
|
||||||
<div class="popup-content">
|
{
|
||||||
@if (Closable)
|
<div class="popup-wrapper">
|
||||||
{
|
<div class="popup-content">
|
||||||
<button @onclick="HandleBackdropFilterClicked">@Icons.Shared.Close</button>
|
@if (Closable)
|
||||||
}
|
{
|
||||||
@ChildContent
|
<button @onclick="HandleBackdropFilterClicked">@Icons.Shared.Close</button>
|
||||||
|
}
|
||||||
|
@ChildContent
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
}
|
||||||
</CascadingValue>
|
</CascadingValue>
|
||||||
|
|
||||||
|
|
||||||
<BackdropFilter @ref="BackdropFilter" OnClick="HandleBackdropFilterClicked" CloseOnClick="@Closable"
|
<BackdropFilter @ref="BackdropFilter" OnClick="HandleBackdropFilterClicked" CloseOnClick="@Closable"
|
||||||
AllowBodyScroll="false" Color="BackdropFilterColor.Overlay" />
|
AllowBodyScroll="true" Color="BackdropFilterColor.Overlay" />
|
||||||
@@ -5,11 +5,9 @@ namespace GameIdeas.BlazorApp.Shared.Components.Popup;
|
|||||||
public partial class Popup
|
public partial class Popup
|
||||||
{
|
{
|
||||||
[Parameter] public RenderFragment? ChildContent { get; set; }
|
[Parameter] public RenderFragment? ChildContent { get; set; }
|
||||||
[Parameter] public bool IsDrawerOpen { get; set; }
|
|
||||||
[Parameter] public EventCallback BackdropFilterClicked { get; set; }
|
[Parameter] public EventCallback BackdropFilterClicked { get; set; }
|
||||||
[Parameter] public bool Closable { get; set; } = true;
|
[Parameter] public bool Closable { get; set; } = true;
|
||||||
public bool IsOpen { get; set; }
|
public bool IsOpen { get; set; }
|
||||||
public EventHandler<bool>? StateChanged { get; set; }
|
|
||||||
|
|
||||||
private BackdropFilter.BackdropFilter? BackdropFilter;
|
private BackdropFilter.BackdropFilter? BackdropFilter;
|
||||||
|
|
||||||
@@ -31,7 +29,6 @@ public partial class Popup
|
|||||||
{
|
{
|
||||||
IsOpen = true;
|
IsOpen = true;
|
||||||
await BackdropFilter?.Show()!;
|
await BackdropFilter?.Show()!;
|
||||||
StateChanged?.Invoke(null, IsOpen);
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +36,6 @@ public partial class Popup
|
|||||||
{
|
{
|
||||||
IsOpen = false;
|
IsOpen = false;
|
||||||
await BackdropFilter?.Hide()!;
|
await BackdropFilter?.Hide()!;
|
||||||
StateChanged?.Invoke(null, IsOpen);
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,6 +43,4 @@ public partial class Popup
|
|||||||
{
|
{
|
||||||
await BackdropFilterClicked.InvokeAsync();
|
await BackdropFilterClicked.InvokeAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetDisplayStyle() => IsOpen ? "display: flex;" : "display: none;";
|
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,13 @@
|
|||||||
.popup-wrapper {
|
.popup-wrapper {
|
||||||
display: none;
|
display: flex;
|
||||||
justify-content: center;
|
justify-self: anchor-center;
|
||||||
align-items: center;
|
align-self: anchor-center;
|
||||||
position: fixed;
|
position: absolute;
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
z-index: var(--index-popup);
|
z-index: var(--index-popup);
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup-content {
|
.popup-content {
|
||||||
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: var(--dropdown-content);
|
background-color: var(--dropdown-content);
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
type="text"
|
type="text"
|
||||||
class="search-field"
|
class="search-field"
|
||||||
placeholder="@Placeholder"
|
placeholder="@Placeholder"
|
||||||
|
disabled="@IsDisable"
|
||||||
|
style="@(IsDisable ? "pointer-events: none" : "")"
|
||||||
@bind=@Text
|
@bind=@Text
|
||||||
@bind:event="oninput"
|
@bind:event="oninput"
|
||||||
@bind:after=HandleTextChanged
|
@bind:after=HandleTextChanged
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ public partial class SearchInput
|
|||||||
{
|
{
|
||||||
[Parameter] public string? Text { get; set; }
|
[Parameter] public string? Text { get; set; }
|
||||||
[Parameter] public string? Placeholder { get; set; }
|
[Parameter] public string? Placeholder { get; set; }
|
||||||
|
[Parameter] public bool IsDisable { get; set; }
|
||||||
[Parameter] public EventCallback<string> TextChanged { get; set; }
|
[Parameter] public EventCallback<string> TextChanged { get; set; }
|
||||||
[Parameter] public EventCallback ClearClicked { get; set; }
|
[Parameter] public EventCallback ClearClicked { get; set; }
|
||||||
[Parameter] public EventCallback SearchClicked { get; set; }
|
[Parameter] public EventCallback SearchClicked { get; set; }
|
||||||
@@ -39,13 +40,17 @@ public partial class SearchInput
|
|||||||
}
|
}
|
||||||
private async Task HandleSearchClicked()
|
private async Task HandleSearchClicked()
|
||||||
{
|
{
|
||||||
await TextChanged.InvokeAsync(Text);
|
if (!IsDisable)
|
||||||
await SearchClicked.InvokeAsync();
|
{
|
||||||
await InputText.FocusAsync();
|
await SearchClicked.InvokeAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private async Task HandleFocusIn()
|
private async Task HandleFocusIn()
|
||||||
{
|
{
|
||||||
await FocusIn.InvokeAsync();
|
if (!IsDisable)
|
||||||
|
{
|
||||||
|
await FocusIn.InvokeAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private MarkupString GetSearchIcon()
|
private MarkupString GetSearchIcon()
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
height: 20px;
|
height: 20px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 2px 6px;
|
padding: 2px 6px;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.select-element:hover {
|
.select-element:hover {
|
||||||
cursor: pointer;
|
|
||||||
background: var(--input-selected);
|
background: var(--input-selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,11 @@
|
|||||||
public class SelectParams<TItem, THeader>
|
public class SelectParams<TItem, THeader>
|
||||||
{
|
{
|
||||||
public List<TItem> Items { get; set; } = [];
|
public List<TItem> Items { get; set; } = [];
|
||||||
public TItem? DefaultItem { get; set; }
|
public List<TItem> DefaultItems { get; set; } = [];
|
||||||
public Func<TItem, string> GetItemLabel { get; set; } = _ => string.Empty;
|
public Func<TItem, string> GetItemLabel { get; set; } = _ => string.Empty;
|
||||||
public List<THeader> Headers { get; set; } = [];
|
public List<THeader> Headers { get; set; } = [];
|
||||||
public THeader? DefaultHeader { get; set; }
|
public List<THeader> DefaultHeaders { get; set; } = [];
|
||||||
public Func<THeader, string> GetHeaderLabel { get; set; } = _ => string.Empty;
|
public Func<THeader, string> GetHeaderLabel { get; set; } = _ => string.Empty;
|
||||||
|
public Func<string, TItem>? AddItem { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,9 +14,20 @@
|
|||||||
@if (IsContentOpen)
|
@if (IsContentOpen)
|
||||||
{
|
{
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
@if (QuickAdd)
|
||||||
|
{
|
||||||
|
<div class="add-item">
|
||||||
|
<EditForm EditContext="QuickAddEditContext" OnSubmit="HandleSubmitAdd">
|
||||||
|
<input type="text" placeholder="@ResourcesKey.PlaceholderAdd" @bind=AddLabel>
|
||||||
|
</EditForm>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span class="line"></span>
|
||||||
|
}
|
||||||
|
|
||||||
@if (Params.Headers != null)
|
@if (Params.Headers != null)
|
||||||
{
|
{
|
||||||
@foreach (var header in Params.Headers)
|
@foreach (var header in Params.Headers.Union(HeaderValues ?? []))
|
||||||
{
|
{
|
||||||
<SelectRow IsSelected=HeaderValues?.Contains(header)
|
<SelectRow IsSelected=HeaderValues?.Contains(header)
|
||||||
Label="@Params.GetHeaderLabel(header)" Theme=Theme
|
Label="@Params.GetHeaderLabel(header)" Theme=Theme
|
||||||
@@ -24,14 +35,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (Params.Headers?.Any() == true)
|
@if (Params.Headers?.Count != 0)
|
||||||
{
|
{
|
||||||
<span class="line"></span>
|
<span class="line"></span>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (Params.Items != null)
|
@if (Params.Items != null)
|
||||||
{
|
{
|
||||||
@foreach (var item in Params.Items)
|
@foreach (var item in Params.Items.Union(Values ?? []))
|
||||||
{
|
{
|
||||||
<SelectRow IsSelected=Values?.Contains(item)
|
<SelectRow IsSelected=Values?.Contains(item)
|
||||||
Label="@Params.GetItemLabel(item)" Theme=Theme
|
Label="@Params.GetItemLabel(item)" Theme=Theme
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
using GameIdeas.BlazorApp.Shared.Components.Select.Models;
|
using GameIdeas.BlazorApp.Shared.Components.Select.Models;
|
||||||
|
using GameIdeas.Resources;
|
||||||
|
using GameIdeas.Shared.Constants;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Microsoft.AspNetCore.Components.Forms;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace GameIdeas.BlazorApp.Shared.Components.Select;
|
namespace GameIdeas.BlazorApp.Shared.Components.Select;
|
||||||
|
|
||||||
@@ -14,37 +18,48 @@ public partial class Select<TItem, THeader>
|
|||||||
[Parameter] public SelectTheme Theme { get; set; }
|
[Parameter] public SelectTheme Theme { get; set; }
|
||||||
[Parameter] public SelectType Type { get; set; } = SelectType.Single;
|
[Parameter] public SelectType Type { get; set; } = SelectType.Single;
|
||||||
[Parameter] public bool DisableClicked { get; set; } = false;
|
[Parameter] public bool DisableClicked { get; set; } = false;
|
||||||
|
[Parameter] public bool QuickAdd { get; set; } = false;
|
||||||
|
|
||||||
private bool IsContentOpen = false;
|
private bool IsContentOpen = false;
|
||||||
|
private string AddLabel = string.Empty;
|
||||||
|
private EditContext? QuickAddEditContext;
|
||||||
|
|
||||||
public void Close() =>
|
public void Close()
|
||||||
IsContentOpen = false;
|
|
||||||
|
|
||||||
public void Open() =>
|
|
||||||
IsContentOpen = true;
|
|
||||||
|
|
||||||
private void HandleButtonClicked()
|
|
||||||
{
|
{
|
||||||
if (!DisableClicked)
|
IsContentOpen = false;
|
||||||
IsContentOpen = !IsContentOpen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleContentClosed() =>
|
public void Open()
|
||||||
IsContentOpen = false;
|
{
|
||||||
|
IsContentOpen = true;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
if (Params.DefaultItem != null)
|
QuickAddEditContext = new EditContext(AddLabel);
|
||||||
|
|
||||||
|
if (Params.DefaultItems.Count != 0)
|
||||||
{
|
{
|
||||||
Values.Add(Params.DefaultItem);
|
Values.AddRange(Params.DefaultItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Params.DefaultHeader != null)
|
if (Params.DefaultHeaders.Count != 0)
|
||||||
{
|
{
|
||||||
HeaderValues.Add(Params.DefaultHeader);
|
HeaderValues.AddRange(Params.DefaultHeaders);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void HandleButtonClicked()
|
||||||
|
{
|
||||||
|
if (!DisableClicked && IsContentOpen)
|
||||||
|
Close();
|
||||||
|
|
||||||
|
if (!DisableClicked && !IsContentOpen)
|
||||||
|
Open();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleContentClosed() => Close();
|
||||||
|
|
||||||
private async Task HandleValueClicked(TItem value)
|
private async Task HandleValueClicked(TItem value)
|
||||||
{
|
{
|
||||||
if (Type != SelectType.Multiple || Values == null)
|
if (Type != SelectType.Multiple || Values == null)
|
||||||
@@ -82,4 +97,16 @@ public partial class Select<TItem, THeader>
|
|||||||
|
|
||||||
await HeaderValuesChanged.InvokeAsync(HeaderValues);
|
await HeaderValuesChanged.InvokeAsync(HeaderValues);
|
||||||
}
|
}
|
||||||
|
private async Task HandleSubmitAdd()
|
||||||
|
{
|
||||||
|
if (Params.AddItem != null)
|
||||||
|
{
|
||||||
|
Values ??= [];
|
||||||
|
Values.Add(Params.AddItem(AddLabel));
|
||||||
|
|
||||||
|
AddLabel = string.Empty;
|
||||||
|
|
||||||
|
await ValuesChanged.InvokeAsync(Values);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
z-index: var(--index-component)
|
z-index: var(--index-component);
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown {
|
.dropdown {
|
||||||
@@ -29,6 +30,20 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.add-item {
|
||||||
|
align-content: center;
|
||||||
|
height: 24px;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-item input {
|
||||||
|
width: 100%;
|
||||||
|
color: var(--white);
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
.dropdown::-webkit-scrollbar {
|
.dropdown::-webkit-scrollbar {
|
||||||
width: 10px;
|
width: 10px;
|
||||||
}
|
}
|
||||||
@@ -72,4 +87,16 @@
|
|||||||
border-bottom: 2px solid var(--input-selected);
|
border-bottom: 2px solid var(--input-selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***** Sort Theme *****/
|
||||||
|
.creation .content {
|
||||||
|
border-radius: var(--small-radius);
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: solid 1px var(--violet);
|
||||||
|
}
|
||||||
|
|
||||||
|
.creation .content .line {
|
||||||
|
display: block;
|
||||||
|
margin: 2px 6px;
|
||||||
|
border-bottom: 2px solid var(--input-selected);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,12 +5,12 @@
|
|||||||
|
|
||||||
@typeparam TItem
|
@typeparam TItem
|
||||||
|
|
||||||
<Select @ref=Select TItem="TItem" THeader="string" Theme="Theme" Type="SelectType.Multiple" DisableClicked=true
|
<Select @ref=Select TItem="TItem" THeader="string" Theme="Theme" Type="SelectType.Multiple"
|
||||||
Params="SelectParams" Values=Values ValuesChanged="HandleValuesChanged">
|
Params="SelectParams" Values=Values ValuesChanged="HandleValuesChanged" QuickAdd=QuickAdd>
|
||||||
|
|
||||||
<div class="@SelectHelper.GetClassFromTheme(Theme)">
|
<div class="@SelectHelper.GetClassFromTheme(Theme)">
|
||||||
<SearchInput @ref=SearchInput Icon="SearchInputIcon.Dropdown" Placeholder="@Placeholder"
|
<SearchInput @ref=SearchInput Icon="SearchInputIcon.Dropdown" Placeholder="@Placeholder"
|
||||||
TextChanged="HandleClearClicked" ClearClicked="HandleClearClicked"
|
TextChanged="HandleClearClicked" ClearClicked="HandleClearClicked" IsDisable=QuickAdd
|
||||||
FocusIn="HandleFocusIn" SearchClicked="HandleFocusIn" />
|
FocusIn="HandleFocusIn" SearchClicked="HandleFocusIn" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -13,16 +13,20 @@ public partial class SelectSearch<TItem>
|
|||||||
[Parameter] public List<TItem> Values { get; set; } = [];
|
[Parameter] public List<TItem> Values { get; set; } = [];
|
||||||
[Parameter] public EventCallback<List<TItem>> ValuesChanged { get; set; }
|
[Parameter] public EventCallback<List<TItem>> ValuesChanged { get; set; }
|
||||||
[Parameter] public string Placeholder { get; set; } = string.Empty;
|
[Parameter] public string Placeholder { get; set; } = string.Empty;
|
||||||
|
[Parameter] public bool QuickAdd { get; set; } = false;
|
||||||
|
[Parameter] public Func<string, TItem>? AddItem { get; set; }
|
||||||
|
|
||||||
private SelectParams<TItem, string> SelectParams = new();
|
private SelectParams<TItem, string> SelectParams = new();
|
||||||
private SearchInput? SearchInput;
|
private SearchInput? SearchInput;
|
||||||
private Select<TItem, string>? Select;
|
private Select<TItem, string>? Select;
|
||||||
|
|
||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
{
|
{
|
||||||
SelectParams = new()
|
SelectParams = new()
|
||||||
{
|
{
|
||||||
Items = Items,
|
Items = Items,
|
||||||
GetItemLabel = GetLabel
|
GetItemLabel = GetLabel,
|
||||||
|
AddItem = AddItem
|
||||||
};
|
};
|
||||||
|
|
||||||
base.OnParametersSet();
|
base.OnParametersSet();
|
||||||
@@ -31,12 +35,13 @@ public partial class SelectSearch<TItem>
|
|||||||
{
|
{
|
||||||
Values = values.ToList();
|
Values = values.ToList();
|
||||||
SearchInput?.SetText(string.Join(", ", Values.Select(GetLabel)));
|
SearchInput?.SetText(string.Join(", ", Values.Select(GetLabel)));
|
||||||
await ValuesChanged.InvokeAsync(values.ToList());
|
await ValuesChanged.InvokeAsync(Values.ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleClearClicked()
|
private async Task HandleClearClicked()
|
||||||
{
|
{
|
||||||
Values = [];
|
Values = [];
|
||||||
|
await ValuesChanged.InvokeAsync(Values.ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleFocusIn()
|
private void HandleFocusIn()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
.container {
|
.container {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: var(--index-component)
|
z-index: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="range"] {
|
input[type="range"] {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
.container {
|
.container {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: var(--index-component)
|
z-index: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="range"] {
|
input[type="range"] {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ public static class Endpoints
|
|||||||
{
|
{
|
||||||
public static class Game
|
public static class Game
|
||||||
{
|
{
|
||||||
|
public static readonly string Create = "api/Game/Create";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Category
|
public static class Category
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
namespace GameIdeas.BlazorApp.Shared.Exceptions;
|
||||||
|
|
||||||
|
public class GameCreationException(string message) : Exception(message);
|
||||||
@@ -27,6 +27,7 @@
|
|||||||
--index-backdrop: 700;
|
--index-backdrop: 700;
|
||||||
--index-dropdown: 900;
|
--index-dropdown: 900;
|
||||||
--index-popup: 1000;
|
--index-popup: 1000;
|
||||||
|
--index-overlay: 1100;
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
@@ -41,10 +42,6 @@ html, body, #app {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.valid.modified:not([type=checkbox]) {
|
|
||||||
border: 2px solid var(--green);
|
|
||||||
}
|
|
||||||
|
|
||||||
.invalid {
|
.invalid {
|
||||||
border: 2px solid var(--red) !important;
|
border: 2px solid var(--red) !important;
|
||||||
}
|
}
|
||||||
@@ -65,7 +62,7 @@ html, body, #app {
|
|||||||
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
|
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: 1000;
|
z-index: 10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
#blazor-error-ui .dismiss {
|
#blazor-error-ui .dismiss {
|
||||||
|
|||||||
@@ -34,6 +34,10 @@ public class Translations (TranslationService translationService)
|
|||||||
public string ErrorWhenFetchingData => translationService.Translate(nameof(ErrorWhenFetchingData));
|
public string ErrorWhenFetchingData => translationService.Translate(nameof(ErrorWhenFetchingData));
|
||||||
public string RequestFailedStatusFormat => translationService.Translate(nameof(RequestFailedStatusFormat));
|
public string RequestFailedStatusFormat => translationService.Translate(nameof(RequestFailedStatusFormat));
|
||||||
public string ErrorFetchCategories => translationService.Translate(nameof(ErrorFetchCategories));
|
public string ErrorFetchCategories => translationService.Translate(nameof(ErrorFetchCategories));
|
||||||
|
public string PlaceholderAdd => translationService.Translate(nameof(PlaceholderAdd));
|
||||||
|
public string ErrorCreateGame => translationService.Translate(nameof(ErrorCreateGame));
|
||||||
|
public string InvalidTitle => translationService.Translate(nameof(InvalidTitle));
|
||||||
|
public string InvalidInterest => translationService.Translate(nameof(InvalidInterest));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ResourcesKey
|
public static class ResourcesKey
|
||||||
@@ -76,4 +80,8 @@ public static class ResourcesKey
|
|||||||
public static string ErrorWhenFetchingData => _instance?.ErrorWhenFetchingData ?? throw new InvalidOperationException("ResourcesKey.ErrorWhenFetchingData is not initialized.");
|
public static string ErrorWhenFetchingData => _instance?.ErrorWhenFetchingData ?? throw new InvalidOperationException("ResourcesKey.ErrorWhenFetchingData is not initialized.");
|
||||||
public static string RequestFailedStatusFormat => _instance?.RequestFailedStatusFormat ?? throw new InvalidOperationException("ResourcesKey.RequestFailedStatusFormat is not initialized.");
|
public static string RequestFailedStatusFormat => _instance?.RequestFailedStatusFormat ?? throw new InvalidOperationException("ResourcesKey.RequestFailedStatusFormat is not initialized.");
|
||||||
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 ErrorCreateGame => _instance?.ErrorCreateGame ?? throw new InvalidOperationException("ResourcesKey.ErrorCreateGame 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.");
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
public class GlobalConstants
|
public class GlobalConstants
|
||||||
{
|
{
|
||||||
public const string EnterKeyCode = "Enter";
|
|
||||||
public const string PadEnterKeyCode = "NumpadEnter";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,11 +40,12 @@ public class GameController(IGameService gameService, ILoggerFactory loggerFacto
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("Create")]
|
[HttpPost("Create")]
|
||||||
public async Task<ActionResult<GameDto>> CreateGame([FromBody] GameDto game)
|
public async Task<ActionResult<int>> CreateGame([FromBody] GameDto game)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Created("/Create", await gameService.CreateGame(game));
|
var gameResult = await gameService.CreateGame(game);
|
||||||
|
return Created("/Create", gameResult.Id);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -54,11 +55,12 @@ public class GameController(IGameService gameService, ILoggerFactory loggerFacto
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPut("Update")]
|
[HttpPut("Update")]
|
||||||
public async Task<ActionResult<GameDto>> UpdateGame([FromBody] GameDto game)
|
public async Task<ActionResult<int>> UpdateGame([FromBody] GameDto game)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Created($"/Update", await gameService.UpdateGame(game));
|
var gameResult = await gameService.UpdateGame(game);
|
||||||
|
return Created($"/Update", gameResult.Id);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,5 +29,9 @@
|
|||||||
"ErrorWhenDeletingData": "Erreur lors de la requête DELETE",
|
"ErrorWhenDeletingData": "Erreur lors de la requête DELETE",
|
||||||
"ErrorWhenFetchingData": "Erreur lors de la requête GET",
|
"ErrorWhenFetchingData": "Erreur lors de la requête GET",
|
||||||
"RequestFailedStatusFormat": "Erreur lors de la réponse, code {0}",
|
"RequestFailedStatusFormat": "Erreur lors de la réponse, code {0}",
|
||||||
"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",
|
||||||
|
"ErrorCreateGame": "Erreur lors de la Création d'un jeu",
|
||||||
|
"InvalidTitle": "Le titre est incorrect",
|
||||||
|
"InvalidInterest": "L'interêt est incorrect'"
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user