diff --git a/Portfolio.Domain/Features/Pokemon/Pokemon.cs b/Portfolio.Domain/Features/Pokemon/Pokemon.cs index a92debf..d730256 100644 --- a/Portfolio.Domain/Features/Pokemon/Pokemon.cs +++ b/Portfolio.Domain/Features/Pokemon/Pokemon.cs @@ -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; } } diff --git a/Portfolio.Infrastructure/Migrations/20250404172651_include_pokemon_type.Designer.cs b/Portfolio.Infrastructure/Migrations/20250404172651_include_pokemon_type.Designer.cs new file mode 100644 index 0000000..ce7e01a --- /dev/null +++ b/Portfolio.Infrastructure/Migrations/20250404172651_include_pokemon_type.Designer.cs @@ -0,0 +1,124 @@ +// +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 + { + /// + 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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("IsVariation") + .HasColumnType("bit"); + + b.Property("PokemonId") + .HasColumnType("int"); + + b.Property("PokemonImageUrl") + .HasColumnType("nvarchar(max)"); + + b.Property("PokemonName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PokemonShinyImageUrl") + .HasColumnType("nvarchar(max)"); + + b.Property("PokemonType") + .HasColumnType("nvarchar(max)"); + + b.Property("SleepType") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Speciality") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("VariationName") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Pokemons"); + }); + + modelBuilder.Entity("Portfolio.Domain.Features.Pokemon_Natures.PokemonNature", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("BerryRating") + .HasColumnType("int"); + + b.Property("IngredientRating") + .HasColumnType("int"); + + b.Property("Nature") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SkillRating") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("PokemonNatures"); + }); + + modelBuilder.Entity("Portfolio.Domain.Features.Pokemon_Subskills.PokemonSubskill", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("BerryRank") + .HasColumnType("int"); + + b.Property("IngredientRank") + .HasColumnType("int"); + + b.Property("SkillRank") + .HasColumnType("int"); + + b.Property("SubSkill") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("PokemonSubskills"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Portfolio.Infrastructure/Migrations/20250404172651_include_pokemon_type.cs b/Portfolio.Infrastructure/Migrations/20250404172651_include_pokemon_type.cs new file mode 100644 index 0000000..e488823 --- /dev/null +++ b/Portfolio.Infrastructure/Migrations/20250404172651_include_pokemon_type.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Portfolio.Infrastructure.Migrations +{ + /// + public partial class include_pokemon_type : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "PokemonType", + table: "Pokemons", + type: "nvarchar(max)", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "PokemonType", + table: "Pokemons"); + } + } +} diff --git a/Portfolio.Infrastructure/Migrations/20250404173359_include_flavortext.Designer.cs b/Portfolio.Infrastructure/Migrations/20250404173359_include_flavortext.Designer.cs new file mode 100644 index 0000000..499f5c6 --- /dev/null +++ b/Portfolio.Infrastructure/Migrations/20250404173359_include_flavortext.Designer.cs @@ -0,0 +1,127 @@ +// +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 + { + /// + 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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("FlavorText") + .HasColumnType("nvarchar(max)"); + + b.Property("IsVariation") + .HasColumnType("bit"); + + b.Property("PokemonId") + .HasColumnType("int"); + + b.Property("PokemonImageUrl") + .HasColumnType("nvarchar(max)"); + + b.Property("PokemonName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PokemonShinyImageUrl") + .HasColumnType("nvarchar(max)"); + + b.Property("PokemonType") + .HasColumnType("nvarchar(max)"); + + b.Property("SleepType") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Speciality") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("VariationName") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Pokemons"); + }); + + modelBuilder.Entity("Portfolio.Domain.Features.Pokemon_Natures.PokemonNature", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("BerryRating") + .HasColumnType("int"); + + b.Property("IngredientRating") + .HasColumnType("int"); + + b.Property("Nature") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SkillRating") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("PokemonNatures"); + }); + + modelBuilder.Entity("Portfolio.Domain.Features.Pokemon_Subskills.PokemonSubskill", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("BerryRank") + .HasColumnType("int"); + + b.Property("IngredientRank") + .HasColumnType("int"); + + b.Property("SkillRank") + .HasColumnType("int"); + + b.Property("SubSkill") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("PokemonSubskills"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Portfolio.Infrastructure/Migrations/20250404173359_include_flavortext.cs b/Portfolio.Infrastructure/Migrations/20250404173359_include_flavortext.cs new file mode 100644 index 0000000..a1dc268 --- /dev/null +++ b/Portfolio.Infrastructure/Migrations/20250404173359_include_flavortext.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Portfolio.Infrastructure.Migrations +{ + /// + public partial class include_flavortext : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "FlavorText", + table: "Pokemons", + type: "nvarchar(max)", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "FlavorText", + table: "Pokemons"); + } + } +} diff --git a/Portfolio.Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs b/Portfolio.Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs index be99988..8877fe0 100644 --- a/Portfolio.Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/Portfolio.Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs @@ -29,6 +29,9 @@ namespace Portfolio.Infrastructure.Migrations SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + b.Property("FlavorText") + .HasColumnType("nvarchar(max)"); + b.Property("IsVariation") .HasColumnType("bit"); @@ -45,6 +48,9 @@ namespace Portfolio.Infrastructure.Migrations b.Property("PokemonShinyImageUrl") .HasColumnType("nvarchar(max)"); + b.Property("PokemonType") + .HasColumnType("nvarchar(max)"); + b.Property("SleepType") .IsRequired() .HasColumnType("nvarchar(max)"); diff --git a/Portfolio.WebUI.Server/Components/Component/PokemonCard.razor b/Portfolio.WebUI.Server/Components/Component/PokemonCard.razor index c5f73cc..17bc90f 100644 --- a/Portfolio.WebUI.Server/Components/Component/PokemonCard.razor +++ b/Portfolio.WebUI.Server/Components/Component/PokemonCard.razor @@ -2,7 +2,7 @@ @rendermode InteractiveServer
- +
@if (_pokemon.IsVariation) { @@ -15,6 +15,9 @@

Pokédex #@_pokemon.PokemonId

+
+ +
@@ -26,7 +29,16 @@
-

[ Pokemon Flavor Text Placeholder ]

+ @if (string.IsNullOrEmpty(_pokemon.FlavorText)) + { +

[ Pokemon Flavor Text Placeholder ]

+ + } + else + { +

@_pokemon.FlavorText

+ + }
diff --git a/Portfolio.WebUI.Server/Components/Component/PokemonCard.razor.cs b/Portfolio.WebUI.Server/Components/Component/PokemonCard.razor.cs index f20140b..7548b0e 100644 --- a/Portfolio.WebUI.Server/Components/Component/PokemonCard.razor.cs +++ b/Portfolio.WebUI.Server/Components/Component/PokemonCard.razor.cs @@ -26,5 +26,17 @@ namespace Portfolio.WebUI.Server.Components.Component 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"; + } + + } } diff --git a/Portfolio.WebUI.Server/Components/Component/PokemonCard.razor.css b/Portfolio.WebUI.Server/Components/Component/PokemonCard.razor.css index 3ff2b26..2114fc6 100644 --- a/Portfolio.WebUI.Server/Components/Component/PokemonCard.razor.css +++ b/Portfolio.WebUI.Server/Components/Component/PokemonCard.razor.css @@ -21,12 +21,22 @@ position: absolute; top: 0 !important; left: 0 !important; - margin-top: 3rem !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%; @@ -41,11 +51,29 @@ left: 50% !important; width: 90%; height: 20%; - padding: 0.5rem; + 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; diff --git a/Portfolio.WebUI.Server/Components/Component/PokemonTable.razor b/Portfolio.WebUI.Server/Components/Component/PokemonTable.razor index e27c1a3..d6b3b13 100644 --- a/Portfolio.WebUI.Server/Components/Component/PokemonTable.razor +++ b/Portfolio.WebUI.Server/Components/Component/PokemonTable.razor @@ -33,12 +33,13 @@ else - - # - Pokemon - Sleep Type - Speciality - + + # + Pokemon + Type + Sleep Type + Speciality + @@ -94,17 +95,25 @@ else @pokemon.PokemonName } - + + + +
+ +
+ + +

@pokemon.SleepType

- +

@pokemon.Speciality

- + @@ -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"); - } } \ No newline at end of file diff --git a/Portfolio.WebUI.Server/Components/Pages/PokemonEdit.razor.cs b/Portfolio.WebUI.Server/Components/Pages/PokemonEdit.razor.cs new file mode 100644 index 0000000..e2c71aa --- /dev/null +++ b/Portfolio.WebUI.Server/Components/Pages/PokemonEdit.razor.cs @@ -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"); + } + } +} diff --git a/Portfolio.WebUI.Server/Components/Pages/PokemonEdit.razor.css b/Portfolio.WebUI.Server/Components/Pages/PokemonEdit.razor.css new file mode 100644 index 0000000..c83bb0d --- /dev/null +++ b/Portfolio.WebUI.Server/Components/Pages/PokemonEdit.razor.css @@ -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; +}