Compare commits
3 Commits
d977e08650
...
2f210a0e1a
| Author | SHA1 | Date |
|---|---|---|
|
|
2f210a0e1a | |
|
|
37d8fdaca2 | |
|
|
286b913832 |
|
|
@ -0,0 +1,12 @@
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
namespace Portfolio.WebUI.Server.Components.Component
|
||||||
|
{
|
||||||
|
public partial class Loading
|
||||||
|
{
|
||||||
|
[Parameter]
|
||||||
|
public string LoadingString { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,152 +0,0 @@
|
||||||
@inject IPokemonService PokemonService
|
|
||||||
|
|
||||||
|
|
||||||
<div class="create-container m-auto bg-info border border-5 border-info-subtle rounded-4 p-3">
|
|
||||||
<EditForm class="col" Model="NewPokemon">
|
|
||||||
<DataAnnotationsValidator />
|
|
||||||
|
|
||||||
<div class="bg-primary-subtle rounded"><p class="fs-3 fw-light text-center card-title">New Pokemon</p></div>
|
|
||||||
|
|
||||||
<!-- Pokemon Number and Name -->
|
|
||||||
<div class="row mt-1">
|
|
||||||
<div class="col input-group mb-2">
|
|
||||||
<span class="input-group-text text-sm-center rounded-start">#</span>
|
|
||||||
<InputNumber min="1"
|
|
||||||
placeholder="Pokedex #"
|
|
||||||
id="PokemonId"
|
|
||||||
@bind-Value="NewPokemon.PokemonId"
|
|
||||||
class="form-control "
|
|
||||||
type="number" />
|
|
||||||
<InputText placeholder="Pokemon Name"
|
|
||||||
id="PokemonName"
|
|
||||||
@bind-Value="NewPokemon.PokemonName"
|
|
||||||
class="form-control w-50 rounded-end" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Variation Check -->
|
|
||||||
<div class="d-flex flex-row justify-content-start input-group ">
|
|
||||||
<InputCheckbox id="IsVariation"
|
|
||||||
@bind-Value="NewPokemon.IsVariation"
|
|
||||||
@onclick="@Toggle"
|
|
||||||
class="form-check-input p-3 rounded" />
|
|
||||||
<span class="input-group-text ms-1 @GetRoundingClass()">Variation?</span>
|
|
||||||
<InputText placeholder="How So?"
|
|
||||||
id="VariationName"
|
|
||||||
@bind-Value="NewPokemon.VariationName"
|
|
||||||
class="form-control rounded-end"
|
|
||||||
hidden="@HideLabel" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- <br> -->
|
|
||||||
<div class="border-bottom border-3 border-info-subtle rounded m-1 my-3"></div>
|
|
||||||
|
|
||||||
<!-- Pokemon Type -->
|
|
||||||
<div class="row mb-2">
|
|
||||||
<div class="input-group m-auto">
|
|
||||||
<span for="PokemonType" class="input-group-text rounded-start">Pokemon Type</span>
|
|
||||||
<InputSelect id="PokemonType" @bind-Value="NewPokemon.PokemonType" class="form-select rounded-end">
|
|
||||||
<option disabled value="" selected>Select...</option>
|
|
||||||
@foreach (var pt in PokemonTypes)
|
|
||||||
{
|
|
||||||
<option value="@pt">@pt</option>
|
|
||||||
}
|
|
||||||
</InputSelect>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Pokemon Sleep Type, Specialty -->
|
|
||||||
<div class="row mb-3 mx-0">
|
|
||||||
<!-- Sleep Type -->
|
|
||||||
<div class="col ps-0 pe-1">
|
|
||||||
<div class="row input-group m-auto">
|
|
||||||
<span for="SleepType" class="input-group-text rounded-top">Sleep Type</span>
|
|
||||||
</div>
|
|
||||||
<div class="row input-group m-auto">
|
|
||||||
<InputSelect id="SleepType" @bind-Value="NewPokemon.SleepType" class="form-select rounded-bottom">
|
|
||||||
<option disabled value="" selected>Select...</option>
|
|
||||||
@foreach (var st in SleepTypes)
|
|
||||||
{
|
|
||||||
<option value="@st">@st</option>
|
|
||||||
}
|
|
||||||
</InputSelect>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Speciality -->
|
|
||||||
<div class="col ps-1 pe-0">
|
|
||||||
<div class="row input-group m-auto">
|
|
||||||
<span for="Speciality" class="input-group-text rounded-top">Specialty</span>
|
|
||||||
</div>
|
|
||||||
<div class="row input-group m-auto">
|
|
||||||
<InputSelect id="Speciality" @bind-Value="NewPokemon.Speciality" class="form-select rounded-bottom">
|
|
||||||
<option disabled value="" selected>Select...</option>
|
|
||||||
@foreach (var sp in Specialities)
|
|
||||||
{
|
|
||||||
<option value="@sp">@sp</option>
|
|
||||||
}
|
|
||||||
</InputSelect>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- <br> -->
|
|
||||||
<div class="border-bottom border-3 border-info-subtle rounded m-1 my-3"></div>
|
|
||||||
|
|
||||||
<!-- Images -->
|
|
||||||
<div class="row mb-2">
|
|
||||||
<div class="input-group m-auto">
|
|
||||||
<span for="ImageUrl" class="input-group-text rounded-start">Base Image URL</span>
|
|
||||||
<InputText id="ImageUrl" @bind-Value="NewPokemon.PokemonImageUrl" class="form-control rounded-end" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-2">
|
|
||||||
<div class="input-group m-auto">
|
|
||||||
<span for="ShinyImageUrl" class="input-group-text rounded-start">Shiny Image URL</span>
|
|
||||||
<InputText id="ShinyImageUrl" @bind-Value="NewPokemon.PokemonShinyImageUrl" class="form-control rounded-end" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Flavor -->
|
|
||||||
<div class="row mb-2">
|
|
||||||
<div class="input-group m-auto">
|
|
||||||
<span for="FlavorText" class="input-group-text rounded-start">Flavor Text</span>
|
|
||||||
<InputText id="FlavorText" @bind-Value="NewPokemon.FlavorText" class="form-control rounded-end" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- <br> -->
|
|
||||||
<div class="border-bottom border-3 border-info-subtle rounded m-1 my-3"></div>
|
|
||||||
|
|
||||||
@if (showErrors && !IsComplete)
|
|
||||||
{
|
|
||||||
<div class="alert alert-warning mt-2">
|
|
||||||
Please complete: @string.Join(", ", MissingFields())
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
<div class="d-flex mt-3 justify-content-center gap-3">
|
|
||||||
<button type="button"
|
|
||||||
class="btn btn-primary rounded p-1 px-0"
|
|
||||||
@onclick="@SendPokemon"
|
|
||||||
disabled="@( !IsComplete )">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-file-arrow-up" viewBox="0 0 16 16">
|
|
||||||
<path d="M8 11a.5.5 0 0 0 .5-.5V6.707l1.146 1.147a.5.5 0 0 0 .708-.708l-2-2a.5.5 0 0 0-.708 0l-2 2a.5.5 0 1 0 .708.708L7.5 6.707V10.5a.5.5 0 0 0 .5.5" />
|
|
||||||
<path d="M4 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm0 1h8a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
@if(mostRecentForm)
|
|
||||||
{
|
|
||||||
<button type="button"
|
|
||||||
class="btn btn-danger rounded p-1 px-0"
|
|
||||||
@onclick="@HandleRemove">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-file-minus" viewBox="0 0 16 16">
|
|
||||||
<path d="M5.5 8a.5.5 0 0 1 .5-.5h4a.5.5 0 0 1 0 1H6a.5.5 0 0 1-.5-.5" />
|
|
||||||
<path d="M4 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm0 1h8a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</EditForm>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
@ -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<Pokemon> 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<string> 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -5,7 +5,7 @@ using System.Text.Json;
|
||||||
|
|
||||||
namespace Portfolio.WebUI.Server.Components.Component.Pokemon_Components
|
namespace Portfolio.WebUI.Server.Components.Component.Pokemon_Components
|
||||||
{
|
{
|
||||||
partial class PokemonDownload
|
partial class PokemonDownloadButton
|
||||||
{
|
{
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public List<Pokemon> _Pokemon { get; set; }
|
public List<Pokemon> _Pokemon { get; set; }
|
||||||
|
|
@ -0,0 +1,308 @@
|
||||||
|
@inject IPokemonService PokemonService
|
||||||
|
|
||||||
|
@if(formUse == "ADD")
|
||||||
|
{
|
||||||
|
<div class="pokemon-form-container m-auto bg-info border border-5 border-info-subtle rounded-4 p-3">
|
||||||
|
<EditForm class="col" Model="NewPokemon">
|
||||||
|
<DataAnnotationsValidator />
|
||||||
|
|
||||||
|
<div class="bg-primary-subtle rounded"><p class="fs-3 fw-light text-center card-title">New Pokemon</p></div>
|
||||||
|
|
||||||
|
<!-- Pokemon Number and Name -->
|
||||||
|
<div class="row mt-1">
|
||||||
|
<div class="col input-group mb-2">
|
||||||
|
<span class="input-group-text text-sm-center rounded-start">#</span>
|
||||||
|
<InputNumber min="1"
|
||||||
|
placeholder="Pokedex #"
|
||||||
|
id="PokemonId"
|
||||||
|
@bind-Value="NewPokemon.PokemonId"
|
||||||
|
@onchange="@SendPokemon"
|
||||||
|
class="form-control "
|
||||||
|
type="number" />
|
||||||
|
<InputText placeholder="Pokemon Name"
|
||||||
|
id="PokemonName"
|
||||||
|
@bind-Value="NewPokemon.PokemonName"
|
||||||
|
@onchange="@SendPokemon"
|
||||||
|
class="form-control w-50 rounded-end" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Variation Check -->
|
||||||
|
<div class="d-flex flex-row justify-content-start input-group ">
|
||||||
|
<InputCheckbox id="IsVariation"
|
||||||
|
@bind-Value="NewPokemon.IsVariation"
|
||||||
|
@onclick="@Toggle"
|
||||||
|
@onchange="@SendPokemon"
|
||||||
|
class="form-check-input p-3 rounded" />
|
||||||
|
<span class="input-group-text ms-1 @GetRoundingClass()">Variation?</span>
|
||||||
|
<InputText placeholder="How So?"
|
||||||
|
id="VariationName"
|
||||||
|
@bind-Value="NewPokemon.VariationName"
|
||||||
|
@onchange="@SendPokemon"
|
||||||
|
class="form-control rounded-end"
|
||||||
|
hidden="@HideLabel" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <br> -->
|
||||||
|
<div class="border-bottom border-3 border-info-subtle rounded m-1 my-3"></div>
|
||||||
|
|
||||||
|
<!-- Pokemon Type -->
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="input-group m-auto">
|
||||||
|
<span for="PokemonType" class="input-group-text rounded-start">Pokemon Type</span>
|
||||||
|
<InputSelect id="PokemonType" @bind-Value="NewPokemon.PokemonType" @onchange="@SendPokemon" class="form-select rounded-end">
|
||||||
|
<option disabled value="" selected>Select...</option>
|
||||||
|
@foreach (var pt in PokemonTypes)
|
||||||
|
{
|
||||||
|
<option value="@pt">@pt</option>
|
||||||
|
}
|
||||||
|
</InputSelect>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Pokemon Sleep Type, Specialty -->
|
||||||
|
<div class="row mb-3 mx-0">
|
||||||
|
<!-- Sleep Type -->
|
||||||
|
<div class="col ps-0 pe-1">
|
||||||
|
<div class="row input-group m-auto">
|
||||||
|
<span for="SleepType" class="input-group-text rounded-top">Sleep Type</span>
|
||||||
|
</div>
|
||||||
|
<div class="row input-group m-auto">
|
||||||
|
<InputSelect id="SleepType" @bind-Value="NewPokemon.SleepType" @onchange="@SendPokemon" class="form-select rounded-bottom">
|
||||||
|
<option disabled value="" selected>Select...</option>
|
||||||
|
@foreach (var st in SleepTypes)
|
||||||
|
{
|
||||||
|
<option value="@st">@st</option>
|
||||||
|
}
|
||||||
|
</InputSelect>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Speciality -->
|
||||||
|
<div class="col ps-1 pe-0">
|
||||||
|
<div class="row input-group m-auto">
|
||||||
|
<span for="Speciality" class="input-group-text rounded-top">Specialty</span>
|
||||||
|
</div>
|
||||||
|
<div class="row input-group m-auto">
|
||||||
|
<InputSelect id="Speciality" @bind-Value="NewPokemon.Speciality" @onchange="@SendPokemon" class="form-select rounded-bottom">
|
||||||
|
<option disabled value="" selected>Select...</option>
|
||||||
|
@foreach (var sp in Specialities)
|
||||||
|
{
|
||||||
|
<option value="@sp">@sp</option>
|
||||||
|
}
|
||||||
|
</InputSelect>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <br> -->
|
||||||
|
<div class="border-bottom border-3 border-info-subtle rounded m-1 my-3"></div>
|
||||||
|
|
||||||
|
<!-- Images -->
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="input-group m-auto">
|
||||||
|
<span for="ImageUrl" class="input-group-text rounded-start">Base Image URL</span>
|
||||||
|
<InputText id="ImageUrl" @bind-Value="NewPokemon.PokemonImageUrl" @onchange="@SendPokemon" class="form-control rounded-end" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="input-group m-auto">
|
||||||
|
<span for="ShinyImageUrl" class="input-group-text rounded-start">Shiny Image URL</span>
|
||||||
|
<InputText id="ShinyImageUrl" @bind-Value="NewPokemon.PokemonShinyImageUrl" @onchange="@SendPokemon" class="form-control rounded-end" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Flavor -->
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="input-group m-auto">
|
||||||
|
<span for="FlavorText" class="input-group-text rounded-start">Flavor Text</span>
|
||||||
|
<InputText id="FlavorText" @bind-Value="NewPokemon.FlavorText" @onchange="@SendPokemon" class="form-control rounded-end" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <br> -->
|
||||||
|
<div class="border-bottom border-3 border-info-subtle rounded m-1 my-3"></div>
|
||||||
|
|
||||||
|
@if (showErrors && !IsComplete)
|
||||||
|
{
|
||||||
|
<div class="alert alert-warning mt-2">
|
||||||
|
Please complete: @string.Join(", ", MissingFields())
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="d-flex mt-3 justify-content-center gap-3">
|
||||||
|
@if (mostRecentForm)
|
||||||
|
{
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-danger rounded rounded-5 p-1"
|
||||||
|
@onclick="@HandleRemove">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-x-circle" viewBox="0 0 16 16">
|
||||||
|
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16" />
|
||||||
|
<path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-danger rounded rounded-5 p-1"
|
||||||
|
|
||||||
|
disabled>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-x-circle" viewBox="0 0 16 16">
|
||||||
|
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16" />
|
||||||
|
<path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</EditForm>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (formUse == "EDIT")
|
||||||
|
{
|
||||||
|
<div class="pokemon-form-container m-auto bg-info border border-5 border-info-subtle rounded-4 p-3">
|
||||||
|
<EditForm class="col" Model="PokemonToEdit">
|
||||||
|
<DataAnnotationsValidator />
|
||||||
|
|
||||||
|
<div class="bg-primary-subtle rounded"><p class="fs-3 fw-light text-center card-title">Edit Pokemon</p></div>
|
||||||
|
|
||||||
|
<!-- Pokemon Number and Name -->
|
||||||
|
<div class="row mt-1">
|
||||||
|
<div class="col input-group mb-2">
|
||||||
|
<span class="input-group-text text-sm-center rounded-start">#</span>
|
||||||
|
<InputNumber min="1"
|
||||||
|
placeholder="Pokedex #"
|
||||||
|
id="PokemonId"
|
||||||
|
@bind-Value="PokemonToEdit.PokemonId"
|
||||||
|
@onchange="@SendPokemon"
|
||||||
|
class="form-control "
|
||||||
|
type="number" />
|
||||||
|
<InputText placeholder="Pokemon Name"
|
||||||
|
id="PokemonName"
|
||||||
|
@bind-Value="PokemonToEdit.PokemonName"
|
||||||
|
@onchange="@SendPokemon"
|
||||||
|
class="form-control w-50 rounded-end" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Variation Check -->
|
||||||
|
<div class="d-flex flex-row justify-content-start input-group ">
|
||||||
|
<InputCheckbox id="IsVariation"
|
||||||
|
@bind-Value="PokemonToEdit.IsVariation"
|
||||||
|
@onclick="@Toggle"
|
||||||
|
@onchange="@SendPokemon"
|
||||||
|
class="form-check-input p-3 rounded" />
|
||||||
|
<span class="input-group-text ms-1 @GetRoundingClass()">Variation?</span>
|
||||||
|
<InputText placeholder="How So?"
|
||||||
|
id="VariationName"
|
||||||
|
@bind-Value="PokemonToEdit.VariationName"
|
||||||
|
@onchange="@SendPokemon"
|
||||||
|
class="form-control rounded-end"
|
||||||
|
hidden="@HideLabel" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <br> -->
|
||||||
|
<div class="border-bottom border-3 border-info-subtle rounded m-1 my-3"></div>
|
||||||
|
|
||||||
|
<!-- Pokemon Type -->
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="input-group m-auto">
|
||||||
|
<span for="PokemonType" class="input-group-text rounded-start">Pokemon Type</span>
|
||||||
|
<InputSelect id="PokemonType" @bind-Value="PokemonToEdit.PokemonType" class="form-select rounded-end" @onchange="@SendPokemon">
|
||||||
|
<option disabled value="" selected>Select...</option>
|
||||||
|
@foreach (var pt in PokemonTypes)
|
||||||
|
{
|
||||||
|
<option value="@pt">@pt</option>
|
||||||
|
}
|
||||||
|
</InputSelect>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Pokemon Sleep Type, Specialty -->
|
||||||
|
<div class="row mb-3 mx-0">
|
||||||
|
<!-- Sleep Type -->
|
||||||
|
<div class="col ps-0 pe-1">
|
||||||
|
<div class="row input-group m-auto">
|
||||||
|
<span for="SleepType" class="input-group-text rounded-top">Sleep Type</span>
|
||||||
|
</div>
|
||||||
|
<div class="row input-group m-auto">
|
||||||
|
<InputSelect id="SleepType" @bind-Value="PokemonToEdit.SleepType" class="form-select rounded-bottom" @onchange="@SendPokemon">
|
||||||
|
<option disabled value="" selected>Select...</option>
|
||||||
|
@foreach (var st in SleepTypes)
|
||||||
|
{
|
||||||
|
<option value="@st">@st</option>
|
||||||
|
}
|
||||||
|
</InputSelect>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Speciality -->
|
||||||
|
<div class="col ps-1 pe-0">
|
||||||
|
<div class="row input-group m-auto">
|
||||||
|
<span for="Speciality" class="input-group-text rounded-top">Specialty</span>
|
||||||
|
</div>
|
||||||
|
<div class="row input-group m-auto">
|
||||||
|
<InputSelect id="Speciality" @bind-Value="PokemonToEdit.Speciality" class="form-select rounded-bottom" @onchange="@SendPokemon">
|
||||||
|
<option disabled value="" selected>Select...</option>
|
||||||
|
@foreach (var sp in Specialities)
|
||||||
|
{
|
||||||
|
<option value="@sp">@sp</option>
|
||||||
|
}
|
||||||
|
</InputSelect>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <br> -->
|
||||||
|
<div class="border-bottom border-3 border-info-subtle rounded m-1 my-3"></div>
|
||||||
|
|
||||||
|
<!-- Images -->
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="input-group m-auto">
|
||||||
|
<span for="ImageUrl" class="input-group-text rounded-start">Base Image URL</span>
|
||||||
|
<InputText id="ImageUrl" @bind-Value="PokemonToEdit.PokemonImageUrl" class="form-control rounded-end" @onchange="@SendPokemon" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="input-group m-auto">
|
||||||
|
<span for="ShinyImageUrl" class="input-group-text rounded-start">Shiny Image URL</span>
|
||||||
|
<InputText id="ShinyImageUrl" @bind-Value="PokemonToEdit.PokemonShinyImageUrl" class="form-control rounded-end" @onchange="@SendPokemon" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Flavor -->
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="input-group m-auto">
|
||||||
|
<span for="FlavorText" class="input-group-text rounded-start">Flavor Text</span>
|
||||||
|
<InputText id="FlavorText" @bind-Value="PokemonToEdit.FlavorText" class="form-control rounded-end" @onchange="@SendPokemon" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <br> -->
|
||||||
|
<div class="border-bottom border-3 border-info-subtle rounded m-1 my-3"></div>
|
||||||
|
|
||||||
|
@if (showErrors && !IsComplete)
|
||||||
|
{
|
||||||
|
<div class="alert alert-warning mt-2">
|
||||||
|
Please complete: @string.Join(", ", MissingFields())
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="d-flex mt-3 justify-content-center gap-3">
|
||||||
|
@if (mostRecentForm)
|
||||||
|
{
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-danger rounded rounded-5 p-1"
|
||||||
|
@onclick="@HandleRemove">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-x-circle" viewBox="0 0 16 16">
|
||||||
|
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16" />
|
||||||
|
<path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</EditForm>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,162 @@
|
||||||
|
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<Pokemon> 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<string> 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);
|
||||||
|
Console.WriteLine(edit);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,10 +8,8 @@ $display-font-sizes: (
|
||||||
6: 2.5rem
|
6: 2.5rem
|
||||||
);
|
);
|
||||||
|
|
||||||
.create-container {
|
.pokemon-form-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
|
||||||
max-width: 390px; /* Prevent it from getting too huge */
|
|
||||||
aspect-ratio: 3 / 4; /* Maintains card shape dynamically */
|
aspect-ratio: 3 / 4; /* Maintains card shape dynamically */
|
||||||
background-color: var(--bg-color);
|
background-color: var(--bg-color);
|
||||||
border-width: .5rem;
|
border-width: .5rem;
|
||||||
|
|
@ -24,5 +22,4 @@ $display-font-sizes: (
|
||||||
.checkbox-styling {
|
.checkbox-styling {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
|
|
||||||
<!-- Search Input -->
|
<!-- Search Input -->
|
||||||
<div class="pokemon-selector p-3 bg-light">
|
<div class="pokemon-selector p-3 bg-light">
|
||||||
<input class="form-control mb-3" placeholder="Search Pokémon..." @bind="SearchTerm" @oninput="HandleSearch" />
|
<input class="form-control mb-3 rounded rounded-5" placeholder="Search Pokémon..." @bind="SearchTerm" @oninput="HandleSearch" />
|
||||||
|
|
||||||
<!-- Scrollable Pokémon Grid -->
|
<!-- Scrollable Pokémon Grid -->
|
||||||
<div class="row pokemon-grid">
|
<div class="row pokemon-grid pt-1">
|
||||||
@foreach (var pokemon in FilteredPokemon)
|
@foreach (var pokemon in FilteredPokemon)
|
||||||
{
|
{
|
||||||
bool isSelected = SelectedPokemon?.Id == pokemon.Id;
|
bool isSelected = SelectedPokemon?.Id == pokemon.Id;
|
||||||
|
|
||||||
<div class="col-6 col-md-3 mb-3">
|
<div class="col-6 col-md-3 mb-3">
|
||||||
<div class="card pokemon-card small-card @(isSelected ? "border-primary border-2 shadow" : "border-2 border-white")"
|
<div class="card pokemon-card small-card @(isSelected ? "border-primary border-2 shadow" : "border-2 border-white") rounded rounded-3"
|
||||||
@onclick="() => SelectPokemon(pokemon)">
|
@onclick="() => SelectPokemon(pokemon)">
|
||||||
<img src="@pokemon.PokemonImageUrl" class="card-img-top" style="height: 50px; object-fit: contain;" />
|
<img src="@pokemon.PokemonImageUrl" class="card-img-top" style="height: 50px; object-fit: contain;" />
|
||||||
<div class="card-body p-2 text-center">
|
<div class="card-body p-2 text-center">
|
||||||
|
|
@ -21,7 +21,3 @@
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
@ -5,11 +5,13 @@
|
||||||
border-radius: 5% / 3.5%;
|
border-radius: 5% / 3.5%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.pokemon-grid {
|
.pokemon-grid {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
align-content: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -19,7 +21,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.pokemon-card:hover {
|
.pokemon-card:hover {
|
||||||
transform: scale(1.05);
|
transform: scale(1.13);
|
||||||
}
|
}
|
||||||
|
|
||||||
.small-card {
|
.small-card {
|
||||||
|
|
|
||||||
|
|
@ -5,20 +5,17 @@
|
||||||
@attribute [StreamRendering]
|
@attribute [StreamRendering]
|
||||||
@rendermode InteractiveServer
|
@rendermode InteractiveServer
|
||||||
|
|
||||||
<div class="d-flex justify-content-end">
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<!-- Table A: Desktop View-->
|
<!-- Table A: Desktop View-->
|
||||||
<div class="container d-none d-md-block " style="height: 70vh;">
|
<div class="container d-none d-md-block" style="height: 70vh;">
|
||||||
<!-- Main UI -->
|
<!-- Main UI -->
|
||||||
<div class="border-0 mt-4 mx-auto col-12 col-md-10 col-lg-8 pokemontable ">
|
<div class="border-0 mt-4 mx-auto col-12 col-md-10 col-lg-8 pokemontable">
|
||||||
<!-- Table Header -->
|
<!-- Table Header -->
|
||||||
<div class="row bg-secondary bg-gradient py-3 border-0">
|
<div class="row bg-secondary bg-gradient py-3 border-0 rounded-top">
|
||||||
<div class="d-flex align-items-center justify-content-between w-100 position-relative px-3">
|
<div class="d-flex align-items-center justify-content-between w-100 position-relative px-3">
|
||||||
|
|
||||||
<!-- Left: Search -->
|
<!-- Left: Search -->
|
||||||
<input class="form-control w-25 me-3"
|
<input class="form-control w-25 me-3 rounded rounded-5"
|
||||||
placeholder="Search Pokémon..."
|
placeholder="Search Pokémon..."
|
||||||
@bind="SearchTerm"
|
@bind="SearchTerm"
|
||||||
@oninput="HandleSearch" />
|
@oninput="HandleSearch" />
|
||||||
|
|
@ -33,7 +30,7 @@
|
||||||
<div class="badge bg-info">
|
<div class="badge bg-info">
|
||||||
<p class="statText mb-0">@(pokemons.Count()) Pokémon</p>
|
<p class="statText mb-0">@(pokemons.Count()) Pokémon</p>
|
||||||
</div>
|
</div>
|
||||||
<PokemonDownload _Pokemon="pokemons" />
|
<PokemonDownloadButton _Pokemon="pokemons" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -43,8 +40,8 @@
|
||||||
<div class="tableFixHead d-flex flex-column justify-content-start bg-secondary table-responsive row ">
|
<div class="tableFixHead d-flex flex-column justify-content-start bg-secondary table-responsive row ">
|
||||||
<table class="table table-borderless border-0 table-secondary table-striped align-middle">
|
<table class="table table-borderless border-0 table-secondary table-striped align-middle">
|
||||||
<!-- Table Head -->
|
<!-- Table Head -->
|
||||||
<thead class="">
|
<thead>
|
||||||
<tr class="">
|
<tr>
|
||||||
<th class="text-white text-bg-info col-2 d-none d-md-table-cell" scope="col"></th>
|
<th class="text-white text-bg-info col-2 d-none d-md-table-cell" scope="col"></th>
|
||||||
<th class="text-white text-bg-info col-1" scope="col">#</th>
|
<th class="text-white text-bg-info col-1" scope="col">#</th>
|
||||||
<th class="text-white text-bg-info col-2" scope="col">Pokémon</th>
|
<th class="text-white text-bg-info col-2" scope="col">Pokémon</th>
|
||||||
|
|
@ -68,7 +65,7 @@
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<!-- Table Body -->
|
<!-- Table Body -->
|
||||||
<tbody class="">
|
<tbody>
|
||||||
<tr></tr>
|
<tr></tr>
|
||||||
@if (FilteredPokemon != null && FilteredPokemon.Any())
|
@if (FilteredPokemon != null && FilteredPokemon.Any())
|
||||||
{
|
{
|
||||||
|
|
@ -104,7 +101,7 @@
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<!-- Section 2: Pokemon # -->
|
<!-- Section 2: Pokemon # -->
|
||||||
<th class="" scope="row" style="cursor: default;">@pokemon.PokemonId</th>
|
<th scope="row" style="cursor: default;">@pokemon.PokemonId</th>
|
||||||
|
|
||||||
|
|
||||||
<!-- Section 3: Pokemon Name -->
|
<!-- Section 3: Pokemon Name -->
|
||||||
|
|
@ -114,21 +111,21 @@
|
||||||
|
|
||||||
|
|
||||||
<!-- Section 4: Pokemon Type -->
|
<!-- Section 4: Pokemon Type -->
|
||||||
<td class="">
|
<td>
|
||||||
<div class="d-flex justify-content-center">
|
<div class="d-flex justify-content-center">
|
||||||
<img src="@GetTypeImageUrl(pokemon.PokemonType)" style="width:36px; height:36px;" />
|
<img src="@GetTypeImageUrl(pokemon.PokemonType)" style="width:36px; height:36px;" />
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<!-- Section 5: Sleep Type -->
|
<!-- Section 5: Sleep Type -->
|
||||||
<td class="" style="">
|
<td>
|
||||||
<div class="d-flex justify-content-center ">
|
<div class="d-flex justify-content-center ">
|
||||||
<PokemonBadge BadgeItem="@pokemon.SleepType" />
|
<PokemonBadge BadgeItem="@pokemon.SleepType" />
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<!-- Section 6: Speciality -->
|
<!-- Section 6: Speciality -->
|
||||||
<td class="" style="">
|
<td>
|
||||||
<div class="d-flex justify-content-center">
|
<div class="d-flex justify-content-center">
|
||||||
<PokemonBadge BadgeItem="@pokemon.Speciality" />
|
<PokemonBadge BadgeItem="@pokemon.Speciality" />
|
||||||
|
|
||||||
|
|
@ -137,10 +134,10 @@
|
||||||
|
|
||||||
@if (adminToggle)
|
@if (adminToggle)
|
||||||
{
|
{
|
||||||
<td class="" style="">
|
<td>
|
||||||
<div class="d-flex justify-content-center">
|
<div class="d-flex justify-content-center">
|
||||||
<PokemonEditButton PokemonId="@pokemon.PokemonId" />
|
<PokemonEditButton PokemonId="@pokemon.PokemonId" />
|
||||||
|
@*<button @onclick="() => ConfirmDelete(pokemon.Id)">Delete</button>*@
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
}
|
}
|
||||||
|
|
@ -203,10 +200,10 @@
|
||||||
@foreach (var pokemon in pokemons)
|
@foreach (var pokemon in pokemons)
|
||||||
{
|
{
|
||||||
<tr class="border-0">
|
<tr class="border-0">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center" style="border: 1px dashed hotpink;">
|
||||||
|
|
||||||
<!-- Pokemon Image -->
|
<!-- Pokemon Image -->
|
||||||
<div class="me-3">
|
<div class="me-3" style="border: 1px dashed hotpink;">
|
||||||
<div class="flip-container-sm" @onclick="() => ToggleImage(pokemon.Id)">
|
<div class="flip-container-sm" @onclick="() => ToggleImage(pokemon.Id)">
|
||||||
<div class="flipper-sm @(isShiny[pokemon.Id] ? "flipped" : "")">
|
<div class="flipper-sm @(isShiny[pokemon.Id] ? "flipped" : "")">
|
||||||
<img class="front img-fluid" src="@pokemon.PokemonImageUrl" />
|
<img class="front img-fluid" src="@pokemon.PokemonImageUrl" />
|
||||||
|
|
@ -218,7 +215,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="">
|
<div style="border: 1px dashed hotpink;">
|
||||||
<!-- Number and Name -->
|
<!-- Number and Name -->
|
||||||
<h5>
|
<h5>
|
||||||
@pokemon.PokemonId -
|
@pokemon.PokemonId -
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,8 @@ else
|
||||||
|
|
||||||
<div class="mx-1 align-content-center">
|
<div class="mx-1 align-content-center">
|
||||||
<div class="addcard">
|
<div class="addcard">
|
||||||
<PokemonAddForm
|
<PokemonForm
|
||||||
|
formUse="ADD"
|
||||||
OnPokemonReady="ReceivePokemon1"
|
OnPokemonReady="ReceivePokemon1"
|
||||||
mostRecentForm=false
|
mostRecentForm=false
|
||||||
/>
|
/>
|
||||||
|
|
@ -44,9 +45,10 @@ else
|
||||||
{
|
{
|
||||||
<div class="mx-1 align-content-center">
|
<div class="mx-1 align-content-center">
|
||||||
<div class="addcard">
|
<div class="addcard">
|
||||||
<PokemonAddForm OnPokemonReady="ReceivePokemon2"
|
<PokemonForm OnPokemonReady="ReceivePokemon2"
|
||||||
RemoveForm="TogglePokemon2FormView"
|
formUse="ADD"
|
||||||
mostRecentForm="@pokemon2FormView" />
|
RemoveForm="TogglePokemon2FormView"
|
||||||
|
mostRecentForm="@pokemon2FormView" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mx-1 align-content-center">
|
<div class="mx-1 align-content-center">
|
||||||
|
|
@ -58,16 +60,18 @@ else
|
||||||
{
|
{
|
||||||
<div class="mx-1 align-content-center">
|
<div class="mx-1 align-content-center">
|
||||||
<div class="addcard">
|
<div class="addcard">
|
||||||
<PokemonAddForm OnPokemonReady="ReceivePokemon2"
|
<PokemonForm OnPokemonReady="ReceivePokemon2"
|
||||||
RemoveForm="TogglePokemon2FormView"
|
formUse="ADD"
|
||||||
mostRecentForm="@pokemon2FormView" />
|
RemoveForm="TogglePokemon2FormView"
|
||||||
|
mostRecentForm="@pokemon2FormView" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mx-1 align-content-center">
|
<div class="mx-1 align-content-center">
|
||||||
<div class="addcard">
|
<div class="addcard">
|
||||||
<PokemonAddForm OnPokemonReady="ReceivePokemon3"
|
<PokemonForm OnPokemonReady="ReceivePokemon3"
|
||||||
RemoveForm="TogglePokemon3FormView"
|
formUse="ADD"
|
||||||
mostRecentForm="@pokemon3FormView" />
|
RemoveForm="TogglePokemon3FormView"
|
||||||
|
mostRecentForm="@pokemon3FormView" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
@ -76,7 +80,7 @@ else
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex justify-content-center">
|
<div class="d-flex justify-content-center pt-3">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button @onclick="@HandleAdd" class="btn btn-primary rounded">Add Pokemon</button>
|
<button @onclick="@HandleAdd" class="btn btn-primary rounded">Add Pokemon</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -60,32 +60,32 @@ namespace Portfolio.WebUI.Server.Components.Pages.Pokemon_Pages
|
||||||
*/
|
*/
|
||||||
if (!pokemon2FormView && !pokemon3FormView)
|
if (!pokemon2FormView && !pokemon3FormView)
|
||||||
{
|
{
|
||||||
if(IsComplete(pokemon1))
|
//if(IsComplete(pokemon1))
|
||||||
{
|
//{
|
||||||
await HandleSubmit(pokemon1);
|
await HandleSubmit(pokemon1);
|
||||||
Navigation.NavigateTo("/pokemon");
|
Navigation.NavigateTo("/pokemon");
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
else if (pokemon2FormView)
|
else if (pokemon2FormView)
|
||||||
{
|
{
|
||||||
if (IsComplete(pokemon1) && IsComplete(pokemon2))
|
//if (IsComplete(pokemon1) && IsComplete(pokemon2))
|
||||||
{
|
//{
|
||||||
await HandleSubmit(pokemon1);
|
await HandleSubmit(pokemon1);
|
||||||
await HandleSubmit(pokemon2);
|
await HandleSubmit(pokemon2);
|
||||||
Navigation.NavigateTo("/pokemon");
|
Navigation.NavigateTo("/pokemon");
|
||||||
|
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
else if (pokemon3FormView)
|
else if (pokemon3FormView)
|
||||||
{
|
{
|
||||||
if (IsComplete(pokemon1) && IsComplete(pokemon2) && IsComplete(pokemon3))
|
//if (IsComplete(pokemon1) && IsComplete(pokemon2) && IsComplete(pokemon3))
|
||||||
{
|
//{
|
||||||
await HandleSubmit(pokemon1);
|
await HandleSubmit(pokemon1);
|
||||||
await HandleSubmit(pokemon2);
|
await HandleSubmit(pokemon2);
|
||||||
await HandleSubmit(pokemon3);
|
await HandleSubmit(pokemon3);
|
||||||
Navigation.NavigateTo("/pokemon");
|
Navigation.NavigateTo("/pokemon");
|
||||||
|
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,5 @@
|
||||||
.addcard {
|
.addcard {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 30rem;
|
max-width: 25rem;
|
||||||
flex: 0 0 auto; /* prevent flex shrink/grow */
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0.5rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
@page "/pokemonsleep/edit/{id:int}"
|
@page "/pokemonsleep/edit/{id:int}"
|
||||||
@inject IPokemonService PokemonService
|
@inject IPokemonService PokemonService
|
||||||
@inject NavigationManager Navigation
|
@inject NavigationManager Navigation
|
||||||
@inject IJSRuntime JSRuntime
|
@inject IJSRuntime JS
|
||||||
|
|
||||||
@attribute [StreamRendering]
|
@attribute [StreamRendering]
|
||||||
@rendermode InteractiveServer
|
@rendermode InteractiveServer
|
||||||
|
|
@ -12,122 +12,33 @@
|
||||||
|
|
||||||
@if (pokemon == null)
|
@if (pokemon == null)
|
||||||
{
|
{
|
||||||
<p><em>Loading...</em></p>
|
<Loading />
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<!-- Total Componenet-->
|
|
||||||
<div class="w-50 mt-3 m-auto bg-info edit-container">
|
|
||||||
|
|
||||||
<!-- Header -->
|
<div class="container mx-0 px-0">
|
||||||
<div class="card-header bg-secondary ml-0 py-3 w-100 ">
|
<div class="row mt-5">
|
||||||
<div class="row">
|
<div class="d-flex justify-content-evenly h-100 p-0">
|
||||||
<div class="col-12 text-center">
|
|
||||||
<h2 class="text-info">Edit Pokémon</h2>
|
<div class="mx-1 align-content-center">
|
||||||
|
<div class="addcard">
|
||||||
|
<PokemonForm
|
||||||
|
formUse="EDIT"
|
||||||
|
OnPokemonReady="ReceivePokemon"
|
||||||
|
RemoveForm="Cancel"
|
||||||
|
mostRecentForm=true
|
||||||
|
PokemonToEdit="pokemon"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<!-- Body -->
|
<div class="d-flex justify-content-center">
|
||||||
<div class="p-3 w-100 flex-column ">
|
<div class="btn-group">
|
||||||
<EditForm class="col mb-3" Model="pokemon" OnValidSubmit="HandleSubmit">
|
<button @onclick="@HandleSubmit" class="btn btn-primary rounded">Edit Pokemon</button>
|
||||||
<DataAnnotationsValidator />
|
|
||||||
|
|
||||||
<!-- Dex Number and Name -->
|
|
||||||
<div class="row ">
|
|
||||||
<div class="col-sm-3 input-group mb-3">
|
|
||||||
<span for="PokemonId" class="input-group-text">#</span>
|
|
||||||
<InputNumber min="0" id="PokemonId" @bind-Value="pokemon.PokemonId" class="form-control" required disabled />
|
|
||||||
<InputText id="PokemonName" @bind-Value="pokemon.PokemonName" class="form-control w-75" required />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Pokemon Type, Sleep Type, and Speciality -->
|
|
||||||
<div class="row">
|
|
||||||
<!-- Pokemon Type -->
|
|
||||||
<div class="col mb-3 m-auto">
|
|
||||||
<label for="PokemonType" class="form-label">Pokemon Type</label>
|
|
||||||
<InputSelect id="PokemonType" @bind-Value="pokemon.PokemonType" class="form-select">
|
|
||||||
<option dsabled value="">Select Type</option>
|
|
||||||
<option value="Grass">Grass</option>
|
|
||||||
<option value="Fire">Fire</option>
|
|
||||||
<option value="Water">Water</option>
|
|
||||||
<option value="Normal">Normal</option>
|
|
||||||
<option value="Flying">Flying</option>
|
|
||||||
<option value="Bug">Bug</option>
|
|
||||||
<option value="Poison">Poison</option>
|
|
||||||
<option value="Electric">Electric</option>
|
|
||||||
<option value="Ground">Ground</option>
|
|
||||||
<option value="Rock">Rock</option>
|
|
||||||
<option value="Ice">Ice</option>
|
|
||||||
<option value="Steel">Steel</option>
|
|
||||||
<option value="Fighting">Fighting</option>
|
|
||||||
<option value="Psychic">Psychic</option>
|
|
||||||
<option value="Dark">Dark</option>
|
|
||||||
<option value="Fairy">Fairy</option>
|
|
||||||
<option value="Ghost">Ghost</option>
|
|
||||||
<option value="Dragon">Dragon</option>
|
|
||||||
</InputSelect>
|
|
||||||
</div>
|
|
||||||
<!-- Sleep Type -->
|
|
||||||
<div class="col mb-3 m-auto">
|
|
||||||
<label for="SleepType" class="form-label">Sleep Type</label>
|
|
||||||
<InputSelect id="SleepType" @bind-Value="pokemon.SleepType" class="form-select">
|
|
||||||
<option value="Dozing">Dozing</option>
|
|
||||||
<option value="Snoozing">Snoozing</option>
|
|
||||||
<option value="Slumbering">Slumbering</option>
|
|
||||||
</InputSelect>
|
|
||||||
</div>
|
|
||||||
<!-- Speciality-->
|
|
||||||
<div class="col mb-3 m-auto">
|
|
||||||
<label for="Speciality" class="form-label">Specialty</label>
|
|
||||||
<InputSelect id="Speciality" @bind-Value="pokemon.Speciality" class="form-select">
|
|
||||||
<option value="Berries">Berries</option>
|
|
||||||
<option value="Ingredients">Ingredients</option>
|
|
||||||
<option value="Skills">Skills</option>
|
|
||||||
</InputSelect>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Variation Check -->
|
|
||||||
<div class="row">
|
|
||||||
<div class="input-group mb-3">
|
|
||||||
<!-- Variation Check -->
|
|
||||||
<div class=" d-inline-flex">
|
|
||||||
<InputCheckbox id="IsVariation" @bind-Value="pokemon.IsVariation" @onclick="@Toggle" class="form-check-input checkbox-styling p-3 mt-1" />
|
|
||||||
<span for="IsVariation" class="input-group-text m-1">Variation?</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Variation Region Input -->
|
|
||||||
<div class="w-75 mx-2 mt-1">
|
|
||||||
|
|
||||||
<InputText placeholder="What Variant? (Alolan, Paldean)" hidden="@HideLabel" id="VariationName" @bind-Value="pokemon.VariationName" class="form-control" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Image URL Input -->
|
|
||||||
<div class="row mb-3 m-auto">
|
|
||||||
<label for="ImageUrl" class="form-label">Base Image URL</label>
|
|
||||||
<InputText id="ImageUrl" @bind-Value="pokemon.PokemonImageUrl" class="form-control" />
|
|
||||||
</div>
|
|
||||||
<!-- Shiny Image URL Input -->
|
|
||||||
<div class="row mb-3 m-auto">
|
|
||||||
<label for="ImageUrl" class="form-label">Shiny Image URL</label>
|
|
||||||
<InputText id="ImageUrl" @bind-Value="pokemon.PokemonShinyImageUrl" class="form-control" />
|
|
||||||
</div>
|
|
||||||
<!-- Flavor Text Input -->
|
|
||||||
<div class="row mb-3 m-auto">
|
|
||||||
<label for="FlavorText" class="form-label">Flavor Text</label>
|
|
||||||
<InputText id="FlavorText" @bind-Value="pokemon.FlavorText" class="form-control" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Form Buttons -->
|
|
||||||
<div class="d-flex justify-content-between">
|
|
||||||
<button type="button" class="btn btn-secondary mb-3" @onclick="Cancel">Cancel</button>
|
|
||||||
<button type="submit" class="btn btn-primary mb-3">Save Changes</button>
|
|
||||||
</div>
|
|
||||||
</EditForm>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,16 +14,28 @@ namespace Portfolio.WebUI.Server.Components.Pages.Pokemon_Pages
|
||||||
pokemon = await PokemonService.GetPokemonByIdAsync(Id);
|
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()
|
private async Task HandleSubmit()
|
||||||
{
|
{
|
||||||
await PokemonService.UpdatePokemonAsync(pokemon);
|
await PokemonService.UpdatePokemonAsync(pokemon);
|
||||||
//Navigation.NavigateTo("/pokemonsleep");
|
//Navigation.NavigateTo("/pokemonsleep");
|
||||||
await JSRuntime.InvokeVoidAsync("history.back");
|
await JS.InvokeVoidAsync("history.back");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void Cancel()
|
private async void Cancel()
|
||||||
{
|
{
|
||||||
await JSRuntime.InvokeVoidAsync("history.back");
|
await JS.InvokeVoidAsync("history.back");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
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;
|
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;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue