From 286b91383227ea6033a94fb0a47341c531c3f16a Mon Sep 17 00:00:00 2001 From: Kira Jiroux Date: Tue, 23 Sep 2025 16:42:40 -0400 Subject: [PATCH] Made reusable PokemonForm to replace Add/Edit forms. Also, renamed Download button to better fit the schema. Plus additional decorative changes. --- .../Components/Component/Loading.razor.cs | 12 + .../Pokemon Components/PokemonAddForm.razor | 152 --------- .../PokemonAddForm.razor.cs | 101 ------ ...load.razor => PokemonDownloadButton.razor} | 0 ...azor.cs => PokemonDownloadButton.razor.cs} | 2 +- .../Pokemon Components/PokemonForm.razor | 306 ++++++++++++++++++ .../Pokemon Components/PokemonForm.razor.cs | 161 +++++++++ ...ddForm.razor.css => PokemonForm.razor.css} | 5 +- .../Pokemon Components/PokemonSelector.razor | 4 - .../Pokemon Components/PokemonTable.razor | 4 +- .../Pages/Pokemon Pages/PokemonCreate.razor | 24 +- .../Pages/Pokemon Pages/PokemonEdit.razor | 131 ++------ .../Pages/Pokemon Pages/PokemonEdit.razor.cs | 16 +- .../Pages/Pokemon Pages/PokemonEdit.razor.css | 10 + 14 files changed, 543 insertions(+), 385 deletions(-) create mode 100644 Portfolio.WebUI.Server/Components/Component/Loading.razor.cs delete mode 100644 Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonAddForm.razor delete mode 100644 Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonAddForm.razor.cs rename Portfolio.WebUI.Server/Components/Component/Pokemon Components/{PokemonDownload.razor => PokemonDownloadButton.razor} (100%) rename Portfolio.WebUI.Server/Components/Component/Pokemon Components/{PokemonDownload.razor.cs => PokemonDownloadButton.razor.cs} (95%) create mode 100644 Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonForm.razor create mode 100644 Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonForm.razor.cs rename Portfolio.WebUI.Server/Components/Component/Pokemon Components/{PokemonAddForm.razor.css => PokemonForm.razor.css} (95%) diff --git a/Portfolio.WebUI.Server/Components/Component/Loading.razor.cs b/Portfolio.WebUI.Server/Components/Component/Loading.razor.cs new file mode 100644 index 0000000..d406473 --- /dev/null +++ b/Portfolio.WebUI.Server/Components/Component/Loading.razor.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Components; + +namespace Portfolio.WebUI.Server.Components.Component +{ + public partial class Loading + { + [Parameter] + public string LoadingString { get; set; } + + + } +} diff --git a/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonAddForm.razor b/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonAddForm.razor deleted file mode 100644 index b4cbef9..0000000 --- a/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonAddForm.razor +++ /dev/null @@ -1,152 +0,0 @@ -@inject IPokemonService PokemonService - - -
- - - -

New Pokemon

- - -
-
- # - - -
-
- - -
- - Variation? -
- - -
- - -
-
- Pokemon Type - - - @foreach (var pt in PokemonTypes) - { - - } - -
- -
- - -
- -
-
- Sleep Type -
-
- - - @foreach (var st in SleepTypes) - { - - } - -
-
- -
-
- Specialty -
-
- - - @foreach (var sp in Specialities) - { - - } - -
-
-
- - -
- - -
-
- Base Image URL - -
-
-
-
- Shiny Image URL - -
-
- - -
-
- Flavor Text - -
-
- - -
- - @if (showErrors && !IsComplete) - { -
- Please complete: @string.Join(", ", MissingFields()) -
- } - -
- - @if(mostRecentForm) - { - - } -
-
-
- diff --git a/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonAddForm.razor.cs b/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonAddForm.razor.cs deleted file mode 100644 index 2e24639..0000000 --- a/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonAddForm.razor.cs +++ /dev/null @@ -1,101 +0,0 @@ -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Web; -using Microsoft.EntityFrameworkCore.Metadata.Internal; -using Portfolio.Application.Services.PokemonService; -using Portfolio.Domain.Features.Pokemon; - -namespace Portfolio.WebUI.Server.Components.Component.Pokemon_Components -{ - public partial class PokemonAddForm - { - [Parameter] - public EventCallback OnPokemonReady { get; set; } - [Parameter] - public EventCallback RemoveForm { get; set; } - [Parameter] - public bool mostRecentForm { get; set; } - - protected static readonly string[] PokemonTypes = new[] - { - "Grass","Fire","Water","Normal","Flying","Bug","Poison","Electric","Ground","Rock","Ice", - "Steel","Fighting","Psychic","Dark","Fairy","Ghost","Dragon" - }; - protected static readonly string[] SleepTypes = new[] { "Dozing", "Snoozing", "Slumbering" }; - protected static readonly string[] Specialities = new[] { "Berries", "Ingredients", "Skills", "All" }; - - - private bool HideLabel { get; set; } = true; - private bool showErrors { get; set; } = false; - - private Pokemon NewPokemon = new Pokemon - { - PokemonId = 0, // Or any default ID logic - PokemonName = string.Empty, // Required fields cannot be null - SleepType = string.Empty, - Speciality = string.Empty, - IsVariation = false - }; - - private void Toggle() => HideLabel = !HideLabel; - - - private string GetRoundingClass() - { - if (!HideLabel) { - return "rounded-start"; - } - return "rounded-start rounded-end"; - } - - // Minimal "complete" check (no data annotations needed) - private bool IsComplete => - NewPokemon.PokemonId > 0 && - !string.IsNullOrWhiteSpace(NewPokemon.PokemonName) && - !string.IsNullOrWhiteSpace(NewPokemon.PokemonType) && - !string.IsNullOrWhiteSpace(NewPokemon.SleepType) && - !string.IsNullOrWhiteSpace(NewPokemon.Speciality) && - (!NewPokemon.IsVariation || !string.IsNullOrWhiteSpace(NewPokemon.VariationName)); - - private IEnumerable MissingFields() - { - if (NewPokemon.PokemonId <= 0) yield return "Pokédex #"; - if (string.IsNullOrWhiteSpace(NewPokemon.PokemonName)) yield return "Name"; - if (string.IsNullOrWhiteSpace(NewPokemon.PokemonType)) yield return "Type"; - if (string.IsNullOrWhiteSpace(NewPokemon.SleepType)) yield return "Sleep Type"; - if (string.IsNullOrWhiteSpace(NewPokemon.Speciality)) yield return "Specialty"; - if (NewPokemon.IsVariation && string.IsNullOrWhiteSpace(NewPokemon.VariationName)) yield return "Variation Name"; - } - - private async Task HandleRemove() - { - await RemoveForm.InvokeAsync(); - } - - private async Task SendPokemon() - { - if (!IsComplete) - { - showErrors = true; - StateHasChanged(); - return; - } - - // Optionally send a copy to avoid later mutation by the child - var copy = new Pokemon - { - PokemonId = NewPokemon.PokemonId, - PokemonName = NewPokemon.PokemonName, - PokemonType = NewPokemon.PokemonType, - SleepType = NewPokemon.SleepType, - Speciality = NewPokemon.Speciality, - IsVariation = NewPokemon.IsVariation, - VariationName = NewPokemon.VariationName, - PokemonImageUrl = NewPokemon.PokemonImageUrl, - PokemonShinyImageUrl = NewPokemon.PokemonShinyImageUrl, - FlavorText = NewPokemon.FlavorText - }; - - await OnPokemonReady.InvokeAsync(copy); - } - } -} diff --git a/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonDownload.razor b/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonDownloadButton.razor similarity index 100% rename from Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonDownload.razor rename to Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonDownloadButton.razor diff --git a/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonDownload.razor.cs b/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonDownloadButton.razor.cs similarity index 95% rename from Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonDownload.razor.cs rename to Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonDownloadButton.razor.cs index 3a67e1d..607cc33 100644 --- a/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonDownload.razor.cs +++ b/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonDownloadButton.razor.cs @@ -5,7 +5,7 @@ using System.Text.Json; namespace Portfolio.WebUI.Server.Components.Component.Pokemon_Components { - partial class PokemonDownload + partial class PokemonDownloadButton { [Parameter] public List _Pokemon { get; set; } diff --git a/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonForm.razor b/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonForm.razor new file mode 100644 index 0000000..7537f3a --- /dev/null +++ b/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonForm.razor @@ -0,0 +1,306 @@ +@inject IPokemonService PokemonService + +@if(formUse == "ADD") +{ +
+ + + +

New Pokemon

+ + +
+
+ # + + +
+
+ + +
+ + Variation? +
+ + +
+ + +
+
+ Pokemon Type + + + @foreach (var pt in PokemonTypes) + { + + } + +
+ +
+ + +
+ +
+
+ Sleep Type +
+
+ + + @foreach (var st in SleepTypes) + { + + } + +
+
+ +
+
+ Specialty +
+
+ + + @foreach (var sp in Specialities) + { + + } + +
+
+
+ + +
+ + +
+
+ Base Image URL + +
+
+
+
+ Shiny Image URL + +
+
+ + +
+
+ Flavor Text + +
+
+ + +
+ + @if (showErrors && !IsComplete) + { +
+ Please complete: @string.Join(", ", MissingFields()) +
+ } + +
+ + @if (mostRecentForm) + { + + } +
+
+
+ +} +else if (formUse == "EDIT") +{ +
+ + + +

Edit Pokemon

+ + +
+
+ # + + +
+
+ + +
+ + Variation? +
+ + +
+ + +
+
+ Pokemon Type + + + @foreach (var pt in PokemonTypes) + { + + } + +
+ +
+ + +
+ +
+
+ Sleep Type +
+
+ + + @foreach (var st in SleepTypes) + { + + } + +
+
+ +
+
+ Specialty +
+
+ + + @foreach (var sp in Specialities) + { + + } + +
+
+
+ + +
+ + +
+
+ Base Image URL + +
+
+
+
+ Shiny Image URL + +
+
+ + +
+
+ Flavor Text + +
+
+ + +
+ + @if (showErrors && !IsComplete) + { +
+ Please complete: @string.Join(", ", MissingFields()) +
+ } + +
+ + @if (mostRecentForm) + { + + } +
+
+
+} + diff --git a/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonForm.razor.cs b/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonForm.razor.cs new file mode 100644 index 0000000..66194fd --- /dev/null +++ b/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonForm.razor.cs @@ -0,0 +1,161 @@ +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; +using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Portfolio.Application.Services.PokemonService; +using Portfolio.Domain.Features.Pokemon; + +namespace Portfolio.WebUI.Server.Components.Component.Pokemon_Components +{ + public partial class PokemonForm + { + // To Add or Edit Pokemon + [Parameter] + public string formUse { get; set; } + + + [Parameter] + public EventCallback OnPokemonReady { get; set; } + [Parameter] + public EventCallback RemoveForm { get; set; } + + // When Adding + [Parameter] + public bool mostRecentForm { get; set; } + private Pokemon NewPokemon = new Pokemon + { + PokemonId = 0, // Or any default ID logic + PokemonName = string.Empty, // Required fields cannot be null + SleepType = string.Empty, + Speciality = string.Empty, + IsVariation = false + }; + + // When Editing + [Parameter] + public Pokemon? PokemonToEdit { get; set; } + private int PokemonToEditId { get; set; } + + + // General Form + protected static readonly string[] PokemonTypes = new[] + { + "Grass","Fire","Water","Normal","Flying","Bug","Poison","Electric","Ground","Rock","Ice", + "Steel","Fighting","Psychic","Dark","Fairy","Ghost","Dragon" + }; + protected static readonly string[] SleepTypes = new[] { "Dozing", "Snoozing", "Slumbering" }; + protected static readonly string[] Specialities = new[] { "Berries", "Ingredients", "Skills", "All" }; + + + private bool HideLabel { get; set; } + private bool showErrors { get; set; } = false; + + + protected override async Task OnInitializedAsync() + { + if (formUse == "EDIT") + { + if (PokemonToEdit.IsVariation == true) + { + HideLabel = false; + } + PokemonToEditId = PokemonToEdit.Id; + } + else + { + HideLabel = true; + } + } + + + private void Toggle() + { + HideLabel = !HideLabel; + } + + + // CSS-function to get proper styling for form elements + private string GetRoundingClass() + { + if (!HideLabel) + { + return "rounded-start"; + } + return "rounded-start rounded-end"; + } + + // Minimal "complete" check (no data annotations needed) + private bool IsComplete => + NewPokemon.PokemonId > 0 && + !string.IsNullOrWhiteSpace(NewPokemon.PokemonName) && + !string.IsNullOrWhiteSpace(NewPokemon.PokemonType) && + !string.IsNullOrWhiteSpace(NewPokemon.SleepType) && + !string.IsNullOrWhiteSpace(NewPokemon.Speciality) && + (!NewPokemon.IsVariation || !string.IsNullOrWhiteSpace(NewPokemon.VariationName)); + + private IEnumerable MissingFields() + { + if (NewPokemon.PokemonId <= 0) yield return "Pokédex #"; + if (string.IsNullOrWhiteSpace(NewPokemon.PokemonName)) yield return "Name"; + if (string.IsNullOrWhiteSpace(NewPokemon.PokemonType)) yield return "Type"; + if (string.IsNullOrWhiteSpace(NewPokemon.SleepType)) yield return "Sleep Type"; + if (string.IsNullOrWhiteSpace(NewPokemon.Speciality)) yield return "Specialty"; + if (NewPokemon.IsVariation && string.IsNullOrWhiteSpace(NewPokemon.VariationName)) yield return "Variation Name"; + } + + private async Task HandleRemove() + { + await RemoveForm.InvokeAsync(); + } + + private async Task SendPokemon() + { + if(formUse == "ADD") + { + if (!IsComplete) + { + showErrors = true; + StateHasChanged(); + return; + } + + // Optionally send a copy to avoid later mutation by the child + var copy = new Pokemon + { + PokemonId = NewPokemon.PokemonId, + PokemonName = NewPokemon.PokemonName, + PokemonType = NewPokemon.PokemonType, + SleepType = NewPokemon.SleepType, + Speciality = NewPokemon.Speciality, + IsVariation = NewPokemon.IsVariation, + VariationName = NewPokemon.VariationName, + PokemonImageUrl = NewPokemon.PokemonImageUrl, + PokemonShinyImageUrl = NewPokemon.PokemonShinyImageUrl, + FlavorText = NewPokemon.FlavorText + }; + + await OnPokemonReady.InvokeAsync(copy); + } + else + { + // Optionally send a copy to avoid later mutation by the child + var edit = new Pokemon + { + Id = PokemonToEditId, + PokemonId = PokemonToEdit.PokemonId, + PokemonName = PokemonToEdit.PokemonName, + PokemonType = PokemonToEdit.PokemonType, + SleepType = PokemonToEdit.SleepType, + Speciality = PokemonToEdit.Speciality, + IsVariation = PokemonToEdit.IsVariation, + VariationName = PokemonToEdit.VariationName, + PokemonImageUrl = PokemonToEdit.PokemonImageUrl, + PokemonShinyImageUrl = PokemonToEdit.PokemonShinyImageUrl, + FlavorText = PokemonToEdit.FlavorText + }; + + await OnPokemonReady.InvokeAsync(edit); + } + + } + } +} diff --git a/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonAddForm.razor.css b/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonForm.razor.css similarity index 95% rename from Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonAddForm.razor.css rename to Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonForm.razor.css index 8a32a45..8cca838 100644 --- a/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonAddForm.razor.css +++ b/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonForm.razor.css @@ -8,7 +8,7 @@ $display-font-sizes: ( 6: 2.5rem ); -.create-container { +.pokemon-form-container { position: relative; width: 100%; max-width: 390px; /* Prevent it from getting too huge */ @@ -24,5 +24,4 @@ $display-font-sizes: ( .checkbox-styling { width: 100px; height: 100px; - -} \ No newline at end of file +} diff --git a/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonSelector.razor b/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonSelector.razor index e4e6721..f39567f 100644 --- a/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonSelector.razor +++ b/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonSelector.razor @@ -21,7 +21,3 @@ } - - \ No newline at end of file diff --git a/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonTable.razor b/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonTable.razor index 7779a51..8237713 100644 --- a/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonTable.razor +++ b/Portfolio.WebUI.Server/Components/Component/Pokemon Components/PokemonTable.razor @@ -33,7 +33,7 @@

@(pokemons.Count()) Pokémon

- + @@ -104,7 +104,7 @@ - @pokemon.PokemonId + @pokemon.PokemonId ++ @pokemon.Id diff --git a/Portfolio.WebUI.Server/Components/Pages/Pokemon Pages/PokemonCreate.razor b/Portfolio.WebUI.Server/Components/Pages/Pokemon Pages/PokemonCreate.razor index 305bb05..62403e8 100644 --- a/Portfolio.WebUI.Server/Components/Pages/Pokemon Pages/PokemonCreate.razor +++ b/Portfolio.WebUI.Server/Components/Pages/Pokemon Pages/PokemonCreate.razor @@ -25,7 +25,8 @@ else
- @@ -44,9 +45,10 @@ else {
- +
@@ -58,16 +60,18 @@ else {
- +
- +
} diff --git a/Portfolio.WebUI.Server/Components/Pages/Pokemon Pages/PokemonEdit.razor b/Portfolio.WebUI.Server/Components/Pages/Pokemon Pages/PokemonEdit.razor index d271796..c04951e 100644 --- a/Portfolio.WebUI.Server/Components/Pages/Pokemon Pages/PokemonEdit.razor +++ b/Portfolio.WebUI.Server/Components/Pages/Pokemon Pages/PokemonEdit.razor @@ -1,7 +1,7 @@ @page "/pokemonsleep/edit/{id:int}" @inject IPokemonService PokemonService @inject NavigationManager Navigation -@inject IJSRuntime JSRuntime +@inject IJSRuntime JS @attribute [StreamRendering] @rendermode InteractiveServer @@ -12,122 +12,33 @@ @if (pokemon == null) { -

Loading...

+ } else { - -
- -
-
-
-

Edit Pokémon

+
+
+
+ +
+
+ +
- - -
- - - - -
-
- # - - -
-
- - -
- -
- - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - -
- -
- - - - - - -
-
- -
-
- -
- - Variation? -
- - -
- -
-
-
- - - -
- - -
- -
- - -
- -
- - -
- - -
- - -
-
+
+
+
+
+ } diff --git a/Portfolio.WebUI.Server/Components/Pages/Pokemon Pages/PokemonEdit.razor.cs b/Portfolio.WebUI.Server/Components/Pages/Pokemon Pages/PokemonEdit.razor.cs index d5a8088..5548456 100644 --- a/Portfolio.WebUI.Server/Components/Pages/Pokemon Pages/PokemonEdit.razor.cs +++ b/Portfolio.WebUI.Server/Components/Pages/Pokemon Pages/PokemonEdit.razor.cs @@ -14,16 +14,28 @@ namespace Portfolio.WebUI.Server.Components.Pages.Pokemon_Pages pokemon = await PokemonService.GetPokemonByIdAsync(Id); } + private async Task ReceivePokemon(Pokemon p) + { + // Save received pokemon as Pokemon 1 + pokemon = p; + + // Server console (Blazor Server) + Console.WriteLine($"[Pokemon 1] #{pokemon.PokemonId} {pokemon.PokemonName} | {pokemon.PokemonType} | {pokemon.SleepType} | {pokemon.Speciality} | Var:{pokemon.IsVariation} {pokemon.VariationName}"); + + // Browser console + await JS.InvokeVoidAsync("console.log", "Pokemon 1:", pokemon); + } + private async Task HandleSubmit() { await PokemonService.UpdatePokemonAsync(pokemon); //Navigation.NavigateTo("/pokemonsleep"); - await JSRuntime.InvokeVoidAsync("history.back"); + await JS.InvokeVoidAsync("history.back"); } private async void Cancel() { - await JSRuntime.InvokeVoidAsync("history.back"); + await JS.InvokeVoidAsync("history.back"); } diff --git a/Portfolio.WebUI.Server/Components/Pages/Pokemon Pages/PokemonEdit.razor.css b/Portfolio.WebUI.Server/Components/Pages/Pokemon Pages/PokemonEdit.razor.css index c83bb0d..c2d1fb6 100644 --- a/Portfolio.WebUI.Server/Components/Pages/Pokemon Pages/PokemonEdit.razor.css +++ b/Portfolio.WebUI.Server/Components/Pages/Pokemon Pages/PokemonEdit.razor.css @@ -5,3 +5,13 @@ box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(255,255, 255, 0.19); border-radius: 15px; } + +.addcard { + width: 100%; + max-width: 30rem; + flex: 0 0 auto; /* prevent flex shrink/grow */ + display: flex; + justify-content: center; + align-items: center; + padding: 0.5rem; +} \ No newline at end of file