Compare commits
8 Commits
3b0cbecfc1
...
dd9b0006d3
Author | SHA1 | Date |
---|---|---|
|
dd9b0006d3 | |
|
0f235895f4 | |
|
a8f2bfd2b8 | |
|
6c8119d83c | |
|
3aad300f33 | |
|
b6b4be9dbb | |
|
2e1063c741 | |
|
3552aa99e4 |
|
@ -13,10 +13,12 @@ namespace Portfolio.Domain.Features.Pokemon
|
|||
public required string PokemonName { get; set; }
|
||||
public bool IsVariation { get; set; } = false;
|
||||
public string? VariationName { get; set; }
|
||||
public string? PokemonType { get; set; }
|
||||
public required string SleepType { get; set; }
|
||||
public required string Speciality { get; set; }
|
||||
public string? PokemonImageUrl { get; set; }
|
||||
public string? PokemonShinyImageUrl { get; set; }
|
||||
public string? FlavorText { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
|
124
Portfolio.Infrastructure/Migrations/20250404172651_include_pokemon_type.Designer.cs
generated
Normal file
124
Portfolio.Infrastructure/Migrations/20250404172651_include_pokemon_type.Designer.cs
generated
Normal file
|
@ -0,0 +1,124 @@
|
|||
// <auto-generated />
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Portfolio.Infrastructure;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Portfolio.Infrastructure.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("20250404172651_include_pokemon_type")]
|
||||
partial class include_pokemon_type
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "9.0.2")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Portfolio.Domain.Features.Pokemon.Pokemon", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<bool>("IsVariation")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<int>("PokemonId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("PokemonImageUrl")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("PokemonName")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("PokemonShinyImageUrl")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("PokemonType")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("SleepType")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Speciality")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("VariationName")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Pokemons");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Portfolio.Domain.Features.Pokemon_Natures.PokemonNature", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("BerryRating")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("IngredientRating")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Nature")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<int>("SkillRating")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("PokemonNatures");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Portfolio.Domain.Features.Pokemon_Subskills.PokemonSubskill", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("BerryRank")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("IngredientRank")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("SkillRank")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("SubSkill")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("PokemonSubskills");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Portfolio.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class include_pokemon_type : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "PokemonType",
|
||||
table: "Pokemons",
|
||||
type: "nvarchar(max)",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "PokemonType",
|
||||
table: "Pokemons");
|
||||
}
|
||||
}
|
||||
}
|
127
Portfolio.Infrastructure/Migrations/20250404173359_include_flavortext.Designer.cs
generated
Normal file
127
Portfolio.Infrastructure/Migrations/20250404173359_include_flavortext.Designer.cs
generated
Normal file
|
@ -0,0 +1,127 @@
|
|||
// <auto-generated />
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Portfolio.Infrastructure;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Portfolio.Infrastructure.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("20250404173359_include_flavortext")]
|
||||
partial class include_flavortext
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "9.0.2")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Portfolio.Domain.Features.Pokemon.Pokemon", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("FlavorText")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("IsVariation")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<int>("PokemonId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("PokemonImageUrl")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("PokemonName")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("PokemonShinyImageUrl")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("PokemonType")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("SleepType")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Speciality")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("VariationName")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Pokemons");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Portfolio.Domain.Features.Pokemon_Natures.PokemonNature", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("BerryRating")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("IngredientRating")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Nature")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<int>("SkillRating")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("PokemonNatures");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Portfolio.Domain.Features.Pokemon_Subskills.PokemonSubskill", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("BerryRank")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("IngredientRank")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("SkillRank")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("SubSkill")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("PokemonSubskills");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Portfolio.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class include_flavortext : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "FlavorText",
|
||||
table: "Pokemons",
|
||||
type: "nvarchar(max)",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "FlavorText",
|
||||
table: "Pokemons");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -29,6 +29,9 @@ namespace Portfolio.Infrastructure.Migrations
|
|||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("FlavorText")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("IsVariation")
|
||||
.HasColumnType("bit");
|
||||
|
||||
|
@ -45,6 +48,9 @@ namespace Portfolio.Infrastructure.Migrations
|
|||
b.Property<string>("PokemonShinyImageUrl")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("PokemonType")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("SleepType")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
|
|
@ -1,80 +1,8 @@
|
|||
@inject NavigationManager NavManager
|
||||
|
||||
<div class="pokemon-background">
|
||||
@foreach (var image in BackgroundImages)
|
||||
<div class="pokemon-background">
|
||||
@foreach (var image in _pokemonImages)
|
||||
{
|
||||
<img src="@image.Url"
|
||||
class="pokemon-bg-img"
|
||||
style="left:@image.Left%; top:@image.Top%; width:@image.Size}px; transform:rotate(@(image.Rotation)deg);" />
|
||||
}
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private List<PokemonImage> BackgroundImages = new();
|
||||
private Random random = new();
|
||||
|
||||
// Your specified set of Pokémon numbers
|
||||
private readonly int[] AllowedPokemonNumbers = new int[]
|
||||
{
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
|
||||
11, 12, 19, 20, 23, 24, 25, 26, 35, 36,
|
||||
37, 38, 39, 40, 50, 51, 52, 53, 54, 55,
|
||||
56, 57, 58, 59, 69, 70, 71, 74, 75, 76,
|
||||
79, 80, 81, 82, 84, 85, 92, 93, 94, 95,
|
||||
104, 105, 115, 122, 127, 132, 133, 134,
|
||||
135, 136, 147, 148, 149, 152, 153, 154,
|
||||
155, 156, 157, 158, 159, 160, 172, 173,
|
||||
174, 175, 176, 179, 180, 181, 185, 194,
|
||||
195, 196, 197, 199, 202, 208, 214, 215,
|
||||
225, 228, 229, 243, 244, 245, 246, 247,
|
||||
248, 280, 281, 282, 287, 288, 289, 302,
|
||||
304, 305, 306, 316, 317, 333, 334, 353,
|
||||
354, 359, 360, 363, 364, 365, 403, 404,
|
||||
405, 425, 426, 438, 439, 447, 448, 453,
|
||||
454, 459, 460, 461, 462, 468, 470, 471,
|
||||
475, 627, 628, 700, 702, 736, 737, 738,
|
||||
759, 760, 764, 778, 845, 906, 907, 908,
|
||||
909, 910, 911, 912, 913, 914, 921, 922,
|
||||
923, 980
|
||||
};
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
GeneratePokemonBackground();
|
||||
}
|
||||
|
||||
private void GeneratePokemonBackground()
|
||||
{
|
||||
var normalPath = $"/pokemon_images/normal/";
|
||||
var shinyPath = $"/pokemon_images/shiny/";
|
||||
|
||||
for (int i = 0; i < 30; i++) // Generate 30 Pokémon images
|
||||
{
|
||||
int pokemonNumber = AllowedPokemonNumbers[random.Next(AllowedPokemonNumbers.Length)];
|
||||
|
||||
// 10% chance to use a shiny version
|
||||
bool isShiny = random.NextDouble() < 0.1;
|
||||
string imageUrl = isShiny
|
||||
? $"{shinyPath}{pokemonNumber}.png"
|
||||
: $"{normalPath}{pokemonNumber}.png";
|
||||
|
||||
BackgroundImages.Add(new PokemonImage
|
||||
{
|
||||
Url = imageUrl,
|
||||
Left = random.Next(0, 100), // 0-100% of background container width
|
||||
Top = random.Next(0, 100), // 0-100% of background container height
|
||||
Size = random.Next(50, 130), // 50px to 130px
|
||||
Rotation = random.Next(0, 360) // Random rotation
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private class PokemonImage
|
||||
{
|
||||
public string Url { get; set; } = "";
|
||||
public int Left { get; set; }
|
||||
public int Top { get; set; }
|
||||
public int Size { get; set; }
|
||||
public int Rotation { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Portfolio.Domain.Features.Pokemon;
|
||||
|
||||
namespace Portfolio.WebUI.Server.Components.Component
|
||||
{
|
||||
public partial class PokemonBackground
|
||||
{
|
||||
|
||||
private class PokemonImage
|
||||
{
|
||||
public string Url { get; set; } = "";
|
||||
public int Left { get; set; }
|
||||
public int Top { get; set; }
|
||||
public int Size { get; set; }
|
||||
public int Rotation { get; set; }
|
||||
}
|
||||
|
||||
|
||||
[Parameter]
|
||||
public List<string> PokemonImages { get; set; }
|
||||
[Parameter]
|
||||
public List<string> ShinyPokemonImages { get; set; }
|
||||
|
||||
private List<PokemonImage> _pokemonImages = new List<PokemonImage>();
|
||||
private List<PokemonImage> _shinyPokemonImages = new List<PokemonImage>();
|
||||
private Random random = new Random();
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await LoadPokemonBackgrounds();
|
||||
}
|
||||
|
||||
private async Task LoadPokemonBackgrounds()
|
||||
{
|
||||
|
||||
foreach (var pokemonimgurl in PokemonImages)
|
||||
{
|
||||
Console.WriteLine(pokemonimgurl);
|
||||
_pokemonImages.Add(new PokemonImage
|
||||
{
|
||||
Url = pokemonimgurl, // URL retrieved from the database
|
||||
Left = random.Next(0, 100),
|
||||
Top = random.Next(0, 100),
|
||||
Size = random.Next(50, 130),
|
||||
Rotation = random.Next(0, 360)
|
||||
});
|
||||
}
|
||||
foreach (var pokemonimgurl in ShinyPokemonImages)
|
||||
{
|
||||
_shinyPokemonImages.Add(new PokemonImage
|
||||
{
|
||||
Url = pokemonimgurl, // URL retrieved from the database
|
||||
Left = random.Next(0, 100),
|
||||
Top = random.Next(0, 100),
|
||||
Size = random.Next(50, 130),
|
||||
Rotation = random.Next(0, 360)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
@attribute [StreamRendering]
|
||||
@rendermode InteractiveServer
|
||||
|
||||
<div class="position-relative bg-white pokemon-card border border-5 border-info-subtle shadow-sm ">
|
||||
<!-- Pokemon Name, Number, and Type -->
|
||||
<div class="z-3">
|
||||
@if (_pokemon.IsVariation)
|
||||
{
|
||||
<div class="pokemon-name"><p class="fw-bold card-title">@_pokemon.VariationName @_pokemon.PokemonName</p></div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="pokemon-name"><p class="fw-bold card-title">@_pokemon.PokemonName</p></div>
|
||||
}
|
||||
<div class="pokemon-number">
|
||||
<p class="fw-light card-text">Pokédex #<strong>@_pokemon.PokemonId</strong></p>
|
||||
</div>
|
||||
<div >
|
||||
<img class="pokemon-type" src="@GetTypeImageUrl(_pokemon.PokemonType)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pokemon Image -->
|
||||
<div class="flip-container z-1" @onclick="() => ToggleImage()">
|
||||
<div class="flipper @(isShiny ? "flipped" : "")">
|
||||
<img class="pokemon-image front" src="@_pokemon.PokemonImageUrl" />
|
||||
<img class="pokemon-image back" src="@_pokemon.PokemonShinyImageUrl" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-info-subtle border rounded border-2 border-info pokemon-flavor-text">
|
||||
@if (string.IsNullOrEmpty(_pokemon.FlavorText))
|
||||
{
|
||||
<p class="">[ Pokemon Flavor Text Placeholder ]</p>
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="fw-light ">@_pokemon.FlavorText</p>
|
||||
|
||||
}
|
||||
</div>
|
||||
|
||||
<!-- Pokemon Sleep Type and Specialty Badges -->
|
||||
<div class="position-absolute bottom-0 end-0 mb-1 me-1 z-2">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="m-1 badge @_pokemon.SleepType.ToLower()"><p class="statText">@_pokemon.SleepType</p></div>
|
||||
<div class="m-1 badge @_pokemon.Speciality.ToLower()"><p class="statText">@_pokemon.Speciality</p></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
|
@ -0,0 +1,42 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Portfolio.Domain.Features.Pokemon;
|
||||
|
||||
namespace Portfolio.WebUI.Server.Components.Component
|
||||
{
|
||||
public partial class PokemonCard
|
||||
{
|
||||
[Parameter]
|
||||
public Pokemon Pokemon { get; set; }
|
||||
|
||||
private Pokemon _pokemon { get; set; }
|
||||
|
||||
private bool isShiny = false;
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
if (Pokemon != null)
|
||||
{
|
||||
_pokemon = Pokemon;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void ToggleImage()
|
||||
{
|
||||
isShiny = !isShiny;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private string GetTypeImageUrl(string pokemonType)
|
||||
{
|
||||
if (string.IsNullOrEmpty(pokemonType))
|
||||
{
|
||||
return "https://www.serebii.net/pokemonsleep/pokemon/type/normal.png"; // Fallback image
|
||||
}
|
||||
|
||||
return $"https://www.serebii.net/pokemonsleep/pokemon/type/{pokemonType.ToLower()}.png";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
.pokemon-card {
|
||||
position: relative;
|
||||
width: 24rem;
|
||||
height: 32rem;
|
||||
max-width: 24rem;
|
||||
max-height: 32rem;
|
||||
border-radius: 5% / 3.5%;
|
||||
}
|
||||
|
||||
.pokemon-name {
|
||||
position: absolute;
|
||||
top: 0 !important;
|
||||
left: 0 !important;
|
||||
margin-top: 1.5rem !important;
|
||||
margin-left: 0.5rem !important;
|
||||
transform: translateY(-50%) !important;
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.pokemon-number {
|
||||
position: absolute;
|
||||
top: 0 !important;
|
||||
left: 0 !important;
|
||||
margin-top: 3.3rem !important;
|
||||
margin-left: 1.5rem !important;
|
||||
transform: translateY(-50%) !important;
|
||||
font-size: .75rem;
|
||||
}
|
||||
|
||||
.pokemon-type {
|
||||
position: absolute;
|
||||
top: 0 !important;
|
||||
right: 0 !important;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
margin-top: .5rem !important;
|
||||
margin-right: .5rem !important;
|
||||
}
|
||||
|
||||
.pokemon-image {
|
||||
width: 100%; /* Look to flip-container for the width/height of image */
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.pokemon-flavor-text {
|
||||
position: absolute;
|
||||
top: 60% !important;
|
||||
left: 50% !important;
|
||||
width: 90%;
|
||||
height: 20%;
|
||||
padding: 0.25rem;
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
margin-top: 3rem !important;
|
||||
transform: translateX(-50%) !important;
|
||||
|
||||
display: flex; /* Centers text inside */
|
||||
align-items: start;
|
||||
justify-content: center; /* Horizontally centers text */
|
||||
overflow: hidden; /* Ensures no scrollbar */
|
||||
}
|
||||
|
||||
.pokemon-flavor-text p {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
text-align: start;
|
||||
font-size: min(14px, 1.5vw); /* Scales font but won't exceed 14px */
|
||||
line-height: 1.2; /* Adjust spacing for readability */
|
||||
white-space: normal; /* Ensures wrapping */
|
||||
word-wrap: break-word;
|
||||
hyphens: auto;
|
||||
}
|
||||
|
||||
.flip-container {
|
||||
position: absolute !important;
|
||||
top: 40% !important;
|
||||
left: 50% !important;
|
||||
transform: translate(-50%, -50%) !important;
|
||||
perspective: 1000px;
|
||||
display: inline-block;
|
||||
width: 20rem;
|
||||
height: 20rem;
|
||||
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: 90px;
|
||||
height: 30px;
|
||||
color: white;
|
||||
padding: 4px 8px;
|
||||
border-radius: 30px;
|
||||
}
|
||||
|
||||
.statText {
|
||||
position: relative;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: .8rem;
|
||||
}
|
||||
|
||||
.dozing {
|
||||
background-color: #fcdc5e;
|
||||
}
|
||||
|
||||
.snoozing {
|
||||
background-color: #4ce8ed;
|
||||
}
|
||||
|
||||
.slumbering {
|
||||
background-color: #4588fb;
|
||||
}
|
||||
|
||||
.berries {
|
||||
background-color: #24d86b;
|
||||
}
|
||||
|
||||
.ingredients {
|
||||
background-color: #fdbe4d;
|
||||
}
|
||||
|
||||
.skills {
|
||||
background-color: #47a0fc;
|
||||
}
|
|
@ -19,7 +19,7 @@ else
|
|||
<!-- Table Header -->
|
||||
<div class="card-header bg-secondary bg-gradient ml-0 py-3">
|
||||
<div class="row">
|
||||
<div class="col-12 text-center position-rel">
|
||||
<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>
|
||||
|
@ -33,12 +33,13 @@ else
|
|||
<!-- Table Head -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-bg-info" scope="col"></th>
|
||||
<th class="text-bg-info" scope="col">#</th>
|
||||
<th class="text-bg-info" scope="col">Pokemon</th>
|
||||
<th class="text-bg-info" scope="col">Sleep Type</th>
|
||||
<th class="text-bg-info" scope="col">Speciality</th>
|
||||
<th class="text-bg-info" scope="col"></th>
|
||||
<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>
|
||||
|
||||
|
@ -94,17 +95,25 @@ else
|
|||
<td style="vertical-align: auto;"> @pokemon.PokemonName</td>
|
||||
}
|
||||
|
||||
<!-- Section 4: Sleep Type -->
|
||||
|
||||
<!-- Section 4: Pokemon Type -->
|
||||
<td >
|
||||
<div class="m-1 col-1" >
|
||||
<img src="@GetTypeImageUrl(pokemon.PokemonType)" class="" style="width:60px; height:60px;" />
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<!-- Section 5: Sleep Type -->
|
||||
<td style="vertical-align: auto;">
|
||||
<div class="m-1 col-1 badge @pokemon.SleepType.ToLower()"><p class="statText">@pokemon.SleepType</p></div>
|
||||
</td>
|
||||
|
||||
<!-- Section 5: Speciality -->
|
||||
<!-- Section 6: Speciality -->
|
||||
<td style="padding-right: 30px; vertical-align: auto;">
|
||||
<div class="m-1 col-1 badge @pokemon.Speciality.ToLower()"><p class="statText">@pokemon.Speciality</p></div>
|
||||
</td>
|
||||
|
||||
<!-- Section 6: Functional Buttons -->
|
||||
<!-- 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">
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||
using Microsoft.JSInterop;
|
||||
using Portfolio.Domain.Features.Pokemon;
|
||||
|
||||
|
@ -6,19 +7,18 @@ namespace Portfolio.WebUI.Server.Components.Component
|
|||
{
|
||||
public partial class PokemonTable
|
||||
{
|
||||
[Parameter]
|
||||
public List<Pokemon> AllPokemon { get; set; }
|
||||
|
||||
private List<Pokemon> pokemons = new List<Pokemon>();
|
||||
private Dictionary<int, bool> isShiny = new Dictionary<int, bool>();
|
||||
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
var result = await PokemonService.GetAllPokemonAsync();
|
||||
if (result is not null)
|
||||
{
|
||||
pokemons = result;
|
||||
pokemons.Sort((x, y) => x.PokemonId.CompareTo(y.PokemonId));
|
||||
if (AllPokemon != null) {
|
||||
pokemons = AllPokemon.ToList();
|
||||
|
||||
// Initialize dictionary with false (show base image first)
|
||||
foreach (var pokemon in pokemons)
|
||||
{
|
||||
isShiny[pokemon.Id] = false;
|
||||
|
@ -54,5 +54,16 @@ namespace Portfolio.WebUI.Server.Components.Component
|
|||
{
|
||||
Navigation.NavigateTo($"/pokemonsleep/edit/{id}");
|
||||
}
|
||||
|
||||
private string GetTypeImageUrl(string pokemonType)
|
||||
{
|
||||
if (string.IsNullOrEmpty(pokemonType))
|
||||
{
|
||||
return "https://www.serebii.net/pokemonsleep/pokemon/type/normal.png"; // Fallback image
|
||||
}
|
||||
|
||||
return $"https://www.serebii.net/pokemonsleep/pokemon/type/{pokemonType.ToLower()}.png";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,3 +94,14 @@
|
|||
}
|
||||
|
||||
|
||||
.pokemon-dex-width {
|
||||
width:3%;
|
||||
}
|
||||
|
||||
.pokemon-name-width {
|
||||
width:10%;
|
||||
}
|
||||
|
||||
.pokemon-type-width {
|
||||
width:5%;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
<div class="d-flex flex-column flex-shrink-0 p-3 bg-info vh-100" style="width: 280px; ">
|
||||
<a href="/" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto link-primary text-decoration-none">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-arrow-through-heart" viewBox="0 0 16 16">
|
||||
@inject IJSRuntime JS
|
||||
|
||||
<div class="d-flex flex-column flex-shrink-0 p-3 bg-info vh-100 sidebar @(isSidebarOpen ? "open" : "closed") " style="transition: width 0.3s;">
|
||||
<div class="d-flex align-items-center mb-3 mb-md-0 me-md-auto link-primary text-decoration-none">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-arrow-through-heart" viewBox="0 0 16 16" @onclick="ToggleSidebar" style="cursor: pointer;">
|
||||
<path fill-rule="evenodd" d="M2.854 15.854A.5.5 0 0 1 2 15.5V14H.5a.5.5 0 0 1-.354-.854l1.5-1.5A.5.5 0 0 1 2 11.5h1.793l.53-.53c-.771-.802-1.328-1.58-1.704-2.32-.798-1.575-.775-2.996-.213-4.092C3.426 2.565 6.18 1.809 8 3.233c1.25-.98 2.944-.928 4.212-.152L13.292 2 12.147.854A.5.5 0 0 1 12.5 0h3a.5.5 0 0 1 .5.5v3a.5.5 0 0 1-.854.354L14 2.707l-1.006 1.006c.236.248.44.531.6.845.562 1.096.585 2.517-.213 4.092-.793 1.563-2.395 3.288-5.105 5.08L8 13.912l-.276-.182a22 22 0 0 1-2.685-2.062l-.539.54V14a.5.5 0 0 1-.146.354zm2.893-4.894A20.4 20.4 0 0 0 8 12.71c2.456-1.666 3.827-3.207 4.489-4.512.679-1.34.607-2.42.215-3.185-.817-1.595-3.087-2.054-4.346-.761L8 4.62l-.358-.368c-1.259-1.293-3.53-.834-4.346.761-.392.766-.464 1.845.215 3.185.323.636.815 1.33 1.519 2.065l1.866-1.867a.5.5 0 1 1 .708.708z" />
|
||||
</svg>
|
||||
<span class="fs-4 mx-2">Kira Jiroux</span>
|
||||
</a>
|
||||
</div>
|
||||
<hr>
|
||||
<ul class="nav nav-pills flex-column mb-auto">
|
||||
<li class="nav-item">
|
||||
|
@ -43,4 +45,16 @@
|
|||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@code {
|
||||
private bool isSidebarOpen = true;
|
||||
|
||||
private async void ToggleSidebar()
|
||||
{
|
||||
isSidebarOpen = !isSidebarOpen;
|
||||
await JS.InvokeVoidAsync("console.log", $"Sidebar toggled: {isSidebarOpen}");
|
||||
StateHasChanged(); // Force the UI to update
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
.sidebar.closed {
|
||||
width: 0;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebar.open {
|
||||
width: 256px;
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PageTitle>Home</PageTitle>
|
||||
|
||||
<PokemonBackground />
|
||||
<!-- <PokemonBackground />-->
|
||||
<h1 class="test">Hello, world!</h1>
|
||||
<p>Ensuring that git is connected properly.</p>
|
||||
|
||||
|
|
|
@ -14,8 +14,11 @@
|
|||
}
|
||||
else
|
||||
{
|
||||
<div class="w-50 mt-5 m-auto create-container">
|
||||
<div class="card-header bg-secondary bg-gradient ml-0 py-3">
|
||||
<!-- 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>
|
||||
|
@ -23,7 +26,8 @@ else
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container m-lg-1">
|
||||
<!-- Body -->
|
||||
<div class="p-3 w-100 flex-column ">
|
||||
<EditForm class="col mb-3" Model="pokemon" OnValidSubmit="HandleSubmit">
|
||||
<DataAnnotationsValidator />
|
||||
|
||||
|
@ -31,27 +35,55 @@ else
|
|||
<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 disabled />
|
||||
<InputText id="PokemonName" @bind-Value="pokemon.PokemonName" class="form-control w-75" required />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row 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>
|
||||
<div class="row">
|
||||
<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>
|
||||
|
||||
<div class="row 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 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>
|
||||
|
||||
<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>
|
||||
|
||||
|
||||
<!-- New Image URL Field -->
|
||||
<div class="row mb-3 m-auto">
|
||||
|
@ -63,6 +95,11 @@ else
|
|||
<InputText id="ImageUrl" @bind-Value="pokemon.PokemonShinyImageUrl" class="form-control" />
|
||||
</div>
|
||||
|
||||
<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>
|
||||
</EditForm>
|
||||
|
@ -71,22 +108,5 @@ else
|
|||
}
|
||||
|
||||
@code {
|
||||
[Parameter] public int Id { get; set; }
|
||||
private Pokemon? pokemon;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
pokemon = await PokemonService.GetPokemonByIdAsync(Id);
|
||||
}
|
||||
|
||||
private async Task HandleSubmit()
|
||||
{
|
||||
await PokemonService.UpdatePokemonAsync(pokemon);
|
||||
Navigation.NavigateTo("/pokemonsleep");
|
||||
}
|
||||
|
||||
private void Cancel()
|
||||
{
|
||||
Navigation.NavigateTo("/pokemonsleep");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Portfolio.Domain.Features.Pokemon;
|
||||
|
||||
namespace Portfolio.WebUI.Server.Components.Pages
|
||||
{
|
||||
public partial class PokemonEdit
|
||||
{
|
||||
[Parameter] public int Id { get; set; }
|
||||
private Pokemon? pokemon;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
pokemon = await PokemonService.GetPokemonByIdAsync(Id);
|
||||
}
|
||||
|
||||
private async Task HandleSubmit()
|
||||
{
|
||||
await PokemonService.UpdatePokemonAsync(pokemon);
|
||||
Navigation.NavigateTo("/pokemonsleep");
|
||||
}
|
||||
|
||||
private void Cancel()
|
||||
{
|
||||
Navigation.NavigateTo("/pokemonsleep");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
body {
|
||||
}
|
||||
|
||||
.edit-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;
|
||||
}
|
|
@ -18,27 +18,31 @@
|
|||
}
|
||||
else
|
||||
{
|
||||
<div class="w-75 mt-3 m-auto rate-container">
|
||||
<!-- Total Component -->
|
||||
<div class="w-75 mt-3 m-auto rate-container bg-info ">
|
||||
|
||||
<div class="card-header bg-secondary bg-gradient ml-0 py-3">
|
||||
<!-- Header -->
|
||||
<div class="card-header bg-secondary ml-0 py-3 w-100 ">
|
||||
<div class="row">
|
||||
<div class="col-12 text-center">
|
||||
<div class=" text-center">
|
||||
<h2 class="text-info">Pokémon Rater</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body p-4 col-12">
|
||||
<!-- Section 1: Pokemon Selection -->
|
||||
<div class="row pb-3">
|
||||
<div class="col-3">
|
||||
<div class="position-relative">
|
||||
<!-- Body -->
|
||||
<div class="p-3 w-100 flex-column ">
|
||||
<!-- Section 1: Top - Pokemon Selection -->
|
||||
<div class="row flex-row justify-content-end">
|
||||
<div class="pokemon-search col">
|
||||
<div class="position-relative pb-3" >
|
||||
<!-- Pokemon Selection -->
|
||||
<input type="text"
|
||||
class="form-control form-control-lg"
|
||||
class="form-control form-control"
|
||||
@bind="PokemonSearchTerm"
|
||||
placeholder="Search Pokémon..."
|
||||
@oninput="OnSearchTextChanged" />
|
||||
|
||||
@oninput="OnSearchTextChanged"
|
||||
/>
|
||||
@if (FilteredPokemonList.Any() && !string.IsNullOrWhiteSpace(PokemonSearchTerm))
|
||||
{
|
||||
<ul class="list-group position-absolute w-100" style="z-index: 1000; max-height: 200px; overflow-y: auto;">
|
||||
|
@ -59,137 +63,120 @@ else
|
|||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<button class="btn btn-danger">Clear</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Section 2: Pokemon Rating -->
|
||||
<!-- Section 2: Bottom - Pokemon -->
|
||||
@if (SelectedPokemon != null)
|
||||
{
|
||||
<div class="border rounded p-3 row">
|
||||
<div class="d-flex align-top col">
|
||||
|
||||
<!-- Pokemon Interface -->
|
||||
<div class="m-3 p-1 col-5">
|
||||
<!-- Image and other Pokemon info -->
|
||||
<div class="flip-container" @onclick="() => ToggleImage(SelectedPokemon.Id)">
|
||||
<div class="flipper @(isShiny[SelectedPokemon.Id] ? "flipped" : "")">
|
||||
<img class="front" src="/pokemon_images/normal/@(SelectedPokemon.IsVariation ? $"{SelectedPokemon.PokemonId}-{SelectedPokemon.VariationName.ToLower()}{SelectedPokemon.PokemonName.ToLower()}" : SelectedPokemon.PokemonId).png" />
|
||||
<img class="back" src="/pokemon_images/shiny/@(SelectedPokemon.IsVariation ? $"{SelectedPokemon.PokemonId}-{SelectedPokemon.VariationName.ToLower()}{SelectedPokemon.PokemonName.ToLower()}" : SelectedPokemon.PokemonId).png" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-7">
|
||||
<div class="row mb-0">
|
||||
@if (SelectedPokemon.IsVariation)
|
||||
{
|
||||
<h2>@SelectedPokemon.VariationName @SelectedPokemon.PokemonName</h2>
|
||||
}
|
||||
else
|
||||
{
|
||||
<h3>@SelectedPokemon.PokemonName</h3>
|
||||
}
|
||||
</div>
|
||||
<div class="mt-0">
|
||||
<p class="col-4">Pokédex #<strong>@SelectedPokemon.PokemonId</strong></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-5 p-1">
|
||||
<div class="row d-flex justify-content-between">
|
||||
<div class="m-1 col badge @SelectedPokemon.SleepType.ToLower()"><p class="statText">@SelectedPokemon.SleepType</p></div>
|
||||
<div class="m-1 col badge @SelectedPokemon.Speciality.ToLower()"><p class="statText">@SelectedPokemon.Speciality</p></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row w-100">
|
||||
<!-- Section 2A: Left Side - Pokemon Card View -->
|
||||
<div class="col">
|
||||
<div class="position-relative d-flex justify-content-center">
|
||||
<PokemonCard Pokemon="SelectedPokemon" />
|
||||
</div>
|
||||
|
||||
<!-- Nature / Subskill Selection Dropdowns-->
|
||||
<div class="m-3 p-1 col">
|
||||
<h4 class="mb-3">Select Nature & Subskills</h4>
|
||||
|
||||
<!-- Nature -->
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<label>Select Nature</label>
|
||||
<select class="form-control form-control-lg mb-2" @bind="SelectedNatureId">
|
||||
<option value="" disabled>Choose Nature...</option>
|
||||
@foreach (var nature in NatureList)
|
||||
{
|
||||
<option value="@nature.Id">@nature.Nature</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Subskills -->
|
||||
<div class="row">
|
||||
<!-- Subskill 1 -->
|
||||
<div class="col-4">
|
||||
<label for="subskillSelect1">Select Level 10 Subskill</label>
|
||||
<select id="subskillSelect1" class="form-control form-control mb-2" @bind="subskillSelect1">
|
||||
<option value="" disabled selected>Choose Subskill...</option>
|
||||
@foreach (var subskill in SubskillList)
|
||||
{
|
||||
<option value="@subskill.Id">@subskill.SubSkill</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
<!-- Subskill 2 -->
|
||||
<div class="col-4">
|
||||
<label for="subskillSelect2">Select Level 25 Subskill</label>
|
||||
<select id="subskillSelect2" class="form-control form-control mb-2" @bind="subskillSelect2">
|
||||
<option value="" disabled selected>Choose Subskill...</option>
|
||||
@foreach (var subskill in SubskillList)
|
||||
{
|
||||
<option value="@subskill.Id">@subskill.SubSkill</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
<!-- Subskill 3 -->
|
||||
<div class="col-4">
|
||||
<label for="subskillSelect3">Select Level 50 Subskill</label>
|
||||
<select id="subskillSelect3" class="form-control form-control mb-2" @bind="subskillSelect3">
|
||||
<option value="" disabled selected>Choose Subskill...</option>
|
||||
@foreach (var subskill in SubskillList)
|
||||
{
|
||||
<option value="@subskill.Id">@subskill.SubSkill</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<!-- Subskill 4 -->
|
||||
<div class="col-4">
|
||||
<label for="subskillSelect4">Select Level 75 Subskill</label>
|
||||
<select id="subskillSelect4" disabled class="form-control form-control mb-2" @bind="subskillSelect4">
|
||||
<option value="" disabled selected>Choose Subskill...</option>
|
||||
@foreach (var subskill in SubskillList)
|
||||
{
|
||||
<option value="@subskill.Id">@subskill.SubSkill</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
<!-- Subskill 5 -->
|
||||
<div class="col-4">
|
||||
<label for="subskillSelect5">Select Level 100 Subskill</label>
|
||||
<select id="subskillSelect5" disabled class="form-control form-control mb-2" @bind="subskillSelect5">
|
||||
<option value="" disabled selected>Choose Subskill...</option>
|
||||
@foreach (var subskill in SubskillList)
|
||||
{
|
||||
<option value="@subskill.Id">@subskill.SubSkill</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Calculate -->
|
||||
<div class="d-flex justify-content-between align-items-center mt-3 ">
|
||||
<button class="btn btn-primary mx-2" @onclick="CalculateScore">Calculate Final Score</button>
|
||||
<h4>Final Score: <span class="finalScore" style="background-color: @ScoreBackgroundColor">@FinalScore</span></h4>
|
||||
<!-- Section 2B: Right Side - Stat Selection + Form Submission -->
|
||||
<div class="col">
|
||||
<h4 class="mb-3">Select Nature & Subskills</h4>
|
||||
|
||||
<!-- Nature -->
|
||||
<div class="">
|
||||
<div class="">
|
||||
<label>Select Nature</label>
|
||||
<select class="form-control form-control-sm mb-2" @bind="SelectedNatureId">
|
||||
<option value="" disabled>Choose Nature...</option>
|
||||
@foreach (var nature in NatureList)
|
||||
{
|
||||
<option value="@nature.Id">@nature.Nature</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Subskill 1 -->
|
||||
<div class="">
|
||||
<div class="">
|
||||
<label for="subskillSelect1">Select Level 10 Subskill</label>
|
||||
<select id="subskillSelect1" class="form-control form-control-sm mb-2" @bind="subskillSelect1">
|
||||
<option value="" disabled selected>Choose Subskill...</option>
|
||||
@foreach (var subskill in SubskillList)
|
||||
{
|
||||
<option value="@subskill.Id">@subskill.SubSkill</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Subskill 2 -->
|
||||
<div class="">
|
||||
<div class="">
|
||||
<label for="subskillSelect2">Select Level 25 Subskill</label>
|
||||
<select id="subskillSelect2" class="form-control form-control-sm mb-2" @bind="subskillSelect2">
|
||||
<option value="" disabled selected>Choose Subskill...</option>
|
||||
@foreach (var subskill in SubskillList)
|
||||
{
|
||||
<option value="@subskill.Id">@subskill.SubSkill</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Subskill 3 -->
|
||||
<div class="">
|
||||
<div class="">
|
||||
<label for="subskillSelect3">Select Level 50 Subskill</label>
|
||||
<select id="subskillSelect3" class="form-control form-control-sm mb-2" @bind="subskillSelect3">
|
||||
<option value="" disabled selected>Choose Subskill...</option>
|
||||
@foreach (var subskill in SubskillList)
|
||||
{
|
||||
<option value="@subskill.Id">@subskill.SubSkill</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Subskill 4 Disabled -->
|
||||
<div class="">
|
||||
<div class="">
|
||||
<label for="subskillSelect4">Select Level 75 Subskill</label>
|
||||
<select id="subskillSelect4" disabled class="form-control form-control-sm mb-2" @bind="subskillSelect4">
|
||||
<option value="" disabled selected>Choose Subskill...</option>
|
||||
@foreach (var subskill in SubskillList)
|
||||
{
|
||||
<option value="@subskill.Id">@subskill.SubSkill</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Subskill 5 Disabled -->
|
||||
<div class="">
|
||||
<div class="">
|
||||
<label for="subskillSelect5">Select Level 100 Subskill</label>
|
||||
<select id="subskillSelect5" disabled class="form-control form-control-sm mb-2" @bind="subskillSelect5">
|
||||
<option value="" disabled selected>Choose Subskill...</option>
|
||||
@foreach (var subskill in SubskillList)
|
||||
{
|
||||
<option value="@subskill.Id">@subskill.SubSkill</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Calculate Score -->
|
||||
<div class="">
|
||||
<div class="d-flex justify-content-between align-items-center mt-3">
|
||||
<button class="btn btn-primary" @onclick="CalculateScore">Calculate Final Score</button>
|
||||
<h4 class="bg-white border border-1 rounded p-2 m-2">
|
||||
<span class="finalScore rounded" style="background-color: @ScoreBackgroundColor">@FinalScore</span>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -39,9 +39,6 @@ namespace Portfolio.WebUI.Server.Components.Pages
|
|||
private string ScoreBackgroundColor;
|
||||
private string ScoreColor;
|
||||
|
||||
private string PokemonImageUrl => SelectedPokemon != null
|
||||
? $"https://www.serebii.net/pokemonsleep/pokemon/{SelectedPokemon.Id}.png"
|
||||
: string.Empty;
|
||||
|
||||
private string PokemonSearchTerm = string.Empty;
|
||||
|
||||
|
@ -54,6 +51,7 @@ namespace Portfolio.WebUI.Server.Components.Pages
|
|||
{
|
||||
// Trigger filtering as the user types
|
||||
PokemonSearchTerm = e.Value.ToString();
|
||||
|
||||
}
|
||||
|
||||
private async Task SelectPokemon(Pokemon pokemon)
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
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;
|
||||
|
||||
}
|
||||
|
||||
.pokemon-search {
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
.flip-container {
|
||||
|
@ -79,8 +84,6 @@
|
|||
}
|
||||
|
||||
.finalScore {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
color: white;
|
||||
padding: 4px 8px;
|
||||
text-align: center;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
@page "/pokemonsleep"
|
||||
|
||||
@inject IPokemonService PokemonService
|
||||
|
||||
@attribute [StreamRendering]
|
||||
@rendermode InteractiveServer
|
||||
|
||||
|
@ -7,10 +9,10 @@
|
|||
<PageTitle>Pokémon Sleep</PageTitle>
|
||||
|
||||
<div class="w-100">
|
||||
<PokemonBackground />
|
||||
<PokemonBackground PokemonImages="pokemonImageUrls" ShinyPokemonImages="pokemonShinyImageUrls" />
|
||||
|
||||
<PokemonHeader />
|
||||
|
||||
<PokemonTable />
|
||||
<PokemonTable AllPokemon="pokemons"/>
|
||||
|
||||
</div>
|
|
@ -0,0 +1,30 @@
|
|||
using Portfolio.Application.Services.PokemonService;
|
||||
using Portfolio.Domain.Features.Pokemon;
|
||||
|
||||
namespace Portfolio.WebUI.Server.Components.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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue