Compare commits
4 Commits
bc07f56c97
...
2f210a0e1a
| Author | SHA1 | Date |
|---|---|---|
|
|
2f210a0e1a | |
|
|
37d8fdaca2 | |
|
|
286b913832 | |
|
|
d977e08650 |
|
|
@ -0,0 +1,12 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace Portfolio.WebUI.Server.Components.Component
|
||||
{
|
||||
public partial class Loading
|
||||
{
|
||||
[Parameter]
|
||||
public string LoadingString { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<div class="add-card card border-2 border-secondary-subtle rounded-4"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
@onclick="HandleClick">
|
||||
|
||||
<div class="card-body d-flex align-items-center justify-content-center p-4">
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="@IconSize"
|
||||
height="@IconSize"
|
||||
fill="currentColor"
|
||||
class="bi bi-plus-circle-fill"
|
||||
viewBox="0 0 16 16">
|
||||
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M8.5 4.5a.5.5 0 0 0-1 0v3h-3a.5.5 0 0 0 0 1h3v3a.5.5 0 0 0 1 0v-3h3a.5.5 0 0 0 0-1h-3z" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
@code {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
using Microsoft.AspNetCore.Components.Web;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace Portfolio.WebUI.Server.Components.Component.Pokemon_Components
|
||||
{
|
||||
public partial class PokemonAddButton
|
||||
{
|
||||
[Parameter]
|
||||
public EventCallback OnAdd { get; set; }
|
||||
[Parameter]
|
||||
public int IconSize { get; set; } = 64;
|
||||
|
||||
private async Task HandleClick()
|
||||
{
|
||||
await OnAdd.InvokeAsync();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
.add-card {
|
||||
min-width: 160px;
|
||||
min-height: 120px;
|
||||
max-width: 200px;
|
||||
cursor: pointer;
|
||||
background-color: var(--bs-info-subtle);
|
||||
transition: transform .08s ease, box-shadow .08s ease, background-color .08s ease;
|
||||
}
|
||||
|
||||
.add-card:hover {
|
||||
background-color: var(--bs-light);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.add-card:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 .25rem rgba(13,110,253,.25);
|
||||
}
|
||||
|
||||
.add-card[aria-disabled="true"] {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
|
@ -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> _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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
$display-font-sizes: (
|
||||
1: 5rem,
|
||||
2: 4.5rem,
|
||||
3: 4rem,
|
||||
4: 3.5rem,
|
||||
5: 3rem,
|
||||
6: 2.5rem
|
||||
);
|
||||
|
||||
.pokemon-form-container {
|
||||
position: relative;
|
||||
aspect-ratio: 3 / 4; /* Maintains card shape dynamically */
|
||||
background-color: var(--bg-color);
|
||||
border-width: .5rem;
|
||||
border-style: solid;
|
||||
border-radius: 5% / 3.5%;
|
||||
border-color: var(--border-color);
|
||||
box-shadow: 0 0 10px var(--border-color);
|
||||
}
|
||||
|
||||
.checkbox-styling {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
|
||||
<!-- Search Input -->
|
||||
<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 -->
|
||||
<div class="row pokemon-grid">
|
||||
<div class="row pokemon-grid pt-1">
|
||||
@foreach (var pokemon in FilteredPokemon)
|
||||
{
|
||||
bool isSelected = SelectedPokemon?.Id == pokemon.Id;
|
||||
|
||||
<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)">
|
||||
<img src="@pokemon.PokemonImageUrl" class="card-img-top" style="height: 50px; object-fit: contain;" />
|
||||
<div class="card-body p-2 text-center">
|
||||
|
|
@ -21,7 +21,3 @@
|
|||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
|
@ -5,11 +5,13 @@
|
|||
border-radius: 5% / 3.5%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
}
|
||||
|
||||
.pokemon-grid {
|
||||
flex: 1 1 auto;
|
||||
overflow-y: auto;
|
||||
align-content: flex-start;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -19,7 +21,7 @@
|
|||
}
|
||||
|
||||
.pokemon-card:hover {
|
||||
transform: scale(1.05);
|
||||
transform: scale(1.13);
|
||||
}
|
||||
|
||||
.small-card {
|
||||
|
|
|
|||
|
|
@ -5,20 +5,17 @@
|
|||
@attribute [StreamRendering]
|
||||
@rendermode InteractiveServer
|
||||
|
||||
<div class="d-flex justify-content-end">
|
||||
|
||||
|
||||
</div>
|
||||
<!-- 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 -->
|
||||
<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 -->
|
||||
<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">
|
||||
|
||||
<!-- 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..."
|
||||
@bind="SearchTerm"
|
||||
@oninput="HandleSearch" />
|
||||
|
|
@ -33,7 +30,7 @@
|
|||
<div class="badge bg-info">
|
||||
<p class="statText mb-0">@(pokemons.Count()) Pokémon</p>
|
||||
</div>
|
||||
<PokemonDownload _Pokemon="pokemons" />
|
||||
<PokemonDownloadButton _Pokemon="pokemons" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -43,8 +40,8 @@
|
|||
<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 Head -->
|
||||
<thead class="">
|
||||
<tr class="">
|
||||
<thead>
|
||||
<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-1" scope="col">#</th>
|
||||
<th class="text-white text-bg-info col-2" scope="col">Pokémon</th>
|
||||
|
|
@ -68,7 +65,7 @@
|
|||
else
|
||||
{
|
||||
<!-- Table Body -->
|
||||
<tbody class="">
|
||||
<tbody>
|
||||
<tr></tr>
|
||||
@if (FilteredPokemon != null && FilteredPokemon.Any())
|
||||
{
|
||||
|
|
@ -104,7 +101,7 @@
|
|||
</td>
|
||||
|
||||
<!-- 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 -->
|
||||
|
|
@ -114,21 +111,21 @@
|
|||
|
||||
|
||||
<!-- Section 4: Pokemon Type -->
|
||||
<td class="">
|
||||
<td>
|
||||
<div class="d-flex justify-content-center">
|
||||
<img src="@GetTypeImageUrl(pokemon.PokemonType)" style="width:36px; height:36px;" />
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<!-- Section 5: Sleep Type -->
|
||||
<td class="" style="">
|
||||
<td>
|
||||
<div class="d-flex justify-content-center ">
|
||||
<PokemonBadge BadgeItem="@pokemon.SleepType" />
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<!-- Section 6: Speciality -->
|
||||
<td class="" style="">
|
||||
<td>
|
||||
<div class="d-flex justify-content-center">
|
||||
<PokemonBadge BadgeItem="@pokemon.Speciality" />
|
||||
|
||||
|
|
@ -137,10 +134,10 @@
|
|||
|
||||
@if (adminToggle)
|
||||
{
|
||||
<td class="" style="">
|
||||
<td>
|
||||
<div class="d-flex justify-content-center">
|
||||
<PokemonEditButton PokemonId="@pokemon.PokemonId" />
|
||||
|
||||
@*<button @onclick="() => ConfirmDelete(pokemon.Id)">Delete</button>*@
|
||||
</div>
|
||||
</td>
|
||||
}
|
||||
|
|
@ -203,10 +200,10 @@
|
|||
@foreach (var pokemon in pokemons)
|
||||
{
|
||||
<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 -->
|
||||
<div class="me-3">
|
||||
<div class="me-3" style="border: 1px dashed hotpink;">
|
||||
<div class="flip-container-sm" @onclick="() => ToggleImage(pokemon.Id)">
|
||||
<div class="flipper-sm @(isShiny[pokemon.Id] ? "flipped" : "")">
|
||||
<img class="front img-fluid" src="@pokemon.PokemonImageUrl" />
|
||||
|
|
@ -218,7 +215,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="">
|
||||
<div style="border: 1px dashed hotpink;">
|
||||
<!-- Number and Name -->
|
||||
<h5>
|
||||
@pokemon.PokemonId -
|
||||
|
|
|
|||
|
|
@ -3,11 +3,9 @@
|
|||
<div class="page">
|
||||
<main class="">
|
||||
<NavMenu3 />
|
||||
<article class="container ">
|
||||
<div class="">
|
||||
<div class="container">
|
||||
@Body
|
||||
</div>
|
||||
</article>
|
||||
</main>
|
||||
@* <MadeWithLoveFooter/> *@
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
@inject IPokemonService PokemonService
|
||||
@inject NavigationManager Navigation
|
||||
|
||||
@inject IJSRuntime JS
|
||||
|
||||
@attribute [StreamRendering]
|
||||
@rendermode InteractiveServer
|
||||
|
||||
|
|
@ -17,119 +19,72 @@
|
|||
}
|
||||
else
|
||||
{
|
||||
<div class="w-50 mt-5 m-auto create-container bg-info border border-5 border-info-subtle">
|
||||
<div class="container mx-0 px-0">
|
||||
<div class="row mt-5">
|
||||
<div class="d-flex justify-content-evenly h-100 p-0">
|
||||
|
||||
<div class="mx-1 align-content-center">
|
||||
<div class="addcard">
|
||||
<PokemonForm
|
||||
formUse="ADD"
|
||||
OnPokemonReady="ReceivePokemon1"
|
||||
mostRecentForm=false
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@if(!pokemon2FormView && !pokemon3FormView)
|
||||
{
|
||||
<div class="mx-1 align-content-center">
|
||||
<PokemonAddButton OnAdd="TogglePokemon2FormView" />
|
||||
</div>
|
||||
}
|
||||
|
||||
else if (pokemon2FormView && !pokemon3FormView)
|
||||
{
|
||||
<div class="mx-1 align-content-center">
|
||||
<div class="addcard">
|
||||
<PokemonForm OnPokemonReady="ReceivePokemon2"
|
||||
formUse="ADD"
|
||||
RemoveForm="TogglePokemon2FormView"
|
||||
mostRecentForm="@pokemon2FormView" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="mx-1 align-content-center">
|
||||
<PokemonAddButton OnAdd="TogglePokemon3FormView" />
|
||||
</div>
|
||||
}
|
||||
|
||||
else if (!pokemon2FormView && pokemon3FormView)
|
||||
{
|
||||
<div class="mx-1 align-content-center">
|
||||
<div class="addcard">
|
||||
<PokemonForm OnPokemonReady="ReceivePokemon2"
|
||||
formUse="ADD"
|
||||
RemoveForm="TogglePokemon2FormView"
|
||||
mostRecentForm="@pokemon2FormView" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="mx-1 align-content-center">
|
||||
<div class="addcard">
|
||||
<PokemonForm OnPokemonReady="ReceivePokemon3"
|
||||
formUse="ADD"
|
||||
RemoveForm="TogglePokemon3FormView"
|
||||
mostRecentForm="@pokemon3FormView" />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="card-header rounded-top-3 bg-info py-3">
|
||||
<div class="row text-center">
|
||||
<h2 class="text-white text-decoration-underline">Add New Pokémon</h2>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="p-3" >
|
||||
<EditForm class=" col" Model="NewPokemon" OnValidSubmit="HandleSubmit">
|
||||
<DataAnnotationsValidator />
|
||||
|
||||
<!-- Pokemon Number and Name -->
|
||||
<div class="row mt-3">
|
||||
<div class="col-sm-3 input-group mb-3">
|
||||
<!-- Pokemon #-->
|
||||
<span for="PokemonId" class="input-group-text">#</span>
|
||||
<InputNumber min="0" placeholder="Pokedex #" id="PokemonId" @bind-Value="NewPokemon.PokemonId" class="form-control " required />
|
||||
<!-- Pokemon Name-->
|
||||
<InputText placeholder="Pokemon Name" id="PokemonName" @bind-Value="NewPokemon.PokemonName" class="form-control w-75" required />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pokemon Type, Sleep Type, and Speciality -->
|
||||
<div class="row mb-3">
|
||||
<!-- Pokemon Type -->
|
||||
<div class="col m-auto">
|
||||
<label for="PokemonType" class="form-label">Pokemon Type</label>
|
||||
<InputSelect id="PokemonType" @bind-Value="NewPokemon.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 m-auto">
|
||||
<label for="SleepType" class="form-label">Sleep Type</label>
|
||||
<InputSelect id="SleepType" @bind-Value="NewPokemon.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 m-auto">
|
||||
<label for="Speciality" class="form-label">Specialty</label>
|
||||
<InputSelect id="Speciality" @bind-Value="NewPokemon.Speciality" class="form-select">
|
||||
<option value="Berries">Berries</option>
|
||||
<option value="Ingredients">Ingredients</option>
|
||||
<option value="Skills">Skills</option>
|
||||
<option value="All">All</option>
|
||||
</InputSelect>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- If New Pokemon is Variant -->
|
||||
<div class="row mb-3">
|
||||
<div class="input-group align-items-center">
|
||||
<!-- Variation Check -->
|
||||
<div class="d-flex">
|
||||
<InputCheckbox id="IsVariation" @bind-Value="NewPokemon.IsVariation" @onclick="@Toggle" class="form-check-input checkbox-styling p-3 rounded" />
|
||||
<span for="IsVariation" class="input-group-text mx-2">Variation?</span>
|
||||
</div>
|
||||
|
||||
<!-- Variation Region Input -->
|
||||
<div class="flex-fill">
|
||||
|
||||
<InputText placeholder="What Variant? (Alolan, Paldean)" hidden="@HideLabel" id="VariationName" @bind-Value="NewPokemon.VariationName" class="form-control" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- New Image URL Field -->
|
||||
<div class="row mb-3 m-auto">
|
||||
<label for="ImageUrl" class="form-label">Base Image URL</label>
|
||||
<InputText id="ImageUrl" @bind-Value="NewPokemon.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="NewPokemon.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="NewPokemon.FlavorText" class="form-control" />
|
||||
</div>
|
||||
|
||||
<!-- Form Buttons -->
|
||||
<div class="d-flex mt-5 justify-content-between">
|
||||
<button type="button" class="btn btn-danger rounded rouneded-4 mb-3 " @onclick="Cancel">Cancel</button>
|
||||
<button type="submit" class="btn btn-success rounded rouneded-4 mb-3 ">Add Pokemon</button>
|
||||
</div>
|
||||
</EditForm>
|
||||
</div>
|
||||
<div class="d-flex justify-content-center pt-3">
|
||||
<div class="btn-group">
|
||||
<button @onclick="@HandleAdd" class="btn btn-primary rounded">Add Pokemon</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,32 @@
|
|||
using Microsoft.AspNetCore.Components.Web;
|
||||
using Microsoft.JSInterop;
|
||||
using Portfolio.Domain.Features.Pokemon;
|
||||
|
||||
namespace Portfolio.WebUI.Server.Components.Pages.Pokemon_Pages
|
||||
{
|
||||
public partial class PokemonCreate
|
||||
{
|
||||
|
||||
private bool pokemon2FormView { get; set; } = false;
|
||||
private bool pokemon3FormView { get; set; } = false;
|
||||
|
||||
private bool HideLabel { get; set; } = true;
|
||||
private void Toggle()
|
||||
{
|
||||
HideLabel = !HideLabel;
|
||||
}
|
||||
private void TogglePokemon2FormView()
|
||||
{
|
||||
pokemon2FormView = !pokemon2FormView;
|
||||
}
|
||||
private void TogglePokemon3FormView()
|
||||
{
|
||||
pokemon3FormView = !pokemon3FormView;
|
||||
TogglePokemon2FormView();
|
||||
|
||||
}
|
||||
|
||||
private Pokemon NewPokemon = new Pokemon
|
||||
private Pokemon pokemon1, pokemon2, pokemon3 = new Pokemon
|
||||
{
|
||||
PokemonId = 0, // Or any default ID logic
|
||||
PokemonName = string.Empty, // Required fields cannot be null
|
||||
|
|
@ -27,12 +42,61 @@ namespace Portfolio.WebUI.Server.Components.Pages.Pokemon_Pages
|
|||
{
|
||||
this.ToggleVariationName = true;
|
||||
}
|
||||
private async Task HandleSubmit()
|
||||
private bool IsComplete(Pokemon NewPokemon) =>
|
||||
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 async Task HandleAdd()
|
||||
{
|
||||
/*
|
||||
Okay there are three versions of submits which need to be checked
|
||||
1. Single submit, only one, if both pokemon#FormView is false
|
||||
2. 2 Submit, if pokemon2FormView is true
|
||||
3. 3 Submit, if pokemon3FormView is true
|
||||
*/
|
||||
if (!pokemon2FormView && !pokemon3FormView)
|
||||
{
|
||||
//if(IsComplete(pokemon1))
|
||||
//{
|
||||
await HandleSubmit(pokemon1);
|
||||
Navigation.NavigateTo("/pokemon");
|
||||
//}
|
||||
}
|
||||
else if (pokemon2FormView)
|
||||
{
|
||||
//if (IsComplete(pokemon1) && IsComplete(pokemon2))
|
||||
//{
|
||||
await HandleSubmit(pokemon1);
|
||||
await HandleSubmit(pokemon2);
|
||||
Navigation.NavigateTo("/pokemon");
|
||||
|
||||
// }
|
||||
}
|
||||
else if (pokemon3FormView)
|
||||
{
|
||||
//if (IsComplete(pokemon1) && IsComplete(pokemon2) && IsComplete(pokemon3))
|
||||
//{
|
||||
await HandleSubmit(pokemon1);
|
||||
await HandleSubmit(pokemon2);
|
||||
await HandleSubmit(pokemon3);
|
||||
Navigation.NavigateTo("/pokemon");
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private async Task HandleSubmit(Pokemon NewPokemon)
|
||||
{
|
||||
isSubmitting = true;
|
||||
|
||||
await PokemonService.AddPokemonAsync(NewPokemon);
|
||||
isSubmitting = false;
|
||||
Navigation.NavigateTo("/pokemon");
|
||||
|
||||
}
|
||||
|
||||
protected void Cancel(MouseEventArgs e)
|
||||
|
|
@ -41,5 +105,41 @@ namespace Portfolio.WebUI.Server.Components.Pages.Pokemon_Pages
|
|||
Navigation.NavigateTo("/pokemon");
|
||||
}
|
||||
|
||||
private async Task ReceivePokemon1(Pokemon p)
|
||||
{
|
||||
// Save received pokemon as Pokemon 1
|
||||
pokemon1 = p;
|
||||
|
||||
// Server console (Blazor Server)
|
||||
Console.WriteLine($"[Pokemon 1] #{pokemon1.PokemonId} {pokemon1.PokemonName} | {pokemon1.PokemonType} | {pokemon1.SleepType} | {pokemon1.Speciality} | Var:{pokemon1.IsVariation} {pokemon1.VariationName}");
|
||||
|
||||
// Browser console
|
||||
await JS.InvokeVoidAsync("console.log", "Pokemon 1:", pokemon1);
|
||||
}
|
||||
|
||||
private async Task ReceivePokemon2(Pokemon p)
|
||||
{
|
||||
// Save received pokemon as Pokemon 1
|
||||
pokemon2 = p;
|
||||
|
||||
// Server console (Blazor Server)
|
||||
Console.WriteLine($"[Pokemon 2] #{pokemon2.PokemonId} {pokemon2.PokemonName} | {pokemon2.PokemonType} | {pokemon2.SleepType} | {pokemon2.Speciality} | Var:{pokemon2.IsVariation} {pokemon2.VariationName}");
|
||||
|
||||
// Browser console
|
||||
await JS.InvokeVoidAsync("console.log", "Pokemon 2:", pokemon2);
|
||||
}
|
||||
|
||||
private async Task ReceivePokemon3(Pokemon p)
|
||||
{
|
||||
// Save received pokemon as Pokemon 1
|
||||
pokemon3 = p;
|
||||
|
||||
// Server console (Blazor Server)
|
||||
Console.WriteLine($"[Pokemon 3] #{pokemon3.PokemonId} {pokemon3.PokemonName} | {pokemon3.PokemonType} | {pokemon3.SleepType} | {pokemon3.Speciality} | Var:{pokemon3.IsVariation} {pokemon3.VariationName}");
|
||||
|
||||
// Browser console
|
||||
await JS.InvokeVoidAsync("console.log", "Pokemon 3:", pokemon3);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
|
||||
.create-container {
|
||||
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: 25rem;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
<Loading />
|
||||
}
|
||||
else
|
||||
{
|
||||
<!-- Total Componenet-->
|
||||
<div class="w-50 mt-3 m-auto bg-info edit-container">
|
||||
|
||||
<!-- Header -->
|
||||
<div class="card-header bg-secondary ml-0 py-3 w-100 ">
|
||||
<div class="row">
|
||||
<div class="col-12 text-center">
|
||||
<h2 class="text-info">Edit Pokémon</h2>
|
||||
<div class="container mx-0 px-0">
|
||||
<div class="row mt-5">
|
||||
<div class="d-flex justify-content-evenly h-100 p-0">
|
||||
|
||||
<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>
|
||||
|
||||
<!-- Body -->
|
||||
<div class="p-3 w-100 flex-column ">
|
||||
<EditForm class="col mb-3" Model="pokemon" OnValidSubmit="HandleSubmit">
|
||||
<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 class="d-flex justify-content-center">
|
||||
<div class="btn-group">
|
||||
<button @onclick="@HandleSubmit" class="btn btn-primary rounded">Edit Pokemon</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
@page "/pokemon/{id:int}"
|
||||
@inject IPokemonService PokemonService
|
||||
@inject NavigationManager Navigation
|
||||
|
||||
@attribute [StreamRendering]
|
||||
@rendermode InteractiveServer
|
||||
|
||||
|
||||
<PokemonHeader />
|
||||
|
||||
|
||||
|
||||
@if (_pokemon == null)
|
||||
{
|
||||
<Loading />
|
||||
}
|
||||
else
|
||||
{
|
||||
<PageTitle>@_pokemon.PokemonName</PageTitle>
|
||||
<!-- Total Componenet-->
|
||||
|
||||
<div class="container">
|
||||
<div class="w-75 row mt-4 m-auto">
|
||||
|
||||
<!-- Previous Pokemon Button -->
|
||||
<div class="col-auto">
|
||||
<button class="mt-1 p-2 btn btn-danger rounded-5 align-self-start text-white" disabled="@(!_previousPokemonId.HasValue)" @onclick="NavigateToPrevious">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-arrow-left-circle-fill" viewBox="0 0 16 16">
|
||||
<path d="M8 0a8 8 0 1 0 0 16A8 8 0 0 0 8 0m3.5 7.5a.5.5 0 0 1 0 1H5.707l2.147 2.146a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708l3-3a.5.5 0 1 1 .708.708L5.707 7.5z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Pokemon Presentation -->
|
||||
<div class="mt-5 mx-5 col justify-content-center">
|
||||
@if (_variationPokemonId != null)
|
||||
{
|
||||
@if (_variationPokemonId != null && _pokemonVariant == null){
|
||||
<Loading />
|
||||
}
|
||||
else
|
||||
{
|
||||
<!-- If Variation Pokemon have same PokemonId -->
|
||||
@if(_pokemon.Id != _pokemonVariant.Id)
|
||||
{
|
||||
<div class="d-flex justify-content-center">
|
||||
<div class="pokemoncard m-1">
|
||||
<PokemonCard Pokemon="_pokemon" />
|
||||
</div>
|
||||
|
||||
<div class="pokemoncard m-1">
|
||||
<PokemonCard Pokemon="_pokemonVariant" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
}
|
||||
<!-- If Variation Pokemon has diff PokemonId -->
|
||||
else
|
||||
{
|
||||
<div class="d-flex justify-content-center align-items-center h-100">
|
||||
<div class="pokemoncard">
|
||||
<PokemonCard Pokemon="_pokemonVariant" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
<!-- Standard Pokemon Display -->
|
||||
<div class="d-flex justify-content-center align-items-center h-100">
|
||||
<div class="pokemoncard m-1">
|
||||
<PokemonCard Pokemon="_pokemon" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<!-- Next Pokemon Button -->
|
||||
<div class="col-auto">
|
||||
<button class="mt-1 p-2 btn btn-danger rounded rounded-5 align-self-start text-white" disabled="@(!_nextPokemonId.HasValue)" @onclick="NavigateToNext">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-arrow-right-circle-fill" viewBox="0 0 16 16">
|
||||
<path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0M4.5 7.5a.5.5 0 0 0 0 1h5.793l-2.147 2.146a.5.5 0 0 0 .708.708l3-3a.5.5 0 0 0 0-.708l-3-3a.5.5 0 1 0-.708.708L10.293 7.5z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Portfolio.Domain.Features.Pokemon;
|
||||
|
||||
namespace Portfolio.WebUI.Server.Components.Pages.Pokemon_Pages
|
||||
{
|
||||
public partial class PokemonIndividualView
|
||||
{
|
||||
[Parameter] public int Id { get; set; }
|
||||
private Pokemon? _pokemon;
|
||||
private Pokemon? _pokemonVariant;
|
||||
private List<int> _pokemonIds;
|
||||
private int? _nextPokemonId;
|
||||
private int? _previousPokemonId;
|
||||
private int? _variationPokemonId;
|
||||
private int _currentIndex;
|
||||
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
_pokemon = await PokemonService.GetPokemonByPokemonIdAsync(Id);
|
||||
|
||||
// These can be smart queries if your data is sorted by ID or by another property
|
||||
_pokemonIds = await PokemonService.GetAllPokemonIdsAsync();
|
||||
_currentIndex = _pokemonIds.IndexOf(_pokemon.PokemonId);
|
||||
//Console.WriteLine(_currentIndex);
|
||||
|
||||
_nextPokemonId = await PokemonService.GetNextPokemonIdAsync(Id);
|
||||
_previousPokemonId = await PokemonService.GetPreviousPokemonIdAsync(Id);
|
||||
|
||||
_variationPokemonId = await PokemonService.GetVariationPokemonIdAsync(Id);
|
||||
if (_variationPokemonId != null)
|
||||
{
|
||||
Console.WriteLine(_variationPokemonId);
|
||||
_pokemonVariant = await PokemonService.GetPokemonByIdAsync((int)_variationPokemonId);
|
||||
Console.WriteLine(_pokemonVariant.VariationName);
|
||||
}
|
||||
}
|
||||
|
||||
private void NavigateToNext()
|
||||
{
|
||||
if (_nextPokemonId.HasValue)
|
||||
Navigation.NavigateTo($"/pokemon/{_nextPokemonId.Value}");
|
||||
}
|
||||
|
||||
private void NavigateToPrevious()
|
||||
{
|
||||
if (_previousPokemonId.HasValue)
|
||||
Navigation.NavigateTo($"/pokemon/{_previousPokemonId.Value}");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
.pokemoncard {
|
||||
width: 100%;
|
||||
max-width: 350px;
|
||||
flex: 0 0 auto; /* prevent flex shrink/grow */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
|
@ -1,23 +1,67 @@
|
|||
@page "/pokemon"
|
||||
@page "/pokemonsleep"
|
||||
|
||||
|
||||
@inject IPokemonService PokemonService
|
||||
|
||||
@attribute [StreamRendering]
|
||||
@rendermode InteractiveServer
|
||||
|
||||
|
||||
<PageTitle>Pokémon Sleep</PageTitle>
|
||||
|
||||
<!-- <PokemonBackground PokemonImages="pokemonImageUrls" ShinyPokemonImages="pokemonShinyImageUrls" /> -->
|
||||
<PokemonHeader />
|
||||
|
||||
<div class="w-100">
|
||||
<!-- <PokemonBackground PokemonImages="pokemonImageUrls" ShinyPokemonImages="pokemonShinyImageUrls" /> -->
|
||||
<!-- Card -->
|
||||
<div class="container card shadow-sm border-0 p-3 pb-4 mt-4 m-auto w-75 mb-5 bg-white">
|
||||
|
||||
<PokemonHeader />
|
||||
<!-- Top Row-->
|
||||
<div class="row d-flex flex-row">
|
||||
<!-- Image side -->
|
||||
<div class="col-5 border-0 ">
|
||||
<img class="shadow-sm w-100 m-auto img-fluid" src="images/Pokemon_Sleep_ID.jpg" />
|
||||
</div>
|
||||
<!-- Text side -->
|
||||
<div class="col w-50 p-3">
|
||||
<p class="fw-bold fst-italic fs-3">Pokémon Sleep? Really?</p>
|
||||
<p class="fw-normal fs-6 text-start">
|
||||
Yes, really! Pokémon Sleep has become a fun addition to my day since it's release.
|
||||
</p>
|
||||
<p class="fw-bold fst-italic fs-3">But what do you even do?</p>
|
||||
<p class="fw-normal fs-6 text-start">
|
||||
That's harder to explain. See, it isn't as much a game, as it is a gamified sleep tracker. But it's fun to collect the Pokémon and gather their berries and ingredients and create silly little Pokémon-themed foods. Plus, it encourages me to try to get to bed in a timely manner; though, if I'm honest, I definitely put my Pokémon to bed ahead of when I do.
|
||||
</p>
|
||||
|
||||
<PokemonTable AllPokemon="pokemons"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="mt-5" />
|
||||
<!-- Second Row -->
|
||||
<div class="row mt-3">
|
||||
<p class="fw-bold fst-italic fs-3">Okay, but why a whole section dedicated to Pokémon Sleep?</p>
|
||||
<p class="fw-normal fs-6 text-start">
|
||||
Well, as it is in any Pokémon game, Natures (and in this case Subskills) matter, amongst other things. This was designed as a helpful tool in assessing new Pokémon acquired from Sleep Research.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Button Row-->
|
||||
<div class="d-flex justify-content-evenly mt-4 ">
|
||||
<button class="btn btn-info rounded-4 d-flex justify-content-center" style="width:12rem;">
|
||||
<NavLink class="nav-link d-flex align-items-center" href="/pokemon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-table" viewBox="0 0 16 16">
|
||||
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm15 2h-4v3h4zm0 4h-4v3h4zm0 4h-4v3h3a1 1 0 0 0 1-1zm-5 3v-3H6v3zm-5 0v-3H1v2a1 1 0 0 0 1 1zm-4-4h4V8H1zm0-4h4V4H1zm5-3v3h4V4zm4 4H6v3h4z" />
|
||||
</svg>
|
||||
<span class="ps-1 text-white">Available Pokémon</span>
|
||||
</NavLink>
|
||||
</button>
|
||||
|
||||
<button class="btn btn-success rounded-4 d-flex justify-content-center" style="width:12rem;">
|
||||
<NavLink class="nav-link d-flex align-items-center" href="/rate-pokemon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#FFF" class="bi bi-award-fill" viewBox="0 0 16 16">
|
||||
<path d="m8 0 1.669.864 1.858.282.842 1.68 1.337 1.32L13.4 6l.306 1.854-1.337 1.32-.842 1.68-1.858.282L8 12l-1.669-.864-1.858-.282-.842-1.68-1.337-1.32L2.6 6l-.306-1.854 1.337-1.32.842-1.68L6.331.864z" />
|
||||
<path d="M4 11.794V16l4-1 4 1v-4.206l-2.018.306L8 13.126 6.018 12.1z" />
|
||||
</svg>
|
||||
<span class="ps-1 text-white">Rate Pokémon</span>
|
||||
</NavLink>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
using Portfolio.Application.Services.PokemonService;
|
||||
using Portfolio.Domain.Features.Pokemon;
|
||||
|
||||
namespace Portfolio.WebUI.Server.Components.Pages.Pokemon_Pages
|
||||
{
|
||||
public partial class PokemonSleep
|
||||
{
|
||||
public List<Pokemon> pokemons = new List<Pokemon>();
|
||||
public List<string> pokemonImageUrls = new List<string>();
|
||||
public List<string> pokemonShinyImageUrls = new List<string>();
|
||||
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
var result = await PokemonService.GetAllPokemonAsync();
|
||||
if (result is not null)
|
||||
{
|
||||
pokemons = result;
|
||||
pokemons.Sort((x, y) => x.PokemonId.CompareTo(y.PokemonId));
|
||||
|
||||
foreach (var pokemon in pokemons)
|
||||
{
|
||||
pokemonImageUrls.Add(pokemon.PokemonImageUrl);
|
||||
pokemonShinyImageUrls.Add(pokemon.PokemonShinyImageUrl);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
|
||||
.tableFixHead {
|
||||
overflow: auto;
|
||||
height: 600px;
|
||||
}
|
||||
|
||||
.tableFixHead thead th {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.flip-container {
|
||||
perspective: 1000px;
|
||||
display: inline-block;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.flipper {
|
||||
transition: transform 0.6s;
|
||||
transform-style: preserve-3d;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.flipped {
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
|
||||
.front, .back {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
|
||||
.back {
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
|
||||
.badge {
|
||||
width: 100px;
|
||||
height: 30px;
|
||||
color: white;
|
||||
padding: 4px 8px;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
border-radius: 30px;
|
||||
}
|
||||
|
||||
.statText {
|
||||
position: relative;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.dozing {
|
||||
background-color: #fcdc5e;
|
||||
}
|
||||
|
||||
.snoozing {
|
||||
background-color: #4ce8ed;
|
||||
}
|
||||
|
||||
.slumbering {
|
||||
background-color: #4588fb;
|
||||
}
|
||||
|
||||
.berries {
|
||||
background-color: #24d86b;
|
||||
}
|
||||
|
||||
.ingredients {
|
||||
background-color: #fdbe4d;
|
||||
}
|
||||
|
||||
.skills {
|
||||
background-color: #47a0fc;
|
||||
}
|
||||
|
||||
.page-content {
|
||||
position: relative;
|
||||
z-index: 1; /* Higher than stickers */
|
||||
background-color: rgba(255, 255, 255, 0.8); /* Optional translucent bg */
|
||||
}
|
||||
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
@page "/pokemonsleep"
|
||||
|
||||
|
||||
@attribute [StreamRendering]
|
||||
@rendermode InteractiveServer
|
||||
|
||||
|
||||
<PageTitle>Pokémon Sleep</PageTitle>
|
||||
|
||||
<!-- <PokemonBackground PokemonImages="pokemonImageUrls" ShinyPokemonImages="pokemonShinyImageUrls" /> -->
|
||||
<PokemonHeader />
|
||||
|
||||
<!-- Card -->
|
||||
<div class="container card shadow-sm border-0 p-3 pb-4 mt-4 m-auto w-75 mb-5 bg-white">
|
||||
|
||||
<!-- Top Row-->
|
||||
<div class="row d-flex flex-row">
|
||||
<!-- Image side -->
|
||||
<div class="col-5 border-0 ">
|
||||
<img class="shadow-sm w-100 m-auto img-fluid" src="images/Pokemon_Sleep_ID.jpg" />
|
||||
</div>
|
||||
<!-- Text side -->
|
||||
<div class="col w-50 p-3">
|
||||
<p class="fw-bold fst-italic fs-3">Pokémon Sleep? Really?</p>
|
||||
<p class="fw-normal fs-6 text-start">
|
||||
Yes, really! Pokémon Sleep has become a fun addition to my day since it's release.
|
||||
</p>
|
||||
<p class="fw-bold fst-italic fs-3">But what do you even do?</p>
|
||||
<p class="fw-normal fs-6 text-start">
|
||||
That's harder to explain. See, it isn't as much a game, as it is a gamified sleep tracker. But it's fun to collect the Pokémon and gather their berries and ingredients and create silly little Pokémon-themed foods. Plus, it encourages me to try to get to bed in a timely manner; though, if I'm honest, I definitely put my Pokémon to bed ahead of when I do.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Second Row -->
|
||||
<div class="row mt-3">
|
||||
<p class="fw-bold fst-italic fs-3">Okay, but why a whole section dedicated to Pokémon Sleep?</p>
|
||||
<p class="fw-normal fs-6 text-start">
|
||||
Well, as it is in any Pokémon game, Natures (and in this case Subskills) matter, amongst other things. This was designed as a helpful tool in assessing new Pokémon acquired from Sleep Research.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Button Row-->
|
||||
<div class="d-flex justify-content-evenly mt-4 ">
|
||||
<button class="btn btn-info rounded-4 d-flex justify-content-center" style="width:12rem;">
|
||||
<NavLink class="nav-link d-flex align-items-center" href="/pokemon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-table" viewBox="0 0 16 16">
|
||||
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm15 2h-4v3h4zm0 4h-4v3h4zm0 4h-4v3h3a1 1 0 0 0 1-1zm-5 3v-3H6v3zm-5 0v-3H1v2a1 1 0 0 0 1 1zm-4-4h4V8H1zm0-4h4V4H1zm5-3v3h4V4zm4 4H6v3h4z" />
|
||||
</svg>
|
||||
<span class="ps-1 text-white">Available Pokémon</span>
|
||||
</NavLink>
|
||||
</button>
|
||||
|
||||
<button class="btn btn-success rounded-4 d-flex justify-content-center" style="width:12rem;">
|
||||
<NavLink class="nav-link d-flex align-items-center" href="/rate-pokemon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#FFF" class="bi bi-award-fill" viewBox="0 0 16 16">
|
||||
<path d="m8 0 1.669.864 1.858.282.842 1.68 1.337 1.32L13.4 6l.306 1.854-1.337 1.32-.842 1.68-1.858.282L8 12l-1.669-.864-1.858-.282-.842-1.68-1.337-1.32L2.6 6l-.306-1.854 1.337-1.32.842-1.68L6.331.864z" />
|
||||
<path d="M4 11.794V16l4-1 4 1v-4.206l-2.018.306L8 13.126 6.018 12.1z" />
|
||||
</svg>
|
||||
<span class="ps-1 text-white">Rate Pokémon</span>
|
||||
</NavLink>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
|
@ -1,93 +1,23 @@
|
|||
@page "/pokemon/{id:int}"
|
||||
@page "/pokemon"
|
||||
|
||||
|
||||
@inject IPokemonService PokemonService
|
||||
@inject NavigationManager Navigation
|
||||
|
||||
@attribute [StreamRendering]
|
||||
@rendermode InteractiveServer
|
||||
|
||||
|
||||
<PokemonHeader />
|
||||
<PageTitle>Pokémon Sleep</PageTitle>
|
||||
|
||||
|
||||
<div class="w-100">
|
||||
<!-- <PokemonBackground PokemonImages="pokemonImageUrls" ShinyPokemonImages="pokemonShinyImageUrls" /> -->
|
||||
|
||||
@if (_pokemon == null)
|
||||
{
|
||||
<Loading />
|
||||
}
|
||||
else
|
||||
{
|
||||
<PageTitle>@_pokemon.PokemonName</PageTitle>
|
||||
<!-- Total Componenet-->
|
||||
<PokemonHeader />
|
||||
|
||||
<div class="container">
|
||||
<div class="w-75 row mt-4 m-auto">
|
||||
<PokemonTable AllPokemon="pokemons"/>
|
||||
|
||||
<!-- Previous Pokemon Button -->
|
||||
<div class="col-auto">
|
||||
<button class="mt-1 p-2 btn btn-danger rounded-5 align-self-start text-white" disabled="@(!_previousPokemonId.HasValue)" @onclick="NavigateToPrevious">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-arrow-left-circle-fill" viewBox="0 0 16 16">
|
||||
<path d="M8 0a8 8 0 1 0 0 16A8 8 0 0 0 8 0m3.5 7.5a.5.5 0 0 1 0 1H5.707l2.147 2.146a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708l3-3a.5.5 0 1 1 .708.708L5.707 7.5z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<hr class="mt-5" />
|
||||
|
||||
<!-- Pokemon Presentation -->
|
||||
<div class="mt-5 mx-5 col justify-content-center">
|
||||
@if (_variationPokemonId != null)
|
||||
{
|
||||
@if (_variationPokemonId != null && _pokemonVariant == null){
|
||||
<Loading />
|
||||
}
|
||||
else
|
||||
{
|
||||
<!-- If Variation Pokemon have same PokemonId -->
|
||||
@if(_pokemon.Id != _pokemonVariant.Id)
|
||||
{
|
||||
<div class="d-flex justify-content-center">
|
||||
<div class="pokemoncard m-1">
|
||||
<PokemonCard Pokemon="_pokemon" />
|
||||
</div>
|
||||
|
||||
<div class="pokemoncard m-1">
|
||||
<PokemonCard Pokemon="_pokemonVariant" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
}
|
||||
<!-- If Variation Pokemon has diff PokemonId -->
|
||||
else
|
||||
{
|
||||
<div class="d-flex justify-content-center align-items-center h-100">
|
||||
<div class="pokemoncard">
|
||||
<PokemonCard Pokemon="_pokemonVariant" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
<!-- Standard Pokemon Display -->
|
||||
<div class="d-flex justify-content-center align-items-center h-100">
|
||||
<div class="pokemoncard m-1">
|
||||
<PokemonCard Pokemon="_pokemon" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<!-- Next Pokemon Button -->
|
||||
<div class="col-auto">
|
||||
<button class="mt-1 p-2 btn btn-danger rounded rounded-5 align-self-start text-white" disabled="@(!_nextPokemonId.HasValue)" @onclick="NavigateToNext">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-arrow-right-circle-fill" viewBox="0 0 16 16">
|
||||
<path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0M4.5 7.5a.5.5 0 0 0 0 1h5.793l-2.147 2.146a.5.5 0 0 0 .708.708l3-3a.5.5 0 0 0 0-.708l-3-3a.5.5 0 1 0-.708.708L10.293 7.5z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
|
@ -1,52 +1,30 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Portfolio.Application.Services.PokemonService;
|
||||
using Portfolio.Domain.Features.Pokemon;
|
||||
|
||||
namespace Portfolio.WebUI.Server.Components.Pages.Pokemon_Pages
|
||||
{
|
||||
public partial class PokemonView
|
||||
{
|
||||
[Parameter] public int Id { get; set; }
|
||||
private Pokemon? _pokemon;
|
||||
private Pokemon? _pokemonVariant;
|
||||
private List<int> _pokemonIds;
|
||||
private int? _nextPokemonId;
|
||||
private int? _previousPokemonId;
|
||||
private int? _variationPokemonId;
|
||||
private int _currentIndex;
|
||||
public List<Pokemon> pokemons = new List<Pokemon>();
|
||||
public List<string> pokemonImageUrls = new List<string>();
|
||||
public List<string> pokemonShinyImageUrls = new List<string>();
|
||||
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
_pokemon = await PokemonService.GetPokemonByPokemonIdAsync(Id);
|
||||
|
||||
// These can be smart queries if your data is sorted by ID or by another property
|
||||
_pokemonIds = await PokemonService.GetAllPokemonIdsAsync();
|
||||
_currentIndex = _pokemonIds.IndexOf(_pokemon.PokemonId);
|
||||
//Console.WriteLine(_currentIndex);
|
||||
|
||||
_nextPokemonId = await PokemonService.GetNextPokemonIdAsync(Id);
|
||||
_previousPokemonId = await PokemonService.GetPreviousPokemonIdAsync(Id);
|
||||
|
||||
_variationPokemonId = await PokemonService.GetVariationPokemonIdAsync(Id);
|
||||
if (_variationPokemonId != null)
|
||||
var result = await PokemonService.GetAllPokemonAsync();
|
||||
if (result is not null)
|
||||
{
|
||||
Console.WriteLine(_variationPokemonId);
|
||||
_pokemonVariant = await PokemonService.GetPokemonByIdAsync((int)_variationPokemonId);
|
||||
Console.WriteLine(_pokemonVariant.VariationName);
|
||||
pokemons = result;
|
||||
pokemons.Sort((x, y) => x.PokemonId.CompareTo(y.PokemonId));
|
||||
|
||||
foreach (var pokemon in pokemons)
|
||||
{
|
||||
pokemonImageUrls.Add(pokemon.PokemonImageUrl);
|
||||
pokemonShinyImageUrls.Add(pokemon.PokemonShinyImageUrl);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void NavigateToNext()
|
||||
{
|
||||
if (_nextPokemonId.HasValue)
|
||||
Navigation.NavigateTo($"/pokemon/{_nextPokemonId.Value}");
|
||||
}
|
||||
|
||||
private void NavigateToPrevious()
|
||||
{
|
||||
if (_previousPokemonId.HasValue)
|
||||
Navigation.NavigateTo($"/pokemon/{_previousPokemonId.Value}");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,93 @@
|
|||
.pokemoncard {
|
||||
width: 100%;
|
||||
max-width: 350px;
|
||||
flex: 0 0 auto; /* prevent flex shrink/grow */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 0.5rem;
|
||||
|
||||
.tableFixHead {
|
||||
overflow: auto;
|
||||
height: 600px;
|
||||
}
|
||||
|
||||
.tableFixHead thead th {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.flip-container {
|
||||
perspective: 1000px;
|
||||
display: inline-block;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.flipper {
|
||||
transition: transform 0.6s;
|
||||
transform-style: preserve-3d;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.flipped {
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
|
||||
.front, .back {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
|
||||
.back {
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
|
||||
.badge {
|
||||
width: 100px;
|
||||
height: 30px;
|
||||
color: white;
|
||||
padding: 4px 8px;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
border-radius: 30px;
|
||||
}
|
||||
|
||||
.statText {
|
||||
position: relative;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.dozing {
|
||||
background-color: #fcdc5e;
|
||||
}
|
||||
|
||||
.snoozing {
|
||||
background-color: #4ce8ed;
|
||||
}
|
||||
|
||||
.slumbering {
|
||||
background-color: #4588fb;
|
||||
}
|
||||
|
||||
.berries {
|
||||
background-color: #24d86b;
|
||||
}
|
||||
|
||||
.ingredients {
|
||||
background-color: #fdbe4d;
|
||||
}
|
||||
|
||||
.skills {
|
||||
background-color: #47a0fc;
|
||||
}
|
||||
|
||||
.page-content {
|
||||
position: relative;
|
||||
z-index: 1; /* Higher than stickers */
|
||||
background-color: rgba(255, 255, 255, 0.8); /* Optional translucent bg */
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue