Add frontend creation game (#13)

Reviewed-on: #13
This commit was merged in pull request #13.
This commit is contained in:
2025-04-13 17:21:15 +02:00
parent 3ea96186e7
commit 225e8ba140
60 changed files with 913 additions and 231 deletions

View File

@@ -0,0 +1,69 @@
@using GameIdeas.BlazorApp.Shared.Components.Select
@using GameIdeas.BlazorApp.Shared.Components.Select.Models
@using GameIdeas.BlazorApp.Shared.Components.Slider
@using GameIdeas.Shared.Dto
<EditForm EditContext="EditContext" OnSubmit="HandleOnSubmit">
<div class="game-form">
<div class="container">
<div class="input-game">
<div id="first-label" class="label">@ResourcesKey.Title :</div>
<input type="text" class="title" @bind=GameDto.Title>
</div>
<div class="input-game">
<div class="label">@ResourcesKey.ReleaseDate :</div>
<input type="date" class="date" @bind=GameDto.ReleaseDate>
</div>
<div class="input-game">
<div class="label">@ResourcesKey.StorageSizeMo :</div>
<input type="number" class="storage" @bind=GameDto.StorageSpace>
</div>
<div class="input-game">
<div class="label">@ResourcesKey.Developers :</div>
<MultipleSelectList TItem="DeveloperDto" Theme="SelectListTheme" @bind-Values=GameDto.Developers
Items="CategoriesDto?.Developers?.Select(d => new SelectElement<DeveloperDto>(d, d.Name))" />
</div>
<div class="input-game">
<div class="label">@ResourcesKey.Publishers :</div>
<MultipleSelectList TItem="PublisherDto" Theme="SelectListTheme" @bind-Values=GameDto.Publishers
Items="CategoriesDto?.Publishers?.Select(p => new SelectElement<PublisherDto>(p, p.Name))" />
</div>
</div>
<div class="container">
<div class="input-game">
<div class="label">@ResourcesKey.Interest :</div>
<div class="slider">
<Slider Params="SliderParams" @bind-Value="GameDto.Interest" />
</div>
</div>
<div class="input-game">
<div class="label">@ResourcesKey.Properties :</div>
<MultipleSelectList TItem="PropertyDto" Theme="SelectListTheme" @bind-Values=GameDto.Properties
Items="CategoriesDto?.Properties?.Select(p => new SelectElement<PropertyDto>(p, p.Label))" />
</div>
<div class="input-game">
<div class="label">@ResourcesKey.Genres :</div>
<MultipleSelectList TItem="TagDto" Theme="SelectListTheme" @bind-Values=GameDto.Tags
Items="CategoriesDto?.Tags?.Select(t => new SelectElement<TagDto>(t, t.Label))" />
</div>
<div class="input-game">
<div class="label">@ResourcesKey.Platforms :</div>
<MultipleSelectList TItem="PlatformDto" Theme="SelectListTheme" @bind-Values=GameDto.Platforms
Items="CategoriesDto?.Platforms?.Select(p => new SelectElement<PlatformDto>(p, p.Label))" />
</div>
</div>
</div>
<div class="description-container">
<div id="label-description">@ResourcesKey.Description :</div>
<input type="text" class="description" @bind-value=GameDto.Description>
</div>
<div class="buttons">
<button type="reset" class="cancel" @onclick=HandleOnCancel>
@ResourcesKey.Reset
</button>
<button type="submit" class="submit">
@ResourcesKey.Save
</button>
</div>
</EditForm>

View File

@@ -0,0 +1,56 @@
using GameIdeas.BlazorApp.Pages.Games.Gateways;
using GameIdeas.BlazorApp.Shared.Components.Popup;
using GameIdeas.BlazorApp.Shared.Components.Select.Models;
using GameIdeas.BlazorApp.Shared.Components.Slider;
using GameIdeas.Shared.Dto;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.JSInterop;
namespace GameIdeas.BlazorApp.Pages.Games.Components;
public partial class GameCreationForm
{
[Inject] private IJSRuntime Js { get; set; } = default!;
[Inject] private IGameGateway GameGateway { get; set; } = default!;
[CascadingParameter] private Popup? Popup { get; set; }
private GameDto GameDto = new();
private CategoriesDto CategoriesDto = new();
private EditContext? EditContext;
private readonly SelectListTheme SelectListTheme = SelectListTheme.Creation;
private readonly SliderParams SliderParams = new() { Gap = 1, Min = 1, Max = 5 };
protected override async Task OnInitializedAsync()
{
EditContext = new(GameDto);
CategoriesDto = await GameGateway.FetchCategories();
if (Popup != null)
{
Popup.StateChanged += async (_, isOpen) => await HandlePopupStateChanged();
}
await base.OnInitializedAsync();
}
private async Task HandlePopupStateChanged()
{
await Js.InvokeVoidAsync("resizeGameForm");
}
private void HandleOnCancel()
{
Popup?.Close();
}
private async Task HandleOnSubmit(EditContext args)
{
if (EditContext?.Validate() == false)
{
return;
}
}
}

View File

@@ -0,0 +1,68 @@
.game-form {
display: flex;
flex-direction: row;
gap: 20px;
}
.container {
display: flex;
flex-direction: column;
gap: 8px;
}
.input-game {
display: grid;
grid-template-columns: auto 200px;
grid-gap: 8px;
height: 24px;
}
.label {
text-wrap: nowrap;
align-content: center;
font-weight: bold;
grid-column: 1;
}
input {
width: 100%;
background: var(--input-secondary);
border: solid 1px var(--input-selected);
outline: none;
border-radius: var(--small-radius);
grid-column: 2;
box-sizing: border-box;
color: var(--white);
}
input[type="date"]::-webkit-calendar-picker-indicator {
filter: invert(1);
cursor: pointer;
}
.description-container {
margin-top: 8px;
display: grid;
grid-template-columns: auto 1fr;
grid-gap: 8px;
}
.description {
min-height: 140px;
}
#label-description {
text-wrap: nowrap;
align-content: center;
font-weight: bold;
height: 24px;
}
.slider {
padding: 0 20px;
align-content: center;
}
input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none;
}

View File

@@ -0,0 +1,5 @@
window.resizeGameForm = () => {
const label = document.getElementById('first-label');
const targetLabel = document.getElementById('label-description');
targetLabel.style.width = window.getComputedStyle(label).getPropertyValue("width");
};