Individual pokemon views are being served and can move to the next pokemon. Edit form can be accessed from either table or individual view and goes back to where it was.
This commit is contained in:
parent
42d3a864e4
commit
99ac4581ae
|
@ -10,7 +10,12 @@ namespace Portfolio.Application.Services.PokemonService
|
|||
public interface IPokemonService
|
||||
{
|
||||
Task<List<Pokemon>> GetAllPokemonAsync();
|
||||
Task<Pokemon> GetPokemonByPokemonIdAsync(int id);
|
||||
Task<Pokemon> GetPokemonByIdAsync(int id);
|
||||
Task<List<int>> GetAllPokemonIdsAsync();
|
||||
Task<int?> GetPreviousPokemonIdAsync(int id);
|
||||
Task<int?> GetNextPokemonIdAsync(int id);
|
||||
Task<int?> GetVariationPokemonIdAsync(int id);
|
||||
Task AddPokemonAsync(Pokemon pokemon);
|
||||
Task DeletePokemonAsync(int pokemonId);
|
||||
Task UpdatePokemonAsync(Pokemon pokemon);
|
||||
|
|
|
@ -33,14 +33,40 @@ namespace Portfolio.Application.Services.PokemonService
|
|||
|
||||
}
|
||||
|
||||
public async Task<List<int>> GetAllPokemonIdsAsync()
|
||||
{
|
||||
return await _pokemonRepository.GetAllPokemonIdsAsync();
|
||||
}
|
||||
|
||||
public async Task<int?> GetNextPokemonIdAsync(int id)
|
||||
{
|
||||
return await _pokemonRepository.GetNextPokemonIdAsync(id);
|
||||
}
|
||||
|
||||
public async Task<Pokemon> GetPokemonByPokemonIdAsync(int id)
|
||||
{
|
||||
return await _pokemonRepository.GetPokemonByPokemonIdAsync(id);
|
||||
}
|
||||
|
||||
public async Task<Pokemon> GetPokemonByIdAsync(int id)
|
||||
{
|
||||
return await _pokemonRepository.GetPokemonByIdAsync(id);
|
||||
}
|
||||
|
||||
public async Task<int?> GetPreviousPokemonIdAsync(int id)
|
||||
{
|
||||
return await _pokemonRepository.GetPreviousPokemonIdAsync(id);
|
||||
|
||||
}
|
||||
|
||||
public async Task UpdatePokemonAsync(Pokemon pokemon)
|
||||
{
|
||||
await _pokemonRepository.UpdatePokemonAsync(pokemon);
|
||||
}
|
||||
|
||||
public async Task<int?> GetVariationPokemonIdAsync(int id)
|
||||
{
|
||||
return await _pokemonRepository.GetVariationPokemonIdAsync(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,11 @@ namespace Portfolio.Domain.Features.Pokemon
|
|||
{
|
||||
Task<List<Pokemon>> GetAllPokemonsAsync();
|
||||
Task<Pokemon> GetPokemonByIdAsync(int id);
|
||||
Task<Pokemon> GetPokemonByPokemonIdAsync(int id);
|
||||
Task<List<int>> GetAllPokemonIdsAsync();
|
||||
Task<int?> GetPreviousPokemonIdAsync(int currentPokemonId);
|
||||
Task<int?> GetNextPokemonIdAsync(int currentPokemonId);
|
||||
Task<int?> GetVariationPokemonIdAsync(int pokemonId);
|
||||
Task AddPokemonAsync(Pokemon pokemon);
|
||||
Task DeletePokemonAsync(int pokemonId);
|
||||
Task UpdatePokemonAsync(Pokemon pokemon);
|
||||
|
|
|
@ -21,11 +21,14 @@ namespace Portfolio.Infrastructure.Repositories
|
|||
{
|
||||
return await _context.Pokemons.ToListAsync();
|
||||
}
|
||||
public async Task<Pokemon> GetPokemonByPokemonIdAsync(int id)
|
||||
{
|
||||
return await _context.Pokemons.FirstOrDefaultAsync(p => p.PokemonId == id);
|
||||
}
|
||||
public async Task<Pokemon> GetPokemonByIdAsync(int id)
|
||||
{
|
||||
return await _context.Pokemons.FirstOrDefaultAsync(p => p.Id == id);
|
||||
}
|
||||
|
||||
public async Task AddPokemonAsync(Pokemon pokemon)
|
||||
{
|
||||
_context.Pokemons.Add(pokemon);
|
||||
|
@ -46,5 +49,68 @@ namespace Portfolio.Infrastructure.Repositories
|
|||
_context.Pokemons.Update(pokemon);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task<int?> GetPreviousPokemonIdAsync(int currentPokemonId)
|
||||
{
|
||||
// Get the previous Pokémon's PokemonId
|
||||
var prevPokemonId = await _context.Pokemons
|
||||
.Where(p => p.PokemonId < currentPokemonId)
|
||||
.OrderByDescending(p => p.PokemonId)
|
||||
.Select(p => (int?)p.PokemonId)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
// If no previous PokemonId is found, wrap around to the last one
|
||||
if (prevPokemonId == null)
|
||||
{
|
||||
prevPokemonId = await _context.Pokemons
|
||||
.OrderByDescending(p => p.PokemonId) // Get the last PokemonId
|
||||
.Select(p => (int?)p.PokemonId)
|
||||
.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
return prevPokemonId;
|
||||
}
|
||||
|
||||
public async Task<int?> GetNextPokemonIdAsync(int currentPokemonId)
|
||||
{
|
||||
// Get the next Pokémon's PokemonId
|
||||
var nextPokemonId = await _context.Pokemons
|
||||
.Where(p => p.PokemonId > currentPokemonId)
|
||||
.OrderBy(p => p.PokemonId)
|
||||
.Select(p => (int?)p.PokemonId)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
// If no next PokemonId is found, wrap around to the first one
|
||||
if (nextPokemonId == null)
|
||||
{
|
||||
nextPokemonId = await _context.Pokemons
|
||||
.OrderBy(p => p.PokemonId) // Get the first PokemonId
|
||||
.Select(p => (int?)p.PokemonId)
|
||||
.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
return nextPokemonId;
|
||||
}
|
||||
|
||||
public async Task<List<int>> GetAllPokemonIdsAsync()
|
||||
{
|
||||
return await _context.Pokemons
|
||||
.OrderBy(p => p.PokemonId) // Ensure it's ordered by PokemonId
|
||||
.Select(p => p.PokemonId)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<int?> GetVariationPokemonIdAsync(int pokemonId)
|
||||
{
|
||||
// Find a variation for the given PokemonId (where IsVariation is true)
|
||||
var variation = await _context.Pokemons
|
||||
.Where(p => p.PokemonId == pokemonId && p.IsVariation)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
// Return the Id of the variation, or null if no variation is found
|
||||
return variation?.Id;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<div id="load">
|
||||
<div>G</div>
|
||||
<div>N</div>
|
||||
<div>I</div>
|
||||
<div>D</div>
|
||||
<div>A</div>
|
||||
<div>O</div>
|
||||
<div>L</div>
|
||||
</div>
|
|
@ -0,0 +1,195 @@
|
|||
body {
|
||||
background: #000;
|
||||
}
|
||||
|
||||
#load {
|
||||
position: absolute;
|
||||
width: 600px;
|
||||
height: 36px;
|
||||
left: 50%;
|
||||
top: 40%;
|
||||
margin-left: -300px;
|
||||
overflow: visible;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
#load div {
|
||||
position: absolute;
|
||||
width: 20px;
|
||||
height: 36px;
|
||||
opacity: 0;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
animation: move 3s linear infinite;
|
||||
-o-animation: move 3s linear infinite;
|
||||
-moz-animation: move 3s linear infinite;
|
||||
-webkit-animation: move 3s linear infinite;
|
||||
transform: rotate(180deg);
|
||||
-o-transform: rotate(180deg);
|
||||
-moz-transform: rotate(180deg);
|
||||
-webkit-transform: rotate(180deg);
|
||||
color: #35C4F0;
|
||||
}
|
||||
|
||||
#load div:nth-child(2) {
|
||||
animation-delay: 0.2s;
|
||||
-o-animation-delay: 0.2s;
|
||||
-moz-animation-delay: 0.2s;
|
||||
-webkit-animation-delay: 0.2s;
|
||||
}
|
||||
|
||||
#load div:nth-child(3) {
|
||||
animation-delay: 0.4s;
|
||||
-o-animation-delay: 0.4s;
|
||||
-webkit-animation-delay: 0.4s;
|
||||
-webkit-animation-delay: 0.4s;
|
||||
}
|
||||
|
||||
#load div:nth-child(4) {
|
||||
animation-delay: 0.6s;
|
||||
-o-animation-delay: 0.6s;
|
||||
-moz-animation-delay: 0.6s;
|
||||
-webkit-animation-delay: 0.6s;
|
||||
}
|
||||
|
||||
#load div:nth-child(5) {
|
||||
animation-delay: 0.8s;
|
||||
-o-animation-delay: 0.8s;
|
||||
-moz-animation-delay: 0.8s;
|
||||
-webkit-animation-delay: 0.8s;
|
||||
}
|
||||
|
||||
#load div:nth-child(6) {
|
||||
animation-delay: 1s;
|
||||
-o-animation-delay: 1s;
|
||||
-moz-animation-delay: 1s;
|
||||
-webkit-animation-delay: 1s;
|
||||
}
|
||||
|
||||
#load div:nth-child(7) {
|
||||
animation-delay: 1.2s;
|
||||
-o-animation-delay: 1.2s;
|
||||
-moz-animation-delay: 1.2s;
|
||||
-webkit-animation-delay: 1.2s;
|
||||
}
|
||||
|
||||
@keyframes move {
|
||||
0% {
|
||||
left: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
35% {
|
||||
left: 41%;
|
||||
-moz-transform: rotate(0deg);
|
||||
-webkit-transform: rotate(0deg);
|
||||
-o-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
65% {
|
||||
left: 59%;
|
||||
-moz-transform: rotate(0deg);
|
||||
-webkit-transform: rotate(0deg);
|
||||
-o-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
left: 100%;
|
||||
-moz-transform: rotate(-180deg);
|
||||
-webkit-transform: rotate(-180deg);
|
||||
-o-transform: rotate(-180deg);
|
||||
transform: rotate(-180deg);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@-moz-keyframes move {
|
||||
0% {
|
||||
left: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
35% {
|
||||
left: 41%;
|
||||
-moz-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
65% {
|
||||
left: 59%;
|
||||
-moz-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
left: 100%;
|
||||
-moz-transform: rotate(-180deg);
|
||||
transform: rotate(-180deg);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes move {
|
||||
0% {
|
||||
left: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
35% {
|
||||
left: 41%;
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
65% {
|
||||
left: 59%;
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
left: 100%;
|
||||
-webkit-transform: rotate(-180deg);
|
||||
transform: rotate(-180deg);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@-o-keyframes move {
|
||||
0% {
|
||||
left: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
35% {
|
||||
left: 41%;
|
||||
-o-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
65% {
|
||||
left: 59%;
|
||||
-o-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
left: 100%;
|
||||
-o-transform: rotate(-180deg);
|
||||
transform: rotate(-180deg);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
|
@ -28,7 +28,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-info-subtle border rounded border-2 border-info pokemon-flavor-text">
|
||||
<div class="bg-info-subtle border rounded border-2 border-info z-3 pokemon-flavor-text">
|
||||
@if (string.IsNullOrEmpty(_pokemon.FlavorText))
|
||||
{
|
||||
<p class="">[ Pokemon Flavor Text Placeholder ]</p>
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
@inject NavigationManager Navigation
|
||||
<button class="btn btn-warning" @onclick="() => EditPokemon(PokemonId)">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pencil-fill" viewBox="0 0 16 16">
|
||||
<path d="M12.854.146a.5.5 0 0 0-.707 0L10.5 1.793 14.207 5.5l1.647-1.646a.5.5 0 0 0 0-.708zm.646 6.061L9.793 2.5 3.293 9H3.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.207zm-7.468 7.468A.5.5 0 0 1 6 13.5V13h-.5a.5.5 0 0 1-.5-.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.5-.5V10h-.5a.5.5 0 0 1-.175-.032l-.179.178a.5.5 0 0 0-.11.168l-2 5a.5.5 0 0 0 .65.65l5-2a.5.5 0 0 0 .168-.11z" />
|
||||
</svg>
|
||||
</button>
|
|
@ -0,0 +1,15 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||
|
||||
namespace Portfolio.WebUI.Server.Components.Component
|
||||
{
|
||||
public partial class PokemonEditButton
|
||||
{
|
||||
[Parameter] public int PokemonId { get; set; }
|
||||
|
||||
private void EditPokemon(int PokemonId)
|
||||
{
|
||||
Navigation.NavigateTo($"/pokemonsleep/edit/{PokemonId}");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,56 +6,57 @@
|
|||
@rendermode InteractiveServer
|
||||
|
||||
|
||||
<!-- Main Body -->
|
||||
@if (pokemons == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<!-- Main UI -->
|
||||
<div class="card shadow border-0 mt-4 m-auto w-50">
|
||||
<!-- Main UI -->
|
||||
<div class="card shadow border-0 mt-4 m-auto w-50">
|
||||
|
||||
<!-- Table Header -->
|
||||
<div class="card-header bg-secondary bg-gradient ml-0 py-3">
|
||||
<div class="row">
|
||||
<div class="col-12 text-center position-relative">
|
||||
<h2 class="text-info">Available Pokémon</h2>
|
||||
<div class="m-1 col-1 badge bg-info position-absolute top-0 end-0"><p class="statText">@(pokemons.Count()) Pokemon</p></div>
|
||||
</div>
|
||||
<!-- Table Header -->
|
||||
<div class="card-header bg-secondary bg-gradient ml-0 py-3">
|
||||
<div class="row">
|
||||
<div class="col-12 text-center position-relative">
|
||||
<h2 class="text-info">Available Pokémon</h2>
|
||||
<div class="m-1 col-1 badge bg-info position-absolute top-0 end-0"><p class="statText">@(pokemons.Count()) Pokemon</p></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Table -->
|
||||
<div class="tableFixHead">
|
||||
<table class="table table-striped">
|
||||
|
||||
<!-- Table Head -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-bg-info col col-2" scope="col"></th>
|
||||
<th class="text-bg-info col pokemon-dex-width" scope="col">#</th>
|
||||
<th class="text-bg-info col pokemon-name-width" scope="col">Pokemon</th>
|
||||
<th class="text-bg-info col pokemon-type-width" scope="col">Type</th>
|
||||
<th class="text-bg-info col pokemon-type-width" scope="col">Sleep Type</th>
|
||||
<th class="text-bg-info col pokemon-type-width" scope="col">Speciality</th>
|
||||
<th class="text-bg-info col pokemon-type-width" scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<!-- Table -->
|
||||
<div class="tableFixHead">
|
||||
<table class="table table-striped">
|
||||
|
||||
<!-- Table Head -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-bg-info col col-2" scope="col"></th>
|
||||
<th class="text-bg-info col pokemon-dex-width" scope="col">#</th>
|
||||
<th class="text-bg-info col pokemon-name-width" scope="col">Pokemon</th>
|
||||
<th class="text-bg-info col pokemon-type-width" scope="col">Type</th>
|
||||
<th class="text-bg-info col pokemon-type-width" scope="col">Sleep Type</th>
|
||||
<th class="text-bg-info col pokemon-type-width" scope="col">Speciality</th>
|
||||
<th class="text-bg-info col pokemon-type-width" scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@if(pokemons == null)
|
||||
{
|
||||
<tbody>
|
||||
<Loading />
|
||||
</tbody>
|
||||
}
|
||||
else
|
||||
{
|
||||
<!-- Table Body -->
|
||||
<tbody>
|
||||
@foreach (var pokemon in pokemons)
|
||||
{
|
||||
<tr>
|
||||
|
||||
<!-- Section: Pokemon Image -->
|
||||
<!-- Section: Pokemon Image -->
|
||||
@{
|
||||
string baseUrl = pokemon.PokemonImageUrl;
|
||||
string shinyUrl = pokemon.PokemonShinyImageUrl;
|
||||
}
|
||||
<td style="text-align: center;">
|
||||
@if(shinyUrl == null){
|
||||
@if (shinyUrl == null)
|
||||
{
|
||||
<div class="flip-container">
|
||||
<div class="flipper">
|
||||
<img class="front" src="@baseUrl" />
|
||||
|
@ -83,22 +84,22 @@ else
|
|||
{
|
||||
@if (pokemon.VariationName == "Alolan")
|
||||
{
|
||||
<td style="vertical-align: auto;"> Alolan @pokemon.PokemonName</td>
|
||||
<td @onclick="() => ViewPokemon(pokemon.PokemonId)" style="vertical-align: auto;"> Alolan @pokemon.PokemonName</td>
|
||||
}
|
||||
@if (pokemon.VariationName == "Paldean")
|
||||
{
|
||||
<td style="vertical-align: auto;"> Paldean @pokemon.PokemonName</td>
|
||||
<td @onclick="() => ViewPokemon(pokemon.PokemonId)" style="vertical-align: auto;"> Paldean @pokemon.PokemonName</td>
|
||||
}
|
||||
}
|
||||
else // Otherwise, Base Case
|
||||
{
|
||||
<td style="vertical-align: auto;"> @pokemon.PokemonName</td>
|
||||
<td @onclick="() => ViewPokemon(pokemon.PokemonId)" style="vertical-align: auto;"> @pokemon.PokemonName</td>
|
||||
}
|
||||
|
||||
|
||||
<!-- Section 4: Pokemon Type -->
|
||||
<td >
|
||||
<div class="m-1 col-1" >
|
||||
<td>
|
||||
<div class="m-1 col-1">
|
||||
<img src="@GetTypeImageUrl(pokemon.PokemonType)" class="" style="width:60px; height:60px;" />
|
||||
</div>
|
||||
</td>
|
||||
|
@ -115,14 +116,10 @@ else
|
|||
|
||||
<!-- Section 7: Functional Buttons -->
|
||||
<td>
|
||||
<button class="btn btn-warning" @onclick="() => EditPokemon(pokemon.Id)">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pencil-fill" viewBox="0 0 16 16">
|
||||
<path d="M12.854.146a.5.5 0 0 0-.707 0L10.5 1.793 14.207 5.5l1.647-1.646a.5.5 0 0 0 0-.708zm.646 6.061L9.793 2.5 3.293 9H3.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.207zm-7.468 7.468A.5.5 0 0 1 6 13.5V13h-.5a.5.5 0 0 1-.5-.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.5-.5V10h-.5a.5.5 0 0 1-.175-.032l-.179.178a.5.5 0 0 0-.11.168l-2 5a.5.5 0 0 0 .65.65l5-2a.5.5 0 0 0 .168-.11z" />
|
||||
</svg>
|
||||
</button>
|
||||
<PokemonEditButton PokemonId="pokemon.Id" />
|
||||
<button class="btn btn-danger" @onclick="() => ConfirmDelete(pokemon.Id)">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
|
||||
class="bi bi-trash" viewBox="0 0 16 16">
|
||||
class="bi bi-trash" viewBox="0 0 16 16">
|
||||
<path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0z" />
|
||||
<path d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4zM2.5 3h11V2h-11z" />
|
||||
</svg>
|
||||
|
@ -132,9 +129,11 @@ else
|
|||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
}
|
||||
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ else
|
|||
<DataAnnotationsValidator />
|
||||
|
||||
<!-- Section 1 -->
|
||||
<div class="row ">
|
||||
<div class="row mt-3">
|
||||
<div class="col-sm-3 input-group mb-3 ">
|
||||
<!-- Pokemon #-->
|
||||
<span for="PokemonId" class="input-group-text">#</span>
|
||||
|
@ -43,6 +43,53 @@ else
|
|||
</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="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 mb-3 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 mb-3 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>
|
||||
</InputSelect>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Section 2 -->
|
||||
<div class="row">
|
||||
<div class="input-group mb-3">
|
||||
|
@ -59,31 +106,6 @@ else
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Section 3 -->
|
||||
<div class="row mb-3 m-auto" >
|
||||
<label for="SleepType" class="form-label">Sleep Type</label>
|
||||
<InputSelect id="SleepType" @bind-Value="NewPokemon.SleepType" class="form-select">
|
||||
<option hidden value="">Dozing / Snoozing / Slumbering</option>
|
||||
<option value="Dozing">Dozing</option>
|
||||
<option value="Snoozing">Snoozing</option>
|
||||
<option value="Slumbering">Slumbering</option>
|
||||
</InputSelect>
|
||||
</div>
|
||||
|
||||
<!-- Section 4 -->
|
||||
<div class="row mb-3 m-auto">
|
||||
<label for="Speciality" class="form-label">Specialty</label>
|
||||
<InputSelect id="SleepType" @bind-Value="NewPokemon.Speciality" class="form-select">
|
||||
<option hidden value="">Berries / Ingredients / Skills</option>
|
||||
<option value="Berries">Berries</option>
|
||||
<option value="Ingredients">Ingredients</option>
|
||||
<option value="Skills">Skills</option>
|
||||
<option value="Other">Other</option>
|
||||
</InputSelect>
|
||||
</div>
|
||||
|
||||
<!-- New Image URL Field -->
|
||||
<div class="row mb-3 m-auto">
|
||||
<label for="ImageUrl" class="form-label">Base Image URL</label>
|
||||
|
@ -93,8 +115,12 @@ else
|
|||
<label for="ImageUrl" class="form-label">Shiny Image URL</label>
|
||||
<InputText id="ImageUrl" @bind-Value="NewPokemon.PokemonShinyImageUrl" class="form-control" />
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary mb-3">Add Pokémon</button>
|
||||
<button type="button" class="btn btn-secondary mb-3" @onclick="@Cancel">Cancel</button>
|
||||
|
||||
<!-- 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">Add Pokemon</button>
|
||||
</div>
|
||||
</EditForm>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
@page "/pokemonsleep/edit/{id:int}"
|
||||
@inject IPokemonService PokemonService
|
||||
@inject NavigationManager Navigation
|
||||
@inject IJSRuntime JSRuntime
|
||||
|
||||
@attribute [StreamRendering]
|
||||
@rendermode InteractiveServer
|
||||
|
@ -31,7 +32,8 @@ else
|
|||
<EditForm class="col mb-3" Model="pokemon" OnValidSubmit="HandleSubmit">
|
||||
<DataAnnotationsValidator />
|
||||
|
||||
<div class="row">
|
||||
<!-- 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 />
|
||||
|
@ -39,7 +41,9 @@ else
|
|||
</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">
|
||||
|
@ -64,7 +68,7 @@ else
|
|||
<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">
|
||||
|
@ -73,7 +77,7 @@ else
|
|||
<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">
|
||||
|
@ -83,30 +87,46 @@ else
|
|||
</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>
|
||||
|
||||
|
||||
<!-- New Image URL Field -->
|
||||
<!-- 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" required />
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary mb-3">Save Changes</button>
|
||||
<button type="button" class="btn btn-secondary mb-3" @onclick="Cancel">Cancel</button>
|
||||
<!-- 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>
|
||||
}
|
||||
|
||||
@code {
|
||||
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using Portfolio.Domain.Features.Pokemon;
|
||||
|
||||
namespace Portfolio.WebUI.Server.Components.Pages
|
||||
|
@ -16,12 +17,21 @@ namespace Portfolio.WebUI.Server.Components.Pages
|
|||
private async Task HandleSubmit()
|
||||
{
|
||||
await PokemonService.UpdatePokemonAsync(pokemon);
|
||||
Navigation.NavigateTo("/pokemonsleep");
|
||||
//Navigation.NavigateTo("/pokemonsleep");
|
||||
await JSRuntime.InvokeVoidAsync("history.back");
|
||||
}
|
||||
|
||||
private void Cancel()
|
||||
private async void Cancel()
|
||||
{
|
||||
Navigation.NavigateTo("/pokemonsleep");
|
||||
await JSRuntime.InvokeVoidAsync("history.back");
|
||||
|
||||
}
|
||||
|
||||
private bool HideLabel { get; set; } = true;
|
||||
private void Toggle()
|
||||
{
|
||||
HideLabel = !HideLabel;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<PageTitle>Pokémon Sleep</PageTitle>
|
||||
|
||||
<div class="w-100">
|
||||
<PokemonBackground PokemonImages="pokemonImageUrls" ShinyPokemonImages="pokemonShinyImageUrls" />
|
||||
<!-- <PokemonBackground PokemonImages="pokemonImageUrls" ShinyPokemonImages="pokemonShinyImageUrls" /> -->
|
||||
|
||||
<PokemonHeader />
|
||||
|
||||
|
|
|
@ -1,5 +1,81 @@
|
|||
@page "/pokemonsleep/pokemon/{id:int}"
|
||||
@inject IPokemonService PokemonService
|
||||
@inject NavigationManager Navigation
|
||||
|
||||
@code {
|
||||
@attribute [StreamRendering]
|
||||
@rendermode InteractiveServer
|
||||
|
||||
|
||||
<PokemonHeader />
|
||||
|
||||
@if (_pokemon == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<PageTitle>@_pokemon.PokemonName</PageTitle>
|
||||
<!-- Total Componenet-->
|
||||
|
||||
<div class="w-100">
|
||||
<div class="d-flex justify-content-center mt-4">
|
||||
<button class="mt-1 p-2 btn btn-danger rounded-5 align-self-start shadow-sm" 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 class="mt-5 mx-5 d-flex justify-content-center">
|
||||
@if (_variationPokemonId != null)
|
||||
{
|
||||
@if (_variationPokemonId != null && _pokemonVariant == null){
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
else
|
||||
{
|
||||
@if(_pokemon.Id != _pokemonVariant.Id)
|
||||
{
|
||||
<div class="d-flex justify-content-center">
|
||||
<div class="position-relative">
|
||||
<PokemonCard Pokemon="_pokemon" />
|
||||
<div class="position-absolute top-100 start-50 translate-middle mt-5">
|
||||
<PokemonEditButton PokemonId="_pokemon.Id" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="position-relative">
|
||||
<PokemonCard Pokemon="_pokemonVariant" />
|
||||
<div class="position-absolute top-100 start-50 translate-middle mt-5">
|
||||
<PokemonEditButton PokemonId="_pokemonVariant.Id" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="position-relative">
|
||||
<PokemonCard Pokemon="_pokemonVariant" />
|
||||
<div class="position-absolute top-100 start-50 translate-middle mt-5">
|
||||
<PokemonEditButton PokemonId="_pokemonVariant.Id" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
<div class="position-relative">
|
||||
<PokemonCard Pokemon="_pokemon" />
|
||||
<div class="position-absolute top-100 start-50 translate-middle mt-5">
|
||||
<PokemonEditButton PokemonId="_pokemon.Id" />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<button class="mt-1 p-2 btn btn-danger rounded-5 align-self-start shadow-sm" 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>
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Portfolio.Domain.Features.Pokemon;
|
||||
|
||||
namespace Portfolio.WebUI.Server.Components.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;
|
||||
|
||||
|
||||
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($"/pokemonsleep/pokemon/{_nextPokemonId.Value}");
|
||||
}
|
||||
|
||||
private void NavigateToPrevious()
|
||||
{
|
||||
if (_previousPokemonId.HasValue)
|
||||
Navigation.NavigateTo($"/pokemonsleep/pokemon/{_previousPokemonId.Value}");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
body {
|
||||
}
|
Loading…
Reference in New Issue