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:
Kira Jiroux 2025-04-05 00:28:36 -04:00
parent 42d3a864e4
commit 99ac4581ae
17 changed files with 608 additions and 96 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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>

View File

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

View File

@ -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>

View File

@ -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>

View File

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

View File

@ -6,15 +6,8 @@
@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">
@ -42,7 +35,14 @@ else
<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)
@ -55,7 +55,8 @@ else
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,11 +116,7 @@ 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">
@ -132,9 +129,11 @@ else
</tr>
}
</tbody>
}
</table>
</div>
</div>
</div>
}

View File

@ -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>

View File

@ -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>
<!-- 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 {
}

View File

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

View File

@ -9,7 +9,7 @@
<PageTitle>Pokémon Sleep</PageTitle>
<div class="w-100">
<PokemonBackground PokemonImages="pokemonImageUrls" ShinyPokemonImages="pokemonShinyImageUrls" />
<!-- <PokemonBackground PokemonImages="pokemonImageUrls" ShinyPokemonImages="pokemonShinyImageUrls" /> -->
<PokemonHeader />

View File

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

View File

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

View File

@ -0,0 +1,2 @@
body {
}