Correct style and add loader
All checks were successful
Game Ideas build for PR / build_blazor_app (pull_request) Successful in 49s

This commit is contained in:
Maxime Adler
2025-04-15 11:13:32 +02:00
parent 1b7a43e2ac
commit ab0ab54f61
13 changed files with 93 additions and 50 deletions

View File

@@ -1,4 +1,5 @@
@using Blazored.FluentValidation @using Blazored.FluentValidation
@using GameIdeas.BlazorApp.Shared.Components.CircleLoader
@using GameIdeas.BlazorApp.Shared.Components.SelectSearch @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
@@ -22,14 +23,14 @@
<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)" QuickAdd=true <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 })" /> 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)" QuickAdd=true <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 })" /> AddItem="@(str => new PublisherDto() { Name = str })" />
</div> </div>
</div> </div>
<div class="container"> <div class="container">
@@ -42,21 +43,21 @@
<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)" QuickAdd=true <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 })" /> 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)" QuickAdd=true <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 })" /> 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)" QuickAdd=true <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 })" /> AddItem="@(str => new PlatformDto() { Label = str })" />
</div> </div>
@foreach (var platform in GameDto.Platforms ?? []) @foreach (var platform in GameDto.Platforms ?? [])
@@ -75,13 +76,18 @@
<div class="bottom-container"> <div class="bottom-container">
<ValidationSummary class="invalid-content" /> <ValidationSummary class="invalid-content" />
<div class="buttons"> <div class="buttons">
<button type="reset" class="cancel" @onclick=HandleOnCancel> <button type="reset" class="cancel" @onclick=HandleOnCancel disabled="@IsLoading">
@ResourcesKey.Reset @ResourcesKey.Reset
</button> </button>
<button type="submit" class="submit"> <button type="submit" class="submit" disabled="@IsLoading">
@ResourcesKey.Save @ResourcesKey.Save
</button> </button>
</div>
</div> </div>
</div> </EditForm>
</EditForm>
@if (IsLoading)
{
<CircleLoader />
}

View File

@@ -20,22 +20,18 @@ public partial class GameCreationForm
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 = true;
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()
@@ -50,6 +46,10 @@ public partial class GameCreationForm
return; return;
} }
IsLoading = true;
await GameGateway.CreateGame(GameDto); await GameGateway.CreateGame(GameDto);
IsLoading = false;
} }
} }

View File

@@ -78,7 +78,6 @@
height: 28px; height: 28px;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between;
align-items: center; align-items: center;
} }
@@ -98,6 +97,7 @@
} }
.buttons { .buttons {
margin-left: auto;
height: 100%; height: 100%;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@@ -112,4 +112,9 @@
color: var(--white); color: var(--white);
font-weight: bold; font-weight: bold;
padding: 0 10px; padding: 0 10px;
cursor: pointer;
}
.buttons button:hover {
background: var(--violet-selected);
} }

View File

@@ -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" />
</Popup> </Popup>

View File

@@ -1,5 +1,5 @@
.backdrop-filter { .backdrop-filter {
position: absolute; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;

View File

@@ -0,0 +1,3 @@
<div class="overlay"> <div class="loader"></div> </div>

View File

@@ -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);
}
}

View File

@@ -2,15 +2,18 @@
@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>

View File

@@ -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;
@@ -32,8 +30,6 @@ public partial class Popup
IsOpen = true; IsOpen = true;
await BackdropFilter?.Show()!; await BackdropFilter?.Show()!;
StateHasChanged(); StateHasChanged();
StateChanged?.Invoke(null, IsOpen);
} }
public async Task Close() public async Task Close()
@@ -41,14 +37,10 @@ public partial class Popup
IsOpen = false; IsOpen = false;
await BackdropFilter?.Hide()!; await BackdropFilter?.Hide()!;
StateHasChanged(); StateHasChanged();
StateChanged?.Invoke(null, IsOpen);
} }
private async Task HandleBackdropFilterClicked() private async Task HandleBackdropFilterClicked()
{ {
await BackdropFilterClicked.InvokeAsync(); await BackdropFilterClicked.InvokeAsync();
} }
private string GetDisplayStyle() => IsOpen ? "display: flex;" : "display: none;";
} }

View File

@@ -1,12 +1,14 @@
.popup-wrapper { .popup-wrapper {
display: none; display: flex;
justify-self: anchor-center; justify-self: anchor-center;
align-self: anchor-center; align-self: anchor-center;
position: fixed; position: absolute;
z-index: var(--index-popup); z-index: var(--index-popup);
} }
.popup-content { .popup-content {
overflow: hidden;
position: relative;
background-color: var(--dropdown-content); background-color: var(--dropdown-content);
padding: 10px; padding: 10px;
border-radius: var(--big-radius); border-radius: var(--big-radius);

View File

@@ -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"] {

View File

@@ -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"] {

View File

@@ -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 {
@@ -61,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 {