Compare commits

..

No commits in common. "master" and "feature/keep-adding-pokemon" have entirely different histories.

63 changed files with 1017 additions and 2505 deletions

View File

@ -1,15 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Portfolio.Domain.Features.Pokemon
{
public class Ingredient
{
public string Name { get; set; }
public string Description { get; set; }
public string ImageURL { get; set; }
}
}

View File

@ -13,18 +13,12 @@ namespace Portfolio.Domain.Features.Pokemon
public required string PokemonName { get; set; } public required string PokemonName { get; set; }
public bool IsVariation { get; set; } = false; public bool IsVariation { get; set; } = false;
public string? VariationName { get; set; } public string? VariationName { get; set; }
public required string PokemonType { get; set; } public string? PokemonType { get; set; }
public required string SleepType { get; set; } public required string SleepType { get; set; }
public required string Speciality { get; set; } public required string Speciality { get; set; }
public string? Skill { get; set; }
public string? SkillDescription { get; set; }
public string? PokemonImageUrl { get; set; } public string? PokemonImageUrl { get; set; }
public string? PokemonShinyImageUrl { get; set; } public string? PokemonShinyImageUrl { get; set; }
public string[]? PokemonSleepStyleImageUrls { get; set; }
public string? FlavorText { get; set; } public string? FlavorText { get; set; }
public string? Ingredient1 { get; set; }
public string? Ingredient2 { get; set; }
public string? Ingredient3 { get; set; }
} }

View File

@ -1,18 +0,0 @@
using Portfolio.Domain.Features.Abstractions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Portfolio.Domain.Features.Pokemon
{
public class PokemonType : Entity
{
public string Type { get; set; }
public string TypeImageUrl { get; set; }
public string Berry { get; set; }
public string BerryDescription { get; set; }
public string BerryImageUrl { get; set; }
}
}

View File

@ -1,130 +0,0 @@
// <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("20251117160500_updatePokemonAddIngredients")]
partial class updatePokemonAddIngredients
{
/// <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.PrimitiveCollection<string>("Ingredients")
.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
}
}
}

View File

@ -1,28 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Portfolio.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class updatePokemonAddIngredients : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "Ingredients",
table: "Pokemons",
type: "nvarchar(max)",
nullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Ingredients",
table: "Pokemons");
}
}
}

View File

@ -1,136 +0,0 @@
// <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("20251117171147_updatePokemonChangeIngredient")]
partial class updatePokemonChangeIngredient
{
/// <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<string>("Ingredient1")
.HasColumnType("nvarchar(max)");
b.Property<string>("Ingredient2")
.HasColumnType("nvarchar(max)");
b.Property<string>("Ingredient3")
.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
}
}
}

View File

@ -1,48 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Portfolio.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class updatePokemonChangeIngredient : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.RenameColumn(
name: "Ingredients",
table: "Pokemons",
newName: "Ingredient3");
migrationBuilder.AddColumn<string>(
name: "Ingredient1",
table: "Pokemons",
type: "nvarchar(max)",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "Ingredient2",
table: "Pokemons",
type: "nvarchar(max)",
nullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Ingredient1",
table: "Pokemons");
migrationBuilder.DropColumn(
name: "Ingredient2",
table: "Pokemons");
migrationBuilder.RenameColumn(
name: "Ingredient3",
table: "Pokemons",
newName: "Ingredients");
}
}
}

View File

@ -1,149 +0,0 @@
// <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("20251205171834_updatePokemonAddBerry+Skill+SleepStyles")]
partial class updatePokemonAddBerrySkillSleepStyles
{
/// <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<string>("Ingredient1")
.HasColumnType("nvarchar(max)");
b.Property<string>("Ingredient2")
.HasColumnType("nvarchar(max)");
b.Property<string>("Ingredient3")
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsVariation")
.HasColumnType("bit");
b.Property<string>("PokemonBerry")
.HasColumnType("nvarchar(max)");
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.PrimitiveCollection<string>("PokemonSleepStyleImageUrls")
.HasColumnType("nvarchar(max)");
b.Property<string>("PokemonType")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Skill")
.HasColumnType("nvarchar(max)");
b.Property<string>("SkillDescription")
.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
}
}
}

View File

@ -1,76 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Portfolio.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class updatePokemonAddBerrySkillSleepStyles : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "PokemonType",
table: "Pokemons",
type: "nvarchar(max)",
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "nvarchar(max)",
oldNullable: true);
migrationBuilder.AddColumn<string>(
name: "PokemonBerry",
table: "Pokemons",
type: "nvarchar(max)",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "PokemonSleepStyleImageUrls",
table: "Pokemons",
type: "nvarchar(max)",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "Skill",
table: "Pokemons",
type: "nvarchar(max)",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "SkillDescription",
table: "Pokemons",
type: "nvarchar(max)",
nullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "PokemonBerry",
table: "Pokemons");
migrationBuilder.DropColumn(
name: "PokemonSleepStyleImageUrls",
table: "Pokemons");
migrationBuilder.DropColumn(
name: "Skill",
table: "Pokemons");
migrationBuilder.DropColumn(
name: "SkillDescription",
table: "Pokemons");
migrationBuilder.AlterColumn<string>(
name: "PokemonType",
table: "Pokemons",
type: "nvarchar(max)",
nullable: true,
oldClrType: typeof(string),
oldType: "nvarchar(max)");
}
}
}

View File

@ -1,146 +0,0 @@
// <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("20251205172848_updatePokemonRemovedBerry")]
partial class updatePokemonRemovedBerry
{
/// <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<string>("Ingredient1")
.HasColumnType("nvarchar(max)");
b.Property<string>("Ingredient2")
.HasColumnType("nvarchar(max)");
b.Property<string>("Ingredient3")
.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.PrimitiveCollection<string>("PokemonSleepStyleImageUrls")
.HasColumnType("nvarchar(max)");
b.Property<string>("PokemonType")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Skill")
.HasColumnType("nvarchar(max)");
b.Property<string>("SkillDescription")
.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
}
}
}

View File

@ -1,28 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Portfolio.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class updatePokemonRemovedBerry : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "PokemonBerry",
table: "Pokemons");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "PokemonBerry",
table: "Pokemons",
type: "nvarchar(max)",
nullable: true);
}
}
}

View File

@ -32,15 +32,6 @@ namespace Portfolio.Infrastructure.Migrations
b.Property<string>("FlavorText") b.Property<string>("FlavorText")
.HasColumnType("nvarchar(max)"); .HasColumnType("nvarchar(max)");
b.Property<string>("Ingredient1")
.HasColumnType("nvarchar(max)");
b.Property<string>("Ingredient2")
.HasColumnType("nvarchar(max)");
b.Property<string>("Ingredient3")
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsVariation") b.Property<bool>("IsVariation")
.HasColumnType("bit"); .HasColumnType("bit");
@ -57,17 +48,7 @@ namespace Portfolio.Infrastructure.Migrations
b.Property<string>("PokemonShinyImageUrl") b.Property<string>("PokemonShinyImageUrl")
.HasColumnType("nvarchar(max)"); .HasColumnType("nvarchar(max)");
b.PrimitiveCollection<string>("PokemonSleepStyleImageUrls")
.HasColumnType("nvarchar(max)");
b.Property<string>("PokemonType") b.Property<string>("PokemonType")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Skill")
.HasColumnType("nvarchar(max)");
b.Property<string>("SkillDescription")
.HasColumnType("nvarchar(max)"); .HasColumnType("nvarchar(max)");
b.Property<string>("SleepType") b.Property<string>("SleepType")

View File

@ -1,10 +0,0 @@
To Update Entites in the Database:
1. Make necessary changes to Enttities within .Domain
2. Open NuGet Packet Manager
3. Ensure default project is pointed to .Infrastructure
4. Enter `Add-Migration [Migration Tag Name, ex: updateEntityAddChange]`
5. Enter `Update-Database`
6. Check SSMS to ensure changes.

View File

@ -8,8 +8,10 @@
} }
else else
{ {
<div class="container">
<h3 class="text-xl font-bold mb-4 mt-4">Temperature Blanket Visualizer</h3> <h3 class="text-xl font-bold mb-4 mt-4">Temperature Blanket Visualizer</h3>
<div>
<div class="row"> <div class="row">
<div class="col-10"> <div class="col-10">
<div class="d-flex"> <div class="d-flex">
@ -24,7 +26,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="col d-flex align-items-center"> <div class="col">
<TemperatureRangeEditor TempRanges="@TemperatureRanges" OnRangesChanged="HandleRangesChanged" /> <TemperatureRangeEditor TempRanges="@TemperatureRanges" OnRangesChanged="HandleRangesChanged" />
</div> </div>
</div> </div>

View File

@ -1,12 +0,0 @@
using Microsoft.AspNetCore.Components;
namespace Portfolio.WebUI.Server.Components.Component
{
public partial class Loading
{
[Parameter]
public string LoadingString { get; set; }
}
}

View File

@ -0,0 +1,152 @@
@inject IPokemonService PokemonService
<div class="create-container m-auto bg-info border border-5 border-info-subtle rounded-4 p-3">
<EditForm class="col" Model="NewPokemon">
<DataAnnotationsValidator />
<div class="bg-primary-subtle rounded"><p class="fs-3 fw-light text-center card-title">New Pokemon</p></div>
<!-- Pokemon Number and Name -->
<div class="row mt-1">
<div class="col input-group mb-2">
<span class="input-group-text text-sm-center rounded-start">#</span>
<InputNumber min="1"
placeholder="Pokedex #"
id="PokemonId"
@bind-Value="NewPokemon.PokemonId"
class="form-control "
type="number" />
<InputText placeholder="Pokemon Name"
id="PokemonName"
@bind-Value="NewPokemon.PokemonName"
class="form-control w-50 rounded-end" />
</div>
</div>
<!-- Variation Check -->
<div class="d-flex flex-row justify-content-start input-group ">
<InputCheckbox id="IsVariation"
@bind-Value="NewPokemon.IsVariation"
@onclick="@Toggle"
class="form-check-input p-3 rounded" />
<span class="input-group-text ms-1 @GetRoundingClass()">Variation?</span>
<InputText placeholder="How So?"
id="VariationName"
@bind-Value="NewPokemon.VariationName"
class="form-control rounded-end"
hidden="@HideLabel" />
</div>
<!-- <br> -->
<div class="border-bottom border-3 border-info-subtle rounded m-1 my-3"></div>
<!-- Pokemon Type -->
<div class="row mb-2">
<div class="input-group m-auto">
<span for="PokemonType" class="input-group-text rounded-start">Pokemon Type</span>
<InputSelect id="PokemonType" @bind-Value="NewPokemon.PokemonType" class="form-select rounded-end">
<option disabled value="" selected>Select...</option>
@foreach (var pt in PokemonTypes)
{
<option value="@pt">@pt</option>
}
</InputSelect>
</div>
</div>
<!-- Pokemon Sleep Type, Specialty -->
<div class="row mb-3 mx-0">
<!-- Sleep Type -->
<div class="col ps-0 pe-1">
<div class="row input-group m-auto">
<span for="SleepType" class="input-group-text rounded-top">Sleep Type</span>
</div>
<div class="row input-group m-auto">
<InputSelect id="SleepType" @bind-Value="NewPokemon.SleepType" class="form-select rounded-bottom">
<option disabled value="" selected>Select...</option>
@foreach (var st in SleepTypes)
{
<option value="@st">@st</option>
}
</InputSelect>
</div>
</div>
<!-- Speciality -->
<div class="col ps-1 pe-0">
<div class="row input-group m-auto">
<span for="Speciality" class="input-group-text rounded-top">Specialty</span>
</div>
<div class="row input-group m-auto">
<InputSelect id="Speciality" @bind-Value="NewPokemon.Speciality" class="form-select rounded-bottom">
<option disabled value="" selected>Select...</option>
@foreach (var sp in Specialities)
{
<option value="@sp">@sp</option>
}
</InputSelect>
</div>
</div>
</div>
<!-- <br> -->
<div class="border-bottom border-3 border-info-subtle rounded m-1 my-3"></div>
<!-- Images -->
<div class="row mb-2">
<div class="input-group m-auto">
<span for="ImageUrl" class="input-group-text rounded-start">Base Image URL</span>
<InputText id="ImageUrl" @bind-Value="NewPokemon.PokemonImageUrl" class="form-control rounded-end" />
</div>
</div>
<div class="row mb-2">
<div class="input-group m-auto">
<span for="ShinyImageUrl" class="input-group-text rounded-start">Shiny Image URL</span>
<InputText id="ShinyImageUrl" @bind-Value="NewPokemon.PokemonShinyImageUrl" class="form-control rounded-end" />
</div>
</div>
<!-- Flavor -->
<div class="row mb-2">
<div class="input-group m-auto">
<span for="FlavorText" class="input-group-text rounded-start">Flavor Text</span>
<InputText id="FlavorText" @bind-Value="NewPokemon.FlavorText" class="form-control rounded-end" />
</div>
</div>
<!-- <br> -->
<div class="border-bottom border-3 border-info-subtle rounded m-1 my-3"></div>
@if (showErrors && !IsComplete)
{
<div class="alert alert-warning mt-2">
Please complete: @string.Join(", ", MissingFields())
</div>
}
<div class="d-flex mt-3 justify-content-center gap-3">
<button type="button"
class="btn btn-primary rounded p-1 px-0"
@onclick="@SendPokemon"
disabled="@( !IsComplete )">
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-file-arrow-up" viewBox="0 0 16 16">
<path d="M8 11a.5.5 0 0 0 .5-.5V6.707l1.146 1.147a.5.5 0 0 0 .708-.708l-2-2a.5.5 0 0 0-.708 0l-2 2a.5.5 0 1 0 .708.708L7.5 6.707V10.5a.5.5 0 0 0 .5.5" />
<path d="M4 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm0 1h8a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1" />
</svg>
</button>
@if(mostRecentForm)
{
<button type="button"
class="btn btn-danger rounded p-1 px-0"
@onclick="@HandleRemove">
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-file-minus" viewBox="0 0 16 16">
<path d="M5.5 8a.5.5 0 0 1 .5-.5h4a.5.5 0 0 1 0 1H6a.5.5 0 0 1-.5-.5" />
<path d="M4 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm0 1h8a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1" />
</svg>
</button>
}
</div>
</EditForm>
</div>

View File

@ -0,0 +1,101 @@
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Portfolio.Application.Services.PokemonService;
using Portfolio.Domain.Features.Pokemon;
namespace Portfolio.WebUI.Server.Components.Component.Pokemon_Components
{
public partial class PokemonAddForm
{
[Parameter]
public EventCallback<Pokemon> OnPokemonReady { get; set; }
[Parameter]
public EventCallback RemoveForm { get; set; }
[Parameter]
public bool mostRecentForm { get; set; }
protected static readonly string[] PokemonTypes = new[]
{
"Grass","Fire","Water","Normal","Flying","Bug","Poison","Electric","Ground","Rock","Ice",
"Steel","Fighting","Psychic","Dark","Fairy","Ghost","Dragon"
};
protected static readonly string[] SleepTypes = new[] { "Dozing", "Snoozing", "Slumbering" };
protected static readonly string[] Specialities = new[] { "Berries", "Ingredients", "Skills", "All" };
private bool HideLabel { get; set; } = true;
private bool showErrors { get; set; } = false;
private Pokemon NewPokemon = new Pokemon
{
PokemonId = 0, // Or any default ID logic
PokemonName = string.Empty, // Required fields cannot be null
SleepType = string.Empty,
Speciality = string.Empty,
IsVariation = false
};
private void Toggle() => HideLabel = !HideLabel;
private string GetRoundingClass()
{
if (!HideLabel) {
return "rounded-start";
}
return "rounded-start rounded-end";
}
// Minimal "complete" check (no data annotations needed)
private bool IsComplete =>
NewPokemon.PokemonId > 0 &&
!string.IsNullOrWhiteSpace(NewPokemon.PokemonName) &&
!string.IsNullOrWhiteSpace(NewPokemon.PokemonType) &&
!string.IsNullOrWhiteSpace(NewPokemon.SleepType) &&
!string.IsNullOrWhiteSpace(NewPokemon.Speciality) &&
(!NewPokemon.IsVariation || !string.IsNullOrWhiteSpace(NewPokemon.VariationName));
private IEnumerable<string> MissingFields()
{
if (NewPokemon.PokemonId <= 0) yield return "Pokédex #";
if (string.IsNullOrWhiteSpace(NewPokemon.PokemonName)) yield return "Name";
if (string.IsNullOrWhiteSpace(NewPokemon.PokemonType)) yield return "Type";
if (string.IsNullOrWhiteSpace(NewPokemon.SleepType)) yield return "Sleep Type";
if (string.IsNullOrWhiteSpace(NewPokemon.Speciality)) yield return "Specialty";
if (NewPokemon.IsVariation && string.IsNullOrWhiteSpace(NewPokemon.VariationName)) yield return "Variation Name";
}
private async Task HandleRemove()
{
await RemoveForm.InvokeAsync();
}
private async Task SendPokemon()
{
if (!IsComplete)
{
showErrors = true;
StateHasChanged();
return;
}
// Optionally send a copy to avoid later mutation by the child
var copy = new Pokemon
{
PokemonId = NewPokemon.PokemonId,
PokemonName = NewPokemon.PokemonName,
PokemonType = NewPokemon.PokemonType,
SleepType = NewPokemon.SleepType,
Speciality = NewPokemon.Speciality,
IsVariation = NewPokemon.IsVariation,
VariationName = NewPokemon.VariationName,
PokemonImageUrl = NewPokemon.PokemonImageUrl,
PokemonShinyImageUrl = NewPokemon.PokemonShinyImageUrl,
FlavorText = NewPokemon.FlavorText
};
await OnPokemonReady.InvokeAsync(copy);
}
}
}

View File

@ -8,8 +8,10 @@ $display-font-sizes: (
6: 2.5rem 6: 2.5rem
); );
.pokemon-form-container { .create-container {
position: relative; position: relative;
width: 100%;
max-width: 390px; /* Prevent it from getting too huge */
aspect-ratio: 3 / 4; /* Maintains card shape dynamically */ aspect-ratio: 3 / 4; /* Maintains card shape dynamically */
background-color: var(--bg-color); background-color: var(--bg-color);
border-width: .5rem; border-width: .5rem;
@ -22,4 +24,5 @@ $display-font-sizes: (
.checkbox-styling { .checkbox-styling {
width: 100px; width: 100px;
height: 100px; height: 100px;
}
}

View File

@ -1,11 +1,4 @@
$width: 200px; .badge {
$height: 80px;
*, *::before, *::after {
box-sizing: border-box;
}
.badge {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -16,14 +9,9 @@ $height: 80px;
color: white; color: white;
font-size: clamp(0.7rem, 1vw, 0.9rem); font-size: clamp(0.7rem, 1vw, 0.9rem);
text-align: center; text-align: center;
font-weight: 400;
text-shadow: 0 2px 2px rgba(0,0,0,0.25);
box-shadow: 0 1px 2px 0 rgba(0,0,0,0.35);
transition: all 0.2s ease;
white-space: nowrap; white-space: nowrap;
} }
.statText { .statText {
margin: 0; margin: 0;
padding: 0; padding: 0;

View File

@ -22,8 +22,11 @@
</div> </div>
<!-- Pokemon Image --> <!-- Pokemon Image -->
<div class="card-image-slot z-1"> <div class="flip-container z-1" @onclick="() => ToggleImage()">
<PokemonImage baseUrl="@_pokemon.PokemonImageUrl" shinyUrl="@_pokemon.PokemonShinyImageUrl" /> <div class="flipper @(isShiny ? "flipped" : "")">
<img class="pokemon-image front" src="@_pokemon.PokemonImageUrl" />
<img class="pokemon-image back" src="@_pokemon.PokemonShinyImageUrl" />
</div>
</div> </div>
<!-- Pokemon Flavortext --> <!-- Pokemon Flavortext -->
@ -50,7 +53,7 @@
</div> </div>
<div class="mt-5"> <div class="mt-3">
<PokemonEditButton PokemonId="@_pokemon.Id" /> <PokemonEditButton PokemonId="@_pokemon.Id" />
</div> </div>
</div> </div>

View File

@ -1,11 +1,4 @@
.card-wrapper { .pokemon-card {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
}
.pokemon-card {
position: relative; position: relative;
width: 100%; width: 100%;
max-width: 350px; /* Prevent it from getting too huge */ max-width: 350px; /* Prevent it from getting too huge */
@ -27,6 +20,14 @@
transform: translateY(-13px); transform: translateY(-13px);
} }
.card-wrapper {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
}
.pokemon-name { .pokemon-name {
position: absolute; position: absolute;
top: 5%; top: 5%;
@ -50,8 +51,14 @@
right: 2%; right: 2%;
width: clamp(1.5rem, 2.5vw, 2.5rem); width: clamp(1.5rem, 2.5vw, 2.5rem);
height: clamp(1.5rem, 2.5vw, 2.5rem); height: clamp(1.5rem, 2.5vw, 2.5rem);
box-shadow: 0 1px 2px 1px rgba(0,0,0,0.35); }
border-radius: 20px;
.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 { .pokemon-flavor-text {
@ -88,18 +95,45 @@
hyphens: auto; hyphens: auto;
} }
/* Position the image area within the card */ .flip-container {
.card-image-slot { position: absolute !important;
position: absolute; top: 40% !important;
top: 50%; left: 50% !important;
left: 50%; transform: translate(-50%, -50%) !important;
transform: translate(-50%, -20%); perspective: 1000px;
width: 100%; display: inline-block;
width: 80%;
aspect-ratio: 1 / 1; aspect-ratio: 1 / 1;
max-width: 300px; max-width: 280px;
margin: 0 auto;
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);
}
/* Type Card Styling */ /* Type Card Styling */

View File

@ -5,7 +5,7 @@ using System.Text.Json;
namespace Portfolio.WebUI.Server.Components.Component.Pokemon_Components namespace Portfolio.WebUI.Server.Components.Component.Pokemon_Components
{ {
partial class PokemonDownloadButton partial class PokemonDownload
{ {
[Parameter] [Parameter]
public List<Pokemon> _Pokemon { get; set; } public List<Pokemon> _Pokemon { get; set; }

View File

@ -9,7 +9,7 @@ namespace Portfolio.WebUI.Server.Components.Component.Pokemon_Components
private void EditPokemon(int PokemonId) private void EditPokemon(int PokemonId)
{ {
Navigation.NavigateTo($"/pokemon-sleep/edit-pokemon/{PokemonId}"); Navigation.NavigateTo($"/pokemonsleep/edit/{PokemonId}");
} }
} }
} }

View File

@ -1,425 +0,0 @@
@inject IPokemonService PokemonService
@inject IHttpClientFactory ClientFactory
@if(Ingredients == null)
{
<Loading />
}
else
{
@if(formUse == "ADD")
{
<div class="pokemon-form-container m-auto bg-info border border-5 border-info-subtle rounded-4 p-3">
<EditForm class="col" Model="NewPokemon">
<DataAnnotationsValidator />
<div class="bg-primary-subtle rounded"><p class="fs-3 fw-light text-center card-title">New Pokemon</p></div>
<!-- Pokemon Number and Name -->
<div class="row mt-1">
<div class="col input-group mb-2">
<span class="input-group-text text-sm-center rounded-start">#</span>
<InputNumber min="1"
placeholder="Pokedex #"
id="PokemonId"
@bind-Value="NewPokemon.PokemonId"
@onchange="@SendPokemon"
class="form-control "
type="number" />
<InputText placeholder="Pokemon Name"
id="PokemonName"
@bind-Value="NewPokemon.PokemonName"
@onchange="@SendPokemon"
class="form-control w-50 rounded-end" />
</div>
</div>
<!-- Variation Check -->
<div class="d-flex flex-row justify-content-start input-group ">
<InputCheckbox id="IsVariation"
@bind-Value="NewPokemon.IsVariation"
@onclick="@Toggle"
@onchange="@SendPokemon"
class="form-check-input p-3 rounded" />
<span class="input-group-text ms-1 @GetRoundingClass()">Variation?</span>
<InputText placeholder="How So?"
id="VariationName"
@bind-Value="NewPokemon.VariationName"
@onchange="@SendPokemon"
class="form-control rounded-end"
hidden="@HideLabel" />
</div>
<!-- <br> -->
<div class="border-bottom border-3 border-info-subtle rounded m-1 my-3"></div>
<!-- Pokemon Type -->
<div class="row mb-2">
<div class="input-group m-auto">
<span for="PokemonType" class="input-group-text rounded-start">Pokemon Type</span>
<InputSelect id="PokemonType" @bind-Value="NewPokemon.PokemonType" @onchange="@SendPokemon" class="form-select rounded-end">
<option disabled value="" selected>Select...</option>
@foreach (var pt in PkmnTypes)
{
<option value="@pt.Type">@pt.Type</option>
}
</InputSelect>
</div>
</div>
<!-- Pokemon Sleep Type, Specialty -->
<div class="row mb-3 mx-0">
<!-- Sleep Type -->
<div class="col ps-0 pe-1">
<div class="row input-group m-auto">
<span for="SleepType" class="input-group-text rounded-top">Sleep Type</span>
</div>
<div class="row input-group m-auto">
<InputSelect id="SleepType" @bind-Value="NewPokemon.SleepType" @onchange="@SendPokemon" class="form-select rounded-bottom">
<option disabled value="" selected>Select...</option>
@foreach (var st in SleepTypes)
{
<option value="@st">@st</option>
}
</InputSelect>
</div>
</div>
<!-- Speciality -->
<div class="col ps-1 pe-0">
<div class="row input-group m-auto">
<span for="Speciality" class="input-group-text rounded-top">Specialty</span>
</div>
<div class="row input-group m-auto">
<InputSelect id="Speciality" @bind-Value="NewPokemon.Speciality" @onchange="@SendPokemon" class="form-select rounded-bottom">
<option disabled value="" selected>Select...</option>
@foreach (var sp in Specialities)
{
<option value="@sp">@sp</option>
}
</InputSelect>
</div>
</div>
</div>
<!-- Pokemon Ingredients -->
<div class="row mb-3 mx-0">
<!-- Ingredient 1 -->
<div class="col ps-0 pe-1">
<div class="row input-group m-auto">
<span for="Ingredient1" class="input-group-text rounded-top">Ingredient 1</span>
</div>
<div class="row input-group m-auto">
<InputSelect id="Ingredient1" @bind-Value="NewPokemon.Ingredient1" @onchange="@SendPokemon" class="form-select rounded-bottom">
<option disabled value="" selected>Select...</option>
@foreach (var ingredient in Ingredients)
{
<option value="@ingredient.Name">@ingredient.Name</option>
}
</InputSelect>
</div>
</div>
<!-- Ingredient 2 -->
<div class="col ps-0 pe-1">
<div class="row input-group m-auto">
<span for="Ingredient2" class="input-group-text rounded-top">Ingredient 2</span>
</div>
<div class="row input-group m-auto">
<InputSelect id="Ingredient2" @bind-Value="NewPokemon.Ingredient2" @onchange="@SendPokemon" class="form-select rounded-bottom">
<option disabled value="" selected>Select...</option>
@foreach (var ingredient in Ingredients)
{
<option value="@ingredient.Name">@ingredient.Name</option>
}
</InputSelect>
</div>
</div>
<!-- Ingredient 3 -->
<div class="col ps-0 pe-1">
<div class="row input-group m-auto">
<span for="Ingredient3" class="input-group-text rounded-top">Ingredient 3</span>
</div>
<div class="row input-group m-auto">
<InputSelect id="Ingredient3" @bind-Value="NewPokemon.Ingredient3" @onchange="@SendPokemon" class="form-select rounded-bottom">
<option disabled value="" selected>Select...</option>
@foreach (var ingredient in Ingredients)
{
<option value="@ingredient.Name">@ingredient.Name</option>
}
</InputSelect>
</div>
</div>
</div>
<!-- <br> -->
<div class="border-bottom border-3 border-info-subtle rounded m-1 my-3"></div>
<!-- Images -->
<div class="row mb-2">
<div class="input-group m-auto">
<span for="ImageUrl" class="input-group-text rounded-start">Base Image URL</span>
<InputText id="ImageUrl" @bind-Value="NewPokemon.PokemonImageUrl" @onchange="@SendPokemon" class="form-control rounded-end" />
</div>
</div>
<div class="row mb-2">
<div class="input-group m-auto">
<span for="ShinyImageUrl" class="input-group-text rounded-start">Shiny Image URL</span>
<InputText id="ShinyImageUrl" @bind-Value="NewPokemon.PokemonShinyImageUrl" @onchange="@SendPokemon" class="form-control rounded-end" />
</div>
</div>
<!-- Flavor -->
<div class="row mb-2">
<div class="input-group m-auto">
<span for="FlavorText" class="input-group-text rounded-start">Flavor Text</span>
<InputText id="FlavorText" @bind-Value="NewPokemon.FlavorText" @onchange="@SendPokemon" class="form-control rounded-end" />
</div>
</div>
<!-- <br> -->
<div class="border-bottom border-3 border-info-subtle rounded m-1 my-3"></div>
@if (showErrors && !IsComplete)
{
<div class="alert alert-warning mt-2">
Please complete: @string.Join(", ", MissingFields())
</div>
}
<div class="d-flex mt-3 justify-content-center gap-3">
<button type="button"
class="btn btn-success rounded rounded-5 p-1"
@onclick="@SendPokemon">
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-plus-circle" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16" />
<path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4" />
</svg>
</button>
@if (mostRecentForm)
{
<button type="button"
class="btn btn-danger rounded rounded-5 p-1"
@onclick="@HandleRemove">
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-x-circle" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16" />
<path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708" />
</svg>
</button>
}
else
{
<button type="button"
class="btn btn-danger rounded rounded-5 p-1"
disabled>
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-x-circle" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16" />
<path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708" />
</svg>
</button>
}
</div>
</EditForm>
</div>
}
else if (formUse == "EDIT")
{
<div class="pokemon-form-container m-auto bg-info border border-5 border-info-subtle rounded-4 p-3">
<EditForm class="col" Model="PokemonToEdit">
<DataAnnotationsValidator />
<div class="bg-primary-subtle rounded"><p class="fs-3 fw-light text-center card-title">Edit Pokemon</p></div>
<!-- Pokemon Number and Name -->
<div class="row mt-1">
<div class="col input-group mb-2">
<span class="input-group-text text-sm-center rounded-start">#</span>
<InputNumber min="1"
placeholder="Pokedex #"
id="PokemonId"
@bind-Value="PokemonToEdit.PokemonId"
@onchange="@SendPokemon"
class="form-control "
type="number" />
<InputText placeholder="Pokemon Name"
id="PokemonName"
@bind-Value="PokemonToEdit.PokemonName"
@onchange="@SendPokemon"
class="form-control w-50 rounded-end" />
</div>
</div>
<!-- Variation Check -->
<div class="d-flex flex-row justify-content-start input-group ">
<InputCheckbox id="IsVariation"
@bind-Value="PokemonToEdit.IsVariation"
@onclick="@Toggle"
@onchange="@SendPokemon"
class="form-check-input p-3 rounded" />
<span class="input-group-text ms-1 @GetRoundingClass()">Variation?</span>
<InputText placeholder="How So?"
id="VariationName"
@bind-Value="PokemonToEdit.VariationName"
@onchange="@SendPokemon"
class="form-control rounded-end"
hidden="@HideLabel" />
</div>
<!-- <br> -->
<div class="border-bottom border-3 border-info-subtle rounded m-1 my-3"></div>
<!-- Pokemon Type -->
<div class="row mb-2">
<div class="input-group m-auto">
<span for="PokemonType" class="input-group-text rounded-start">Pokemon Type</span>
<InputSelect id="PokemonType" @bind-Value="PokemonToEdit.PokemonType" class="form-select rounded-end" @onchange="@SendPokemon">
<option disabled value="" selected>Select...</option>
@foreach (var pt in PokemonTypes)
{
<option value="@pt">@pt</option>
}
</InputSelect>
</div>
</div>
<!-- Pokemon Sleep Type, Specialty -->
<div class="row mb-3 mx-0">
<!-- Sleep Type -->
<div class="col ps-0 pe-1">
<div class="row input-group m-auto">
<span for="SleepType" class="input-group-text rounded-top">Sleep Type</span>
</div>
<div class="row input-group m-auto">
<InputSelect id="SleepType" @bind-Value="PokemonToEdit.SleepType" class="form-select rounded-bottom" @onchange="@SendPokemon">
<option disabled value="" selected>Select...</option>
@foreach (var st in SleepTypes)
{
<option value="@st">@st</option>
}
</InputSelect>
</div>
</div>
<!-- Speciality -->
<div class="col ps-1 pe-0">
<div class="row input-group m-auto">
<span for="Speciality" class="input-group-text rounded-top">Specialty</span>
</div>
<div class="row input-group m-auto">
<InputSelect id="Speciality" @bind-Value="PokemonToEdit.Speciality" class="form-select rounded-bottom" @onchange="@SendPokemon">
<option disabled value="" selected>Select...</option>
@foreach (var sp in Specialities)
{
<option value="@sp">@sp</option>
}
</InputSelect>
</div>
</div>
</div>
<!-- Pokemon Ingredients -->
<div class="row mb-3 mx-0">
<!-- Ingredient 1 -->
<div class="col ps-0 pe-1">
<div class="row input-group m-auto">
<span for="Ingredient1" class="input-group-text rounded-top">Ingredient 1</span>
</div>
<div class="row input-group m-auto">
<InputSelect id="Ingredient1" @bind-Value="PokemonToEdit.Ingredient1" @onchange="@SendPokemon" class="form-select rounded-bottom">
<option disabled value="" selected>Select...</option>
@foreach (var ingredient in Ingredients)
{
<option value="@ingredient.Name">@ingredient.Name</option>
}
</InputSelect>
</div>
</div>
<!-- Ingredient 2 -->
<div class="col ps-0 pe-1">
<div class="row input-group m-auto">
<span for="Ingredient2" class="input-group-text rounded-top">Ingredient 2</span>
</div>
<div class="row input-group m-auto">
<InputSelect id="Ingredient2" @bind-Value="PokemonToEdit.Ingredient2" @onchange="@SendPokemon" class="form-select rounded-bottom">
<option disabled value="" selected>Select...</option>
@foreach (var ingredient in Ingredients)
{
<option value="@ingredient.Name">@ingredient.Name</option>
}
</InputSelect>
</div>
</div>
<!-- Ingredient 3 -->
<div class="col ps-0 pe-1">
<div class="row input-group m-auto">
<span for="Ingredient3" class="input-group-text rounded-top">Ingredient 3</span>
</div>
<div class="row input-group m-auto">
<InputSelect id="Ingredient3" @bind-Value="PokemonToEdit.Ingredient3" @onchange="@SendPokemon" class="form-select rounded-bottom">
<option disabled value="" selected>Select...</option>
@foreach (var ingredient in Ingredients)
{
<option value="@ingredient.Name">@ingredient.Name</option>
}
</InputSelect>
</div>
</div>
</div>
<!-- <br> -->
<div class="border-bottom border-3 border-info-subtle rounded m-1 my-3"></div>
<!-- Images -->
<div class="row mb-2">
<div class="input-group m-auto">
<span for="ImageUrl" class="input-group-text rounded-start">Base Image URL</span>
<InputText id="ImageUrl" @bind-Value="PokemonToEdit.PokemonImageUrl" class="form-control rounded-end" @onchange="@SendPokemon" />
</div>
</div>
<div class="row mb-2">
<div class="input-group m-auto">
<span for="ShinyImageUrl" class="input-group-text rounded-start">Shiny Image URL</span>
<InputText id="ShinyImageUrl" @bind-Value="PokemonToEdit.PokemonShinyImageUrl" class="form-control rounded-end" @onchange="@SendPokemon" />
</div>
</div>
<!-- Flavor -->
<div class="row mb-2">
<div class="input-group m-auto">
<span for="FlavorText" class="input-group-text rounded-start">Flavor Text</span>
<InputText id="FlavorText" @bind-Value="PokemonToEdit.FlavorText" class="form-control rounded-end" @onchange="@SendPokemon" />
</div>
</div>
<!-- <br> -->
<div class="border-bottom border-3 border-info-subtle rounded m-1 my-3"></div>
@if (showErrors && !IsComplete)
{
<div class="alert alert-warning mt-2">
Please complete: @string.Join(", ", MissingFields())
</div>
}
<div class="d-flex mt-3 justify-content-center gap-3">
@if (mostRecentForm)
{
<button type="button"
class="btn btn-danger rounded rounded-5 p-1"
@onclick="@HandleRemove">
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-x-circle" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16" />
<path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708" />
</svg>
</button>
}
</div>
</EditForm>
</div>
}
}

View File

@ -1,190 +0,0 @@
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Portfolio.Application.Services.PokemonService;
using Portfolio.Domain.Features.Pokemon;
using Portfolio.Domain.Features.Portfolio;
namespace Portfolio.WebUI.Server.Components.Component.Pokemon_Components
{
public partial class PokemonForm
{
// To Add or Edit Pokemon
[Parameter]
public string formUse { get; set; }
private bool formChanged { get; set; } = false;
[Parameter]
public EventCallback<Pokemon> OnPokemonReady { get; set; }
[Parameter]
public EventCallback RemoveForm { get; set; }
// When Adding
[Parameter]
public bool mostRecentForm { get; set; }
private Pokemon NewPokemon = new Pokemon
{
PokemonId = 0, // Or any default ID logic
PokemonName = string.Empty, // Required fields cannot be null
PokemonType = string.Empty, // Required fields cannot be null
SleepType = string.Empty,
Speciality = string.Empty,
IsVariation = false
};
// When Editing
[Parameter]
public Pokemon? PokemonToEdit { get; set; }
private int PokemonToEditId { get; set; }
// General Form
protected static readonly string[] PokemonTypes = new[]
{
"Grass","Fire","Water","Normal","Flying","Bug","Poison","Electric","Ground","Rock","Ice",
"Steel","Fighting","Psychic","Dark","Fairy","Ghost","Dragon"
};
protected static readonly string[] SleepTypes = new[] { "Dozing", "Snoozing", "Slumbering" };
protected static readonly string[] Specialities = new[] { "Berries", "Ingredients", "Skills", "All" };
private List<Ingredient>? Ingredients;
private List<PokemonType>? PkmnTypes;
private bool HideLabel { get; set; }
private bool showErrors { get; set; } = false;
protected override async Task OnInitializedAsync()
{
var http = ClientFactory.CreateClient("LocalClient");
Ingredients = await http.GetFromJsonAsync<List<Ingredient>>("data/ingredients.json");
PkmnTypes = await http.GetFromJsonAsync<List<PokemonType>>("data/pkmn_type-and-berries.json");
var count = 0;
foreach (var t in PkmnTypes)
{
count++;
//if (count <= 9) { Console.WriteLine("0"+ count + ": | " + t.Type + "\t| " + t.Berry); }
//else { Console.WriteLine(count + ": | " + t.Type + "\t| " + t.Berry); }
}
if (formUse == "EDIT")
{
if (PokemonToEdit.IsVariation == true)
{
HideLabel = false;
}
PokemonToEditId = PokemonToEdit.Id;
}
else
{
HideLabel = true;
}
}
private void Toggle()
{
HideLabel = !HideLabel;
}
private void ToggleFormChange()
{
formChanged = true;
}
// CSS-function to get proper styling for form elements
private string GetRoundingClass()
{
if (!HideLabel)
{
return "rounded-start";
}
return "rounded-start rounded-end";
}
// Minimal "complete" check (no data annotations needed)
private bool IsComplete =>
NewPokemon.PokemonId > 0 &&
!string.IsNullOrWhiteSpace(NewPokemon.PokemonName) &&
!string.IsNullOrWhiteSpace(NewPokemon.PokemonType) &&
!string.IsNullOrWhiteSpace(NewPokemon.SleepType) &&
!string.IsNullOrWhiteSpace(NewPokemon.Speciality) &&
(!NewPokemon.IsVariation || !string.IsNullOrWhiteSpace(NewPokemon.VariationName));
private IEnumerable<string> MissingFields()
{
if (NewPokemon.PokemonId <= 0) yield return "Pokédex #";
if (string.IsNullOrWhiteSpace(NewPokemon.PokemonName)) yield return "Name";
if (string.IsNullOrWhiteSpace(NewPokemon.PokemonType)) yield return "Type";
if (string.IsNullOrWhiteSpace(NewPokemon.SleepType)) yield return "Sleep Type";
if (string.IsNullOrWhiteSpace(NewPokemon.Speciality)) yield return "Specialty";
if (NewPokemon.IsVariation && string.IsNullOrWhiteSpace(NewPokemon.VariationName)) yield return "Variation Name";
}
private async Task HandleRemove()
{
await RemoveForm.InvokeAsync();
}
private async Task SendPokemon()
{
Console.WriteLine("onchange");
if(formUse == "ADD")
{
if (!IsComplete)
{
showErrors = true;
StateHasChanged();
return;
}
// Optionally send a copy to avoid later mutation by the child
var copy = new Pokemon
{
PokemonId = NewPokemon.PokemonId,
PokemonName = NewPokemon.PokemonName,
PokemonType = NewPokemon.PokemonType,
SleepType = NewPokemon.SleepType,
Speciality = NewPokemon.Speciality,
IsVariation = NewPokemon.IsVariation,
VariationName = NewPokemon.VariationName,
PokemonImageUrl = NewPokemon.PokemonImageUrl,
PokemonShinyImageUrl = NewPokemon.PokemonShinyImageUrl,
FlavorText = NewPokemon.FlavorText,
Ingredient1 = NewPokemon.Ingredient1,
Ingredient2 = NewPokemon.Ingredient2,
Ingredient3 = NewPokemon.Ingredient3
};
await OnPokemonReady.InvokeAsync(copy);
formChanged = false;
}
else
{
// Optionally send a copy to avoid later mutation by the child
var edit = new Pokemon
{
Id = PokemonToEditId,
PokemonId = PokemonToEdit.PokemonId,
PokemonName = PokemonToEdit.PokemonName,
PokemonType = PokemonToEdit.PokemonType,
SleepType = PokemonToEdit.SleepType,
Speciality = PokemonToEdit.Speciality,
IsVariation = PokemonToEdit.IsVariation,
VariationName = PokemonToEdit.VariationName,
PokemonImageUrl = PokemonToEdit.PokemonImageUrl,
PokemonShinyImageUrl = PokemonToEdit.PokemonShinyImageUrl,
FlavorText = PokemonToEdit.FlavorText,
Ingredient1 = PokemonToEdit.Ingredient1,
Ingredient2 = PokemonToEdit.Ingredient2,
Ingredient3 = PokemonToEdit.Ingredient3
};
await OnPokemonReady.InvokeAsync(edit);
Console.WriteLine(edit);
}
}
}
}

View File

@ -1,9 +1,18 @@
<!-- Pokemon Navigation Buttons --> 
<div class="mx-auto w-75 top-row row" > <!-- Heading + Buttons -->
<div class="row btn-group d-flex justify-content-end" > <div class="top-row row rounded-bottom-5 w-100 bg-secondary border-bottom border-start border-end border-2 border-primary py-3">
<div class="col-4"></div>
<div class="col-4 text-center">
<h1 class="text-primary">Pokémon Sleep</h1>
</div>
<div class="col-4">
<div class="btn-group d-flex justify-content-end my-1">
<!-- Home --> <!-- Home -->
<button class="btn btn-primary mx-1 align-content-center" style="border-radius: 50px 15px; max-width: 60px;"> <button class="btn btn-primary mx-1 align-content-center" style="border-radius: 50px 15px; max-width: 60px;">
<NavLink href="/pokemon-sleep"> <NavLink href="/pokemonsleep">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-house-fill mb-1 text-white" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-house-fill mb-1 text-white" viewBox="0 0 16 16">
<path d="M8.707 1.5a1 1 0 0 0-1.414 0L.646 8.146a.5.5 0 0 0 .708.708L8 2.207l6.646 6.647a.5.5 0 0 0 .708-.708L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293z" /> <path d="M8.707 1.5a1 1 0 0 0-1.414 0L.646 8.146a.5.5 0 0 0 .708.708L8 2.207l6.646 6.647a.5.5 0 0 0 .708-.708L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293z" />
<path d="m8 3.293 6 6V13.5a1.5 1.5 0 0 1-1.5 1.5h-9A1.5 1.5 0 0 1 2 13.5V9.293z" /> <path d="m8 3.293 6 6V13.5a1.5 1.5 0 0 1-1.5 1.5h-9A1.5 1.5 0 0 1 2 13.5V9.293z" />
@ -13,7 +22,7 @@
<!-- Pokemon Table--> <!-- Pokemon Table-->
<button class="btn btn-info mx-1" style="border-radius: 50px 15px; max-width: 60px;"> <button class="btn btn-info mx-1" style="border-radius: 50px 15px; max-width: 60px;">
<NavLink href="/pokemon-sleep/pokemon"> <NavLink href="/pokemon">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-table mb-1 text-white" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-table mb-1 text-white" viewBox="0 0 16 16">
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm15 2h-4v3h4zm0 4h-4v3h4zm0 4h-4v3h3a1 1 0 0 0 1-1zm-5 3v-3H6v3zm-5 0v-3H1v2a1 1 0 0 0 1 1zm-4-4h4V8H1zm0-4h4V4H1zm5-3v3h4V4zm4 4H6v3h4z" /> <path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm15 2h-4v3h4zm0 4h-4v3h4zm0 4h-4v3h3a1 1 0 0 0 1-1zm-5 3v-3H6v3zm-5 0v-3H1v2a1 1 0 0 0 1 1zm-4-4h4V8H1zm0-4h4V4H1zm5-3v3h4V4zm4 4H6v3h4z" />
</svg> </svg>
@ -22,7 +31,7 @@
<!-- Rate Pokemon --> <!-- Rate Pokemon -->
<button class="btn btn-success mx-1" style="border-radius: 50px 15px; max-width: 60px;"> <button class="btn btn-success mx-1" style="border-radius: 50px 15px; max-width: 60px;">
<NavLink href="/pokemon-sleep/rate-pokemon"> <NavLink href="/rate-pokemon">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-award-fill mb-1 text-white" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-award-fill mb-1 text-white" viewBox="0 0 16 16">
<path d="m8 0 1.669.864 1.858.282.842 1.68 1.337 1.32L13.4 6l.306 1.854-1.337 1.32-.842 1.68-1.858.282L8 12l-1.669-.864-1.858-.282-.842-1.68-1.337-1.32L2.6 6l-.306-1.854 1.337-1.32.842-1.68L6.331.864z" /> <path d="m8 0 1.669.864 1.858.282.842 1.68 1.337 1.32L13.4 6l.306 1.854-1.337 1.32-.842 1.68-1.858.282L8 12l-1.669-.864-1.858-.282-.842-1.68-1.337-1.32L2.6 6l-.306-1.854 1.337-1.32.842-1.68L6.331.864z" />
<path d="M4 11.794V16l4-1 4 1v-4.206l-2.018.306L8 13.126 6.018 12.1z" /> <path d="M4 11.794V16l4-1 4 1v-4.206l-2.018.306L8 13.126 6.018 12.1z" />
@ -32,7 +41,7 @@
<!-- Add Pokemon (Wrap in Auth) --> <!-- Add Pokemon (Wrap in Auth) -->
<button class="btn btn-warning mx-1 " style="border-radius: 50px 15px; max-width: 60px;"> <button class="btn btn-warning mx-1 " style="border-radius: 50px 15px; max-width: 60px;">
<NavLink href="/pokemon-sleep/add-new-pokemon"> <NavLink href="/pokemonsleep/add-new-pokemon">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-plus-circle-fill text-white" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-plus-circle-fill text-white" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M8.5 4.5a.5.5 0 0 0-1 0v3h-3a.5.5 0 0 0 0 1h3v3a.5.5 0 0 0 1 0v-3h3a.5.5 0 0 0 0-1h-3z" /> <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M8.5 4.5a.5.5 0 0 0-1 0v3h-3a.5.5 0 0 0 0 1h3v3a.5.5 0 0 0 1 0v-3h3a.5.5 0 0 0 0-1h-3z" />
</svg> </svg>
@ -40,4 +49,6 @@
</button> </button>
</div> </div>
</div>
</div> </div>

View File

@ -1,22 +0,0 @@
<div class="wrapper">
@if (shinyUrl == null)
{
<div class="flip-container">
<div class="flipper">
<img class="front" src="@baseUrl" />
</div>
</div>
}
else
{
<div class="flip-container" @onclick="() => ToggleImage()">
<div class="flipper @(isShiny ? "flipped" : "")">
<img class="front" src="@baseUrl" />
<img class="back" src="@shinyUrl" />
</div>
</div>
}
</div>

View File

@ -1,20 +0,0 @@
using Microsoft.AspNetCore.Components;
namespace Portfolio.WebUI.Server.Components.Component.Pokemon_Components
{
public partial class PokemonImage
{
[Parameter]
public string baseUrl { get; set; }
[Parameter]
public string shinyUrl { get; set; }
private bool isShiny = false;
private void ToggleImage()
{
isShiny = !isShiny;
StateHasChanged();
}
}
}

View File

@ -1,50 +0,0 @@
.wrapper {
display: inline-block;
width: 90%;
height: 90%;
}
.flip-container {
position: absolute !important;
top: 40% !important;
left: 50% !important;
transform: translate(-50%, -50%) !important;
perspective: 1000px;
display: inline-block;
width: 80%;
aspect-ratio: 1 / 1;
max-width: 280px;
margin: 0 auto;
cursor: pointer;
}
.flipper {
transition: transform 0.6s;
transform-style: preserve-3d;
width: 100%;
height: 100%;
position: relative;
}
.flipped {
transform: rotateY(180deg);
}
.wrapper {
position: relative;
max-height: 100px;
width: 100%;
}
.front, .back {
width: 100%;
height: 100%;
position: absolute;
inset: 0; /* shorthand for top/right/bottom/left: 0 */
backface-visibility: hidden;
object-fit: contain; /* keep aspect ratio inside the box */
}
.back {
transform: rotateY(180deg);
}

View File

@ -1,6 +0,0 @@
namespace Portfolio.WebUI.Server.Components.Component.Pokemon_Components
{
public partial class PokemonNavMenu
{
}
}

View File

@ -1,16 +1,16 @@
 
<!-- Search Input --> <!-- Search Input -->
<div class="pokemon-selector p-3 bg-light"> <div class="pokemon-selector p-3 bg-light">
<input class="form-control mb-3 rounded rounded-5" placeholder="Search Pokémon..." @bind="SearchTerm" @oninput="HandleSearch" /> <input class="form-control mb-3" placeholder="Search Pokémon..." @bind="SearchTerm" @oninput="HandleSearch" />
<!-- Scrollable Pokémon Grid --> <!-- Scrollable Pokémon Grid -->
<div class="row pokemon-grid pt-1"> <div class="row pokemon-grid">
@foreach (var pokemon in FilteredPokemon) @foreach (var pokemon in FilteredPokemon)
{ {
bool isSelected = SelectedPokemon?.Id == pokemon.Id; bool isSelected = SelectedPokemon?.Id == pokemon.Id;
<div class="col-6 col-md-3 mb-3"> <div class="col-6 col-md-3 mb-3">
<div class="card pokemon-card small-card @(isSelected ? "border-primary border-2 shadow" : "border-2 border-white") rounded rounded-3" <div class="card pokemon-card small-card @(isSelected ? "border-primary border-2 shadow" : "border-2 border-white")"
@onclick="() => SelectPokemon(pokemon)"> @onclick="() => SelectPokemon(pokemon)">
<img src="@pokemon.PokemonImageUrl" class="card-img-top" style="height: 50px; object-fit: contain;" /> <img src="@pokemon.PokemonImageUrl" class="card-img-top" style="height: 50px; object-fit: contain;" />
<div class="card-body p-2 text-center"> <div class="card-body p-2 text-center">
@ -21,3 +21,7 @@
} }
</div> </div>
</div> </div>
<style>
</style>

View File

@ -5,13 +5,11 @@
border-radius: 5% / 3.5%; border-radius: 5% / 3.5%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.pokemon-grid { .pokemon-grid {
flex: 1 1 auto; flex: 1 1 auto;
overflow-y: auto; overflow-y: auto;
align-content: flex-start;
} }
@ -21,7 +19,7 @@
} }
.pokemon-card:hover { .pokemon-card:hover {
transform: scale(1.13); transform: scale(1.05);
} }
.small-card { .small-card {

View File

@ -5,52 +5,55 @@
@attribute [StreamRendering] @attribute [StreamRendering]
@rendermode InteractiveServer @rendermode InteractiveServer
<div class="d-flex justify-content-end">
</div>
<!-- Table A: Desktop View--> <!-- Table A: Desktop View-->
<div class="container d-none d-lg-block d-md-none mt-4"> <div class="container d-none d-md-block " style="height: 70vh;">
<!-- Main UI --> <!-- Main UI -->
<div class="border-0 mx-auto col-8 "> <div class="border-0 mt-4 mx-auto col-12 col-md-10 col-lg-8 pokemontable ">
<!-- UI Header --> <!-- Table Header -->
<div class="row bg-secondary py-3 border-0 rounded-top"> <div class="row bg-secondary bg-gradient py-3 border-0">
<div class="d-flex align-items-center justify-content-between w-100 position-relative px-3"> <div class="d-flex align-items-center justify-content-between w-100 position-relative px-3">
<!-- Left: Search --> <!-- Left: Search -->
<input class="form-control w-25 me-3 rounded rounded-5" <input class="form-control w-25 me-3"
placeholder="Search Pokémon..." placeholder="Search Pokémon..."
@bind="SearchTerm" @bind="SearchTerm"
@oninput="HandleSearch" /> @oninput="HandleSearch" />
<!-- Center: Title --> <!-- Center: Title -->
<h2 class="text-white mb-0 position-absolute start-50 translate-middle-x"> <h2 class="text-white text-decoration-underline mb-0 position-absolute start-50 translate-middle-x">
Available Pokémon Available Pokémon
</h2> </h2>
<!-- Right: Count + Download --> <!-- Right: Count + Download -->
<div class="d-flex align-items-center gap-2"> <div class="d-flex align-items-center gap-2">
<div class="badge bg-light"> <div class="badge bg-info">
<p class="statText text-primary fw-medium shadow mb-0">@(pokemons.Count()) Pokémon</p> <p class="statText mb-0">@(pokemons.Count()) Pokémon</p>
</div> </div>
<PokemonDownloadButton _Pokemon="pokemons" /> <PokemonDownload _Pokemon="pokemons" />
</div> </div>
</div> </div>
</div> </div>
<!-- Table -->
<div class="tableFixHead d-flex flex-column justify-content-start bg-secondary table-responsive row "> <div class="tableFixHead d-flex flex-column justify-content-start bg-secondary table-responsive row ">
<table class="table table-borderless border-0 table-secondary table-striped align-middle"> <table class="table table-borderless border-0 table-secondary table-striped align-middle">
<!-- Table Head --> <!-- Table Head -->
<thead> <thead class="">
<tr> <tr class="">
<th class="text-white text-bg-info col-2" scope="col"></th> <th class="text-white text-bg-info col-2 d-none d-md-table-cell" scope="col"></th>
<th class="text-white text-bg-info col-1" scope="col">#</th> <th class="text-white text-bg-info col-1" scope="col">#</th>
<th class="text-white text-bg-info col-2" scope="col">Pokémon</th> <th class="text-white text-bg-info col-2" scope="col">Pokémon</th>
<th class="text-white text-bg-info col-1 text-center" scope="col">Type</th> <th class="text-white text-bg-info col-1 text-center" scope="col">Type</th>
<th class="text-white text-bg-info col-1 text-center" scope="col">Sleep Type</th> <th class="text-white text-bg-info col-2 text-center" scope="col">Sleep Type</th>
<th class="text-white text-bg-info col-1 text-center" scope="col">Speciality</th> <th class="text-white text-bg-info col-2 text-center" scope="col">Speciality</th>
@if (adminToggle) @if (adminToggle)
{ {
<th class="text-white text-bg-info col-2 text-center" scope="col">Admin</th> <th class="text-white text-bg-info col-1 text-center" scope="col">Edit</th>
} }
</tr> </tr>
@ -65,61 +68,84 @@
else else
{ {
<!-- Table Body --> <!-- Table Body -->
<tbody> <tbody class="">
<tr></tr>
@if (FilteredPokemon != null && FilteredPokemon.Any()) @if (FilteredPokemon != null && FilteredPokemon.Any())
{ {
@foreach (var pokemon in FilteredPokemon) @foreach (var pokemon in FilteredPokemon)
{ {
<tr> <tr class="flex-row">
<!-- Section 1: Pokemon Image --> <!-- Section: Pokemon Image -->
<td class="pokeimage"> @{
<PokemonImage baseUrl="@pokemon.PokemonImageUrl" shinyUrl="@pokemon.PokemonShinyImageUrl" /> string baseUrl = pokemon.PokemonImageUrl;
string shinyUrl = pokemon.PokemonShinyImageUrl;
}
<td class="text-center d-none d-md-table-cell">
@if (shinyUrl == null)
{
<div class="flip-container">
<div class="flipper">
<img class="front img-fluid" style="max-width: 100px;" src="@baseUrl" />
</div>
</div>
}
else
{
<div class="flip-container" @onclick="() => ToggleImage(pokemon.Id)">
<div class="flipper @(isShiny[pokemon.Id] ? "flipped" : "")">
<img class="front img-fluid" style="max-width: 100px;" src="@baseUrl" />
<img class="back img-fluid" style="max-width: 100px;" src="@shinyUrl" />
</div>
</div>
}
</td> </td>
<!-- Section 2: Pokemon # --> <!-- Section 2: Pokemon # -->
<th scope="row" style="cursor: default;">@pokemon.PokemonId</th> <th class="" scope="row" style="cursor: default;">@pokemon.PokemonId</th>
<!-- Section 3: Pokemon Name --> <!-- Section 3: Pokemon Name -->
<td @onclick="() => ViewPokemon(pokemon.PokemonId)" class="pokemon-name-style fw-light col-2">@(pokemon.IsVariation && ToggleVariationName(pokemon.Id, pokemon.PokemonId) ? $"{pokemon.VariationName} {pokemon.PokemonName}" : pokemon.PokemonName)</td>
<td @onclick="() => ViewPokemon(pokemon.PokemonId)" class="pokemon-name-style fw-light col-2">@(pokemon.IsVariation && ToggleVariationName(pokemon.Id, pokemon.PokemonId) ? $"{pokemon.VariationName} {pokemon.PokemonName}" : pokemon.PokemonName)</td>
<!-- Section 4: Pokemon Type --> <!-- Section 4: Pokemon Type -->
<td> <td class="">
<div class="d-flex justify-content-center"> <div class="d-flex justify-content-center">
<img src="@GetTypeImageUrl(pokemon.PokemonType)" style="width:36px; height:36px;box-shadow: 0 1px 2px 1px rgba(0,0,0,0.35);border-radius: 20px;" /> <img src="@GetTypeImageUrl(pokemon.PokemonType)" style="width:36px; height:36px;" />
</div> </div>
</td> </td>
<!-- Section 5: Sleep Type --> <!-- Section 5: Sleep Type -->
<td> <td class="" style="">
<div class="d-flex justify-content-center "> <div class="d-flex justify-content-center ">
<PokemonBadge BadgeItem="@pokemon.SleepType" /> <PokemonBadge BadgeItem="@pokemon.SleepType" />
</div> </div>
</td> </td>
<!-- Section 6: Speciality --> <!-- Section 6: Speciality -->
<td> <td class="" style="">
<div class="d-flex justify-content-center"> <div class="d-flex justify-content-center">
<PokemonBadge BadgeItem="@pokemon.Speciality" /> <PokemonBadge BadgeItem="@pokemon.Speciality" />
</div> </div>
</td> </td>
<!-- Section 7: Admin Controls -->
@if (adminToggle) @if (adminToggle)
{ {
<td> <td class="" style="">
<div class="d-flex justify-content-center gap-1"> <div class="d-flex justify-content-center">
<PokemonEditButton PokemonId="@pokemon.PokemonId" /> <PokemonEditButton PokemonId="@pokemon.PokemonId" />
<button class="btn btn-danger rounded rounded-5 text-white " @onclick="() => ConfirmDelete(pokemon.Id)">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash3-fill" viewBox="0 0 16 16">
<path d="M11 1.5v1h3.5a.5.5 0 0 1 0 1h-.538l-.853 10.66A2 2 0 0 1 11.115 16h-6.23a2 2 0 0 1-1.994-1.84L2.038 3.5H1.5a.5.5 0 0 1 0-1H5v-1A1.5 1.5 0 0 1 6.5 0h3A1.5 1.5 0 0 1 11 1.5m-5 0v1h4v-1a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 0-.5.5M4.5 5.029l.5 8.5a.5.5 0 1 0 .998-.06l-.5-8.5a.5.5 0 1 0-.998.06m6.53-.528a.5.5 0 0 0-.528.47l-.5 8.5a.5.5 0 0 0 .998.058l.5-8.5a.5.5 0 0 0-.47-.528M8 4.5a.5.5 0 0 0-.5.5v8.5a.5.5 0 0 0 1 0V5a.5.5 0 0 0-.5-.5" />
</svg>
</button>
</div> </div>
</td> </td>
} }
</tr> </tr>
} }
} }
@ -150,223 +176,69 @@
</div> </div>
</div> </div>
<div class="container d-none d-lg-none d-md-block mt-4">
<!-- Main UI -->
<div class="border-0 mx-auto col-8 ">
<!-- UI Header -->
<div class="row bg-secondary py-3 border-0 rounded-top">
<div class="d-flex flex-row align-items-center justify-content-between w-100 gap-3 ms-0 me-0">
<div class="col">
<input class="form-control rounded rounded-5 fs-6 fw-lighter"
placeholder="Search Pokémon..."
@bind="SearchTerm"
@oninput="HandleSearch" />
</div>
<!-- Left: Search -->
<!-- Center: Title -->
<div class="col">
<h2 class="text-white text-center pt-2 fs-6 fw-light">
Available Pokémon
</h2>
</div>
<!-- Right: Count + Download -->
<div class="col">
<div class="d-flex align-items-center gap-1">
<div class="badge bg-light">
<p class="statText text-primary fw-medium shadow mb-0">@(pokemons.Count()) Pokémon</p>
</div>
<PokemonDownloadButton _Pokemon="pokemons" />
</div>
</div>
</div>
</div>
<!-- Table -->
<div class="tableFixHead d-flex flex-column justify-content-start bg-secondary table-responsive row ">
<table class="table table-borderless border-0 table-secondary table-striped align-middle">
<!-- Table Head -->
<thead>
<tr>
<th class="text-white text-bg-info col-2" scope="col"></th>
<th class="text-white text-bg-info col-1" scope="col">#</th>
<th class="text-white text-bg-info col-2" scope="col">Pokémon</th>
<th class="text-white text-bg-info col-1 text-center" scope="col">Type</th>
<th class="text-white text-bg-info col-1 text-center" scope="col">Sleep Type</th>
<th class="text-white text-bg-info col-1 text-center" scope="col">Speciality</th>
@if (adminToggle)
{
<th class="text-white text-bg-info col-2 text-center" scope="col">Admin</th>
}
</tr>
</thead>
<!-- If/Else Pokemon Loaded-->
@if (pokemons == null)
{
<tbody>
<Loading />
</tbody>
}
else
{
<!-- Table Body -->
<tbody>
@if (FilteredPokemon != null && FilteredPokemon.Any())
{
@foreach (var pokemon in FilteredPokemon)
{
<tr>
<!-- Section 1: Pokemon Image -->
<td class="">
<img src="@pokemon.PokemonImageUrl" style="width:100px;" />
</td>
<!-- Section 2: Pokemon # -->
<th scope="row" style="cursor: default;">@pokemon.PokemonId</th>
<!-- Section 3: Pokemon Name -->
<td @onclick="() => ViewPokemon(pokemon.PokemonId)" class="pokemon-name-style fw-light col-2">@(pokemon.IsVariation && ToggleVariationName(pokemon.Id, pokemon.PokemonId) ? $"{pokemon.VariationName} {pokemon.PokemonName}" : pokemon.PokemonName)</td>
<!-- Section 4: Pokemon Type -->
<td>
<div class="d-flex justify-content-center">
<img src="@GetTypeImageUrl(pokemon.PokemonType)" style="width:36px; height:36px;" />
</div>
</td>
<!-- Section 5: Sleep Type -->
<td>
<div class="d-flex justify-content-center ">
<PokemonBadge BadgeItem="@pokemon.SleepType" />
</div>
</td>
<!-- Section 6: Speciality -->
<td>
<div class="d-flex justify-content-center">
<PokemonBadge BadgeItem="@pokemon.Speciality" />
</div>
</td>
<!-- Section 7: Admin Controls -->
@if (adminToggle)
{
<td>
<div class="d-flex justify-content-center gap-1">
<PokemonEditButton PokemonId="@pokemon.PokemonId" />
<button class="btn btn-danger rounded rounded-5 text-white " @onclick="() => ConfirmDelete(pokemon.Id)">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash3-fill" viewBox="0 0 16 16">
<path d="M11 1.5v1h3.5a.5.5 0 0 1 0 1h-.538l-.853 10.66A2 2 0 0 1 11.115 16h-6.23a2 2 0 0 1-1.994-1.84L2.038 3.5H1.5a.5.5 0 0 1 0-1H5v-1A1.5 1.5 0 0 1 6.5 0h3A1.5 1.5 0 0 1 11 1.5m-5 0v1h4v-1a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 0-.5.5M4.5 5.029l.5 8.5a.5.5 0 1 0 .998-.06l-.5-8.5a.5.5 0 1 0-.998.06m6.53-.528a.5.5 0 0 0-.528.47l-.5 8.5a.5.5 0 0 0 .998.058l.5-8.5a.5.5 0 0 0-.47-.528M8 4.5a.5.5 0 0 0-.5.5v8.5a.5.5 0 0 0 1 0V5a.5.5 0 0 0-.5-.5" />
</svg>
</button>
</div>
</td>
}
</tr>
}
}
else
{
<tr>
<td colspan="100%">
<div class="d-flex justify-content-center align-items-center" style="height: 200px;">
<p class="text-muted">Pokémon could not be found.</p>
</div>
</td>
</tr>
}
</tbody>
}
</table>
</div>
<!-- Wrap in Auth -->
<div class="d-flex justify-content-end mt-1">
<div class="form-check form-switch">
<input class="form-check-input rounded rounded-3" type="checkbox" role="switch" id="flexSwitchCheckDefault" @bind="adminToggle">
</div>
</div>
</div>
</div>
<!-- Desktop B: Mobile View --> <!-- Desktop B: Mobile View -->
@* <div class="container card border-0 d-block d-md-none mx-auto mt-4 shadow-sm"> <div class="container card border-0 d-block d-md-none mx-auto mt-4 shadow-sm">
<!-- Table Header --> <!-- Table Header -->
<div class="row card-header bg-secondary bg-gradient ml-0 py-3 border-0 bg-info"> <div class="row card-header bg-secondary bg-gradient ml-0 py-3 border-0 bg-info">
<div class="flex-row justify-content-between"> <div class="flex-row justify-content-between">
<div class="text-center position-relative"> <div class="text-center position-relative">
<h2 class="text-white text-decoration-underline">Pokémon</h2> <h2 class="text-white text-decoration-underline">Pokémon</h2>
<div class="m-1 badge bg-white text-info position-absolute top-0 end-0 border-0 w-auto"><p class="statText">@(pokemons.Count()) Pokémon</p></div> <div class="m-1 badge bg-white text-info position-absolute top-0 end-0 border-0 w-auto"><p class="statText">@(pokemons.Count()) Pokémon</p></div>
</div> </div>
</div> </div>
</div> </div>
<!-- Table Body --> <!-- Table Body -->
<div class="tableFixHead row"> <div class="tableFixHead row">
<table class="table table-striped border-0"> <table class="table table-striped border-0">
<tbody> <tbody>
@if (pokemons == null) @if (pokemons == null)
{ {
<Loading /> <Loading />
} }
else else
{ {
@foreach (var pokemon in pokemons) @foreach (var pokemon in pokemons)
{ {
<tr class="border-0"> <tr class="border-0">
<div class="d-flex align-items-center" style="border: 1px dashed hotpink;"> <div class="d-flex align-items-center">
<!-- Pokemon Image --> <!-- Pokemon Image -->
<div class="me-3" style="border: 1px dashed hotpink;"> <div class="me-3">
<div class="flip-container-sm" @onclick="() => ToggleImage(pokemon.Id)"> <div class="flip-container-sm" @onclick="() => ToggleImage(pokemon.Id)">
<div class="flipper-sm @(isShiny[pokemon.Id] ? "flipped" : "")"> <div class="flipper-sm @(isShiny[pokemon.Id] ? "flipped" : "")">
<img class="front img-fluid" src="@pokemon.PokemonImageUrl" /> <img class="front img-fluid" src="@pokemon.PokemonImageUrl" />
@if (pokemon.PokemonShinyImageUrl != null) @if (pokemon.PokemonShinyImageUrl != null)
{ {
<img class="back img-fluid" src="@pokemon.PokemonShinyImageUrl" /> <img class="back img-fluid" src="@pokemon.PokemonShinyImageUrl" />
} }
</div> </div>
</div> </div>
</div> </div>
<div style="border: 1px dashed hotpink;"> <div class="">
<!-- Number and Name --> <!-- Number and Name -->
<h5> <h5>
@pokemon.PokemonId - @pokemon.PokemonId -
<span class="pokemon-name-style fw-light" @onclick="() => ViewPokemon(pokemon.PokemonId)"> <span class="pokemon-name-style fw-light" @onclick="() => ViewPokemon(pokemon.PokemonId)">
@(pokemon.IsVariation && ToggleVariationName(pokemon.Id, pokemon.PokemonId) ? $"{pokemon.VariationName} {pokemon.PokemonName}" : pokemon.PokemonName) @(pokemon.IsVariation && ToggleVariationName(pokemon.Id, pokemon.PokemonId) ? $"{pokemon.VariationName} {pokemon.PokemonName}" : pokemon.PokemonName)
</span> </span>
</h5> </h5>
<!-- Stats --> <!-- Stats -->
<div class="d-flex flex-wrap align-items-center gap-2"> <div class="d-flex flex-wrap align-items-center gap-2">
<img src="@GetTypeImageUrl(pokemon.PokemonType)" style="width:28px;" /> <img src="@GetTypeImageUrl(pokemon.PokemonType)" style="width:28px;" />
<PokemonBadge BadgeItem="@pokemon.SleepType" /> <PokemonBadge BadgeItem="@pokemon.SleepType" />
<PokemonBadge BadgeItem="@pokemon.Speciality" /> <PokemonBadge BadgeItem="@pokemon.Speciality" />
</div> </div>
</div> </div>
</div> </div>
</tr> </tr>
} }
} }
</tbody> </tbody>
</table> </table>
</div> </div>
</div> *@ </div>

View File

@ -11,7 +11,9 @@ namespace Portfolio.WebUI.Server.Components.Component.Pokemon_Components
[Parameter] [Parameter]
public List<Pokemon> AllPokemon { get; set; } public List<Pokemon> AllPokemon { get; set; }
private List<Pokemon> pokemons = new List<Pokemon>(); private List<Pokemon> pokemons = new List<Pokemon>();
private Dictionary<int, bool> isShiny = new Dictionary<int, bool>();
private bool adminToggle = false; private bool adminToggle = false;
@ -21,6 +23,10 @@ namespace Portfolio.WebUI.Server.Components.Component.Pokemon_Components
if (AllPokemon != null) { if (AllPokemon != null) {
pokemons = AllPokemon.ToList(); pokemons = AllPokemon.ToList();
foreach (var pokemon in pokemons)
{
isShiny[pokemon.Id] = false;
}
} }
} }
private string SearchTerm { get; set; } = string.Empty; private string SearchTerm { get; set; } = string.Empty;
@ -35,6 +41,13 @@ namespace Portfolio.WebUI.Server.Components.Component.Pokemon_Components
{ {
SearchTerm = e?.Value?.ToString() ?? ""; SearchTerm = e?.Value?.ToString() ?? "";
} }
private void ToggleImage(int Id)
{
if (isShiny.ContainsKey(Id))
{
isShiny[Id] = !isShiny[Id];
}
}
private bool ToggleVariationName(int Id, int PokemonId) private bool ToggleVariationName(int Id, int PokemonId)
{ {
@ -66,12 +79,12 @@ namespace Portfolio.WebUI.Server.Components.Component.Pokemon_Components
private void EditPokemon(int id) private void EditPokemon(int id)
{ {
Navigation.NavigateTo($"/pokemon-sleep/edit/{id}"); Navigation.NavigateTo($"/pokemonsleep/edit/{id}");
} }
private void ViewPokemon(int id) private void ViewPokemon(int id)
{ {
Navigation.NavigateTo($"/pokemon-sleep/pokemon/{id}"); Navigation.NavigateTo($"/pokemon/{id}");
} }
private string GetTypeImageUrl(string pokemonType) private string GetTypeImageUrl(string pokemonType)
@ -83,7 +96,6 @@ namespace Portfolio.WebUI.Server.Components.Component.Pokemon_Components
return $"https://www.serebii.net/pokemonsleep/pokemon/type/{pokemonType.ToLower()}.png"; return $"https://www.serebii.net/pokemonsleep/pokemon/type/{pokemonType.ToLower()}.png";
} }
private void HandleToggleChange(ChangeEventArgs e) private void HandleToggleChange(ChangeEventArgs e)
{ {
Console.WriteLine($"Admin Toggle is now: {adminToggle}"); Console.WriteLine($"Admin Toggle is now: {adminToggle}");

View File

@ -1,13 +1,12 @@
.five-percent { .five-percent {
width: 5%; width: 5%;
} }
.ten-percent { .ten-percent {
width: 10%; width: 10%;
} }
.pokemontable { .pokemontable {
height: 65vh; height: 69vh;
} }
.tableFixHead { .tableFixHead {
@ -26,7 +25,7 @@
} }
.pokemon-name-style { .pokemon-name-style {
cursor: pointer; cursor:pointer;
font-size: 1.3rem; font-size: 1.3rem;
} }
@ -88,6 +87,28 @@
} }
.pokeimage {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.front, .back {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
backface-visibility: hidden;
}
.back {
transform: rotateY(180deg);
}
.badge { .badge {
width: 100px; width: 100px;
@ -108,15 +129,5 @@
cursor: default; cursor: default;
} }
.pokeimage {
width: 100px;
height: 130px;
}

View File

@ -1,34 +0,0 @@
<div class=" mx-auto w-75" >
<header class="pt-5 w-100">
<div class="row flex-nowrap justify-content-evenly align-items-center" >
<div class="col pt-1">
<div class="d-flex align-items-center">
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="@_primaryColor" class="bi bi-arrow-through-heart" viewBox="0 0 16 16" 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 text-primary">Kira Jiroux</span>
</div>
</div>
<div class="col d-flex justify-content-end align-items-center gap-5">
<NavLink class="nav-link d-flex align-items-center rounded rounded-5" href="" Match="NavLinkMatch.All" ActiveClass="nav-active">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="@_primaryColor" class="bi bi-house-heart-fill" viewBox="0 0 16 16">
<path d="M7.293 1.5a1 1 0 0 1 1.414 0L11 3.793V2.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v3.293l2.354 2.353a.5.5 0 0 1-.708.707L8 2.207 1.354 8.853a.5.5 0 1 1-.708-.707z" />
<path d="m14 9.293-6-6-6 6V13.5A1.5 1.5 0 0 0 3.5 15h9a1.5 1.5 0 0 0 1.5-1.5zm-6-.811c1.664-1.673 5.825 1.254 0 5.018-5.825-3.764-1.664-6.691 0-5.018" />
</svg> <span class="mx-2 mt-0 text-primary">Home</span>
</NavLink>
<NavLink class="nav-link d-flex align-items-center rounded rounded-5" href="temperature-blanket" ActiveClass="nav-active">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="@_primaryColor" class="bi bi-grid-3x3" viewBox="0 0 16 16">
<path d="M0 1.5A1.5 1.5 0 0 1 1.5 0h13A1.5 1.5 0 0 1 16 1.5v13a1.5 1.5 0 0 1-1.5 1.5h-13A1.5 1.5 0 0 1 0 14.5zM1.5 1a.5.5 0 0 0-.5.5V5h4V1zM5 6H1v4h4zm1 4h4V6H6zm-1 1H1v3.5a.5.5 0 0 0 .5.5H5zm1 0v4h4v-4zm5 0v4h3.5a.5.5 0 0 0 .5-.5V11zm0-1h4V6h-4zm0-5h4V1.5a.5.5 0 0 0-.5-.5H11zm-1 0V1H6v4z" />
</svg><span class="mx-2 mt-0 text-primary">Crochet</span>
</NavLink>
<NavLink class="nav-link d-flex align-items-center rounded rounded-5" href="pokemon-sleep" ActiveClass="nav-active">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="@_primaryColor" class="bi bi-p-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M5.5 4.002V12h1.283V9.164h1.668C10.033 9.164 11 8.08 11 6.586c0-1.482-.955-2.584-2.538-2.584zm2.77 4.072c.893 0 1.419-.545 1.419-1.488s-.526-1.482-1.42-1.482H6.778v2.97z" />
</svg> <span class="mx-2 mt-0 text-primary">Pokémon Sleep</span>
</NavLink>
</div>
</div>
</header>
</div>
<div class="mt-2 mb-3 mx-auto w-75 border-top border-primary-subtle"></div>

View File

@ -1,7 +0,0 @@
namespace Portfolio.WebUI.Server.Components.Layout
{
public partial class BaseNavMenu
{
private string _primaryColor = "#593196";
}
}

View File

@ -1,13 +0,0 @@
body {
}
::deep .nav-active {
font-weight: bold;
background-color: #f2eaff;
color: black;
padding-left: 15px;
padding-right: 15px;
padding-top: 5px;
padding-bottom: 5px;
border: 1px dashed #593196;
}

View File

@ -1,14 +1,11 @@
 <div class="position-absolute bottom-0 vw-100">
<div class="mt-2 mx-auto w-75 mt-2 border-top border-primary-subtle"></div> <footer class="d-flex flex-column align-content-center">
<div class="container mt-2"> <hr class="border-bottom border-primary border-1 mx-5">
<footer class="d-flex flex-column align-content-center"> <p class="text-center text-primary">
Made with Love
<p class="text-center fs-6 fw-lighter text-muted"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-through-heart" viewBox="0 0 16 16">
Made with Love <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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-through-heart" viewBox="0 0 16 16"> </svg>
<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" /> </p>
</svg> </footer>
</p> </div>
</footer>
</div>

View File

@ -1,9 +1,11 @@
@inherits LayoutComponentBase @inherits LayoutComponentBase
<div class="d-flex flex-column min-vh-100"> <div class="page">
<BaseNavMenu /> <main class="">
<main class="container flex-grow-1"> <NavMenu3 />
@Body <div class="container">
@Body
</div>
</main> </main>
<MadeWithLoveFooter/> @* <MadeWithLoveFooter/> *@
</div> </div>

View File

@ -1,4 +1,8 @@
.page {
position: relative;
display: flex;
flex-direction: column;
}
main { main {
flex: 1; flex: 1;
@ -8,10 +12,6 @@ main {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
} }
.container {
max-width: 1920px;
}
.top-row { .top-row {
background-color: #f7f7f7; background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5; border-bottom: 1px solid #d6d5d5;
@ -47,6 +47,9 @@ main {
} }
@media (min-width: 641px) { @media (min-width: 641px) {
.page {
flex-direction: row;
}
.sidebar { .sidebar {
width: 250px; width: 250px;
@ -73,3 +76,21 @@ main {
} }
} }
#blazor-error-ui {
background: lightyellow;
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
}
#blazor-error-ui .dismiss {
cursor: pointer;
position: absolute;
right: 0.75rem;
top: 0.5rem;
}

View File

@ -1,35 +1,35 @@
<div class="navbar navbar-expand bg-primary border-0"> <div class="top-row ps-3 navbar navbar-dark">
<div class="d-flex align-items-center mb-3 mb-md-0 me-md-auto link-light text-decoration-none px-3"> <div class="container-fluid">
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="#FFFFFF" class="bi bi-arrow-through-heart" viewBox="0 0 16 16" style="cursor: pointer;"> <a class="navbar-brand" href="">Portfolio.WebUI.Server</a>
<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 text-white">Kira Jiroux</span>
</div> </div>
<ul class="navbar-nav"> </div>
<li class="nav-item"> <input type="checkbox" title="Navigation menu" class="navbar-toggler" />
<NavLink class="nav-link d-flex align-items-center" href="" Match="NavLinkMatch.All">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#FFFFFF" class="bi bi-house-heart-fill" viewBox="0 0 16 16"> <div class="nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()">
<path d="M7.293 1.5a1 1 0 0 1 1.414 0L11 3.793V2.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v3.293l2.354 2.353a.5.5 0 0 1-.708.707L8 2.207 1.354 8.853a.5.5 0 1 1-.708-.707z" /> <nav class="flex-column">
<path d="m14 9.293-6-6-6 6V13.5A1.5 1.5 0 0 0 3.5 15h9a1.5 1.5 0 0 0 1.5-1.5zm-6-.811c1.664-1.673 5.825 1.254 0 5.018-5.825-3.764-1.664-6.691 0-5.018" /> <div class="nav-item px-3">
</svg> <span class="mx-2 mt-0 text-white">Home</span> <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="bi bi-house-door-fill-nav-menu" aria-hidden="true"></span> Home
</NavLink> </NavLink>
</li> </div>
<li>
<NavLink class="nav-link d-flex align-items-center" href="temperature-blanket"> <div class="nav-item px-3">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#FFFFFF" class="bi bi-border-outer" viewBox="0 0 16 16"> <NavLink class="nav-link" href="articles">
<path d="M7.5 1.906v.938h1v-.938zm0 1.875v.938h1V3.78h-1zm0 1.875v.938h1v-.938zM1.906 8.5h.938v-1h-.938zm1.875 0h.938v-1H3.78v1zm1.875 0h.938v-1h-.938zm2.813 0v-.031H8.5V7.53h-.031V7.5H7.53v.031H7.5v.938h.031V8.5zm.937 0h.938v-1h-.938zm1.875 0h.938v-1h-.938zm1.875 0h.938v-1h-.938zM7.5 9.406v.938h1v-.938zm0 1.875v.938h1v-.938zm0 1.875v.938h1v-.938z" /> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-journal-richtext" viewBox="0 0 16 16">
<path d="M0 0v16h16V0zm1 1h14v14H1z" /> <path d="M7.5 3.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m-.861 1.542 1.33.886 1.854-1.855a.25.25 0 0 1 .289-.047L11 4.75V7a.5.5 0 0 1-.5.5h-5A.5.5 0 0 1 5 7v-.5s1.54-1.274 1.639-1.208M5 9.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5m0 2a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5" />
</svg><span class="mx-2 mt-0 text-white">Crochet</span> <path d="M3 0h10a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2v-1h1v1a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H3a1 1 0 0 0-1 1v1H1V2a2 2 0 0 1 2-2" />
<path d="M1 5v-.5a.5.5 0 0 1 1 0V5h.5a.5.5 0 0 1 0 1h-2a.5.5 0 0 1 0-1zm0 3v-.5a.5.5 0 0 1 1 0V8h.5a.5.5 0 0 1 0 1h-2a.5.5 0 0 1 0-1zm0 3v-.5a.5.5 0 0 1 1 0v.5h.5a.5.5 0 0 1 0 1h-2a.5.5 0 0 1 0-1z" />
</svg> Articles
</NavLink> </NavLink>
</li> </div>
<li> <div class="nav-item px-3">
<NavLink class="nav-link d-flex align-items-center" href="pokemonsleep"> <NavLink class="nav-link" href="pokemonsleep">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#FFFFFF" class="bi bi-p-circle-fill" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-p-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M5.5 4.002V12h1.283V9.164h1.668C10.033 9.164 11 8.08 11 6.586c0-1.482-.955-2.584-2.538-2.584zm2.77 4.072c.893 0 1.419-.545 1.419-1.488s-.526-1.482-1.42-1.482H6.778v2.97z" /> <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M5.5 4.002V12h1.283V9.164h1.668C10.033 9.164 11 8.08 11 6.586c0-1.482-.955-2.584-2.538-2.584zm2.77 4.072c.893 0 1.419-.545 1.419-1.488s-.526-1.482-1.42-1.482H6.778v2.97z" />
</svg> <span class="mx-2 mt-0 text-white">Pokémon Sleep</span> </svg> Pokemon Sleep
</NavLink> </NavLink>
</li> </div>
</nav>
</ul> </div>
</div>

View File

@ -0,0 +1,105 @@
.navbar-toggler {
appearance: none;
cursor: pointer;
width: 3.5rem;
height: 2.5rem;
color: white;
position: absolute;
top: 0.5rem;
right: 1rem;
border: 1px solid rgba(255, 255, 255, 0.1);
background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1);
}
.navbar-toggler:checked {
background-color: rgba(255, 255, 255, 0.5);
}
.top-row {
height: 3.5rem;
background-color: rgba(0,0,0,0.4);
}
.navbar-brand {
font-size: 1.1rem;
}
.bi {
display: inline-block;
position: relative;
width: 1.25rem;
height: 1.25rem;
margin-right: 0.75rem;
top: -1px;
background-size: cover;
}
.bi-house-door-fill-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
}
.bi-plus-square-fill-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
}
.bi-list-nested-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
}
.nav-item {
font-size: 0.9rem;
padding-bottom: 0.5rem;
}
.nav-item:first-of-type {
padding-top: 1rem;
}
.nav-item:last-of-type {
padding-bottom: 1rem;
}
.nav-item ::deep .nav-link {
color: #d7d7d7;
background: none;
border: none;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
width: 100%;
}
.nav-item ::deep a.active {
background-color: rgba(255,255,255,0.37);
color: white;
}
.nav-item ::deep .nav-link:hover {
background-color: rgba(255,255,255,0.1);
color: white;
}
.nav-scrollable {
display: none;
}
.navbar-toggler:checked ~ .nav-scrollable {
display: block;
}
@media (min-width: 641px) {
.navbar-toggler {
display: none;
}
.nav-scrollable {
/* Never collapse the sidebar for wide screens */
display: block;
/* Allow sidebar to scroll for tall menus */
height: calc(100vh - 3.5rem);
overflow-y: auto;
}
}

View File

@ -0,0 +1,41 @@
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavDropdown">
<ul class="navbar-nav">
<li class="nav-item active">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="bi bi-house-door-fill-nav-menu" aria-hidden="true"></span> Home
</NavLink>
</li>
<li class="nav-item">
<NavLink class="nav-link" href="articles">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-journal-richtext" viewBox="0 0 16 16">
<path d="M7.5 3.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m-.861 1.542 1.33.886 1.854-1.855a.25.25 0 0 1 .289-.047L11 4.75V7a.5.5 0 0 1-.5.5h-5A.5.5 0 0 1 5 7v-.5s1.54-1.274 1.639-1.208M5 9.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5m0 2a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5" />
<path d="M3 0h10a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2v-1h1v1a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H3a1 1 0 0 0-1 1v1H1V2a2 2 0 0 1 2-2" />
<path d="M1 5v-.5a.5.5 0 0 1 1 0V5h.5a.5.5 0 0 1 0 1h-2a.5.5 0 0 1 0-1zm0 3v-.5a.5.5 0 0 1 1 0V8h.5a.5.5 0 0 1 0 1h-2a.5.5 0 0 1 0-1zm0 3v-.5a.5.5 0 0 1 1 0v.5h.5a.5.5 0 0 1 0 1h-2a.5.5 0 0 1 0-1z" />
</svg> Articles
</NavLink>
</li>
<li class="nav-item">
<NavLink class="nav-link" href="pokemonsleep">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-p-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M5.5 4.002V12h1.283V9.164h1.668C10.033 9.164 11 8.08 11 6.586c0-1.482-.955-2.584-2.538-2.584zm2.77 4.072c.893 0 1.419-.545 1.419-1.488s-.526-1.482-1.42-1.482H6.778v2.97z" />
</svg> Pokemon Sleep
</NavLink>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown link
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
</ul>
</div>
</nav>

View File

@ -0,0 +1,35 @@
<div class="navbar navbar-expand bg-primary border-0">
<div class="d-flex align-items-center mb-3 mb-md-0 me-md-auto link-light text-decoration-none px-3">
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="#FFFFFF" class="bi bi-arrow-through-heart" viewBox="0 0 16 16" 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 text-white">Kira Jiroux</span>
</div>
<ul class="navbar-nav">
<li class="nav-item">
<NavLink class="nav-link d-flex align-items-center" href="" Match="NavLinkMatch.All">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#FFFFFF" class="bi bi-house-heart-fill" viewBox="0 0 16 16">
<path d="M7.293 1.5a1 1 0 0 1 1.414 0L11 3.793V2.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v3.293l2.354 2.353a.5.5 0 0 1-.708.707L8 2.207 1.354 8.853a.5.5 0 1 1-.708-.707z" />
<path d="m14 9.293-6-6-6 6V13.5A1.5 1.5 0 0 0 3.5 15h9a1.5 1.5 0 0 0 1.5-1.5zm-6-.811c1.664-1.673 5.825 1.254 0 5.018-5.825-3.764-1.664-6.691 0-5.018" />
</svg> <span class="mx-2 mt-0 text-white">Home</span>
</NavLink>
</li>
<li>
<NavLink class="nav-link d-flex align-items-center" href="temperature-blanket">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#FFFFFF" class="bi bi-border-outer" viewBox="0 0 16 16">
<path d="M7.5 1.906v.938h1v-.938zm0 1.875v.938h1V3.78h-1zm0 1.875v.938h1v-.938zM1.906 8.5h.938v-1h-.938zm1.875 0h.938v-1H3.78v1zm1.875 0h.938v-1h-.938zm2.813 0v-.031H8.5V7.53h-.031V7.5H7.53v.031H7.5v.938h.031V8.5zm.937 0h.938v-1h-.938zm1.875 0h.938v-1h-.938zm1.875 0h.938v-1h-.938zM7.5 9.406v.938h1v-.938zm0 1.875v.938h1v-.938zm0 1.875v.938h1v-.938z" />
<path d="M0 0v16h16V0zm1 1h14v14H1z" />
</svg><span class="mx-2 mt-0 text-white">Crochet</span>
</NavLink>
</li>
<li>
<NavLink class="nav-link d-flex align-items-center" href="pokemonsleep">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#FFFFFF" class="bi bi-p-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M5.5 4.002V12h1.283V9.164h1.668C10.033 9.164 11 8.08 11 6.586c0-1.482-.955-2.584-2.538-2.584zm2.77 4.072c.893 0 1.419-.545 1.419-1.488s-.526-1.482-1.42-1.482H6.778v2.97z" />
</svg> <span class="mx-2 mt-0 text-white">Pokémon Sleep</span>
</NavLink>
</li>
</ul>
</div>

View File

@ -7,7 +7,7 @@
<PageTitle>Home</PageTitle> <PageTitle>Home</PageTitle>
<!-- View 1: Desktop View --> <!-- View 1: Desktop View -->
<div class="container d-none d-lg-none d-xl-block mt-3 pt-3 pb-5 ps-5 pe-5 "> <div class="container d-none d-lg-none d-xl-block mt-5 pt-3 pb-5 ps-5 pe-5 ">
<h1 class="fst-italic fw-light fs-1 font-monospace">Hello, World!</h1> <h1 class="fst-italic fw-light fs-1 font-monospace">Hello, World!</h1>
<!-- Start of Grid --> <!-- Start of Grid -->
@ -29,7 +29,7 @@
<div class="row"> <div class="row">
<!-- School Experience --> <!-- School Experience -->
<div class="col ps-0"> <div class="col-auto ps-0">
<div class="card rounded p-2 ps-3 pe-3 border border-1 border-primary"> <div class="card rounded p-2 ps-3 pe-3 border border-1 border-primary">
<p class="fs-6 fw-lighter card-subtitle p-0">September 2018 March 2022</p> <p class="fs-6 fw-lighter card-subtitle p-0">September 2018 March 2022</p>
<p class="fs-5 card-title m-0">B.S. in Computer Science</p> <p class="fs-5 card-title m-0">B.S. in Computer Science</p>
@ -73,7 +73,7 @@
</div> </div>
<!--Skills \ Languages--> <!--Skills \ Languages-->
<div class="col-auto p-0 "> <div class="col p-0 ">
<div class="bg-white rounded p-2 border border-1 border-primary" > <div class="bg-white rounded p-2 border border-1 border-primary" >
<div class="card-header"> <div class="card-header">
<label class="text-decoration-underline fw-semibold">Skills \ Languages</label> <label class="text-decoration-underline fw-semibold">Skills \ Languages</label>
@ -98,7 +98,7 @@
</div> </div>
<!-- Tools --> <!-- Tools -->
<div class="col-auto pe-0"> <div class="col pe-0">
<div class="bg-white rounded p-2 border border-1 border-primary"> <div class="bg-white rounded p-2 border border-1 border-primary">
<div class="card-header"> <div class="card-header">

View File

@ -1,18 +1,18 @@
@page "/pokemon-sleep/admincontrol" @page "/pokemonsleep/admincontrol"
<div class="w-100"> <div class="w-100">
<!-- <PokemonBackground PokemonImages="pokemonImageUrls" ShinyPokemonImages="pokemonShinyImageUrls" /> --> <!-- <PokemonBackground PokemonImages="pokemonImageUrls" ShinyPokemonImages="pokemonShinyImageUrls" /> -->
<PokemonNavMenu /> <PokemonHeader />
<hr class="mt-5" /> <hr class="mt-5" />
<!-- Add Pokemon (Wrap in Auth) --> <!-- Add Pokemon (Wrap in Auth) -->
<button class="btn btn-warning mx-1" style="border-radius: 50px 15px; max-width: 60px;"> <button class="btn btn-warning mx-1" style="border-radius: 50px 15px; max-width: 60px;">
<NavLink href="/pokemon-sleep/addmincontrol/add-new-pokemon"> <NavLink href="/pokemonsleep/addmincontrol/add-new-pokemon">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#FFF" class="bi bi-plus-circle-fill mb-1" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#FFF" class="bi bi-plus-circle-fill mb-1" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M8.5 4.5a.5.5 0 0 0-1 0v3h-3a.5.5 0 0 0 0 1h3v3a.5.5 0 0 0 1 0v-3h3a.5.5 0 0 0 0-1h-3z" /> <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M8.5 4.5a.5.5 0 0 0-1 0v3h-3a.5.5 0 0 0 0 1h3v3a.5.5 0 0 0 1 0v-3h3a.5.5 0 0 0 0-1h-3z" />
</svg> </svg>

View File

@ -1,4 +1,4 @@
@page "/pokemon-sleep/add-new-pokemon" @page "/pokemonsleep/add-new-pokemon"
@inject IPokemonService PokemonService @inject IPokemonService PokemonService
@inject NavigationManager Navigation @inject NavigationManager Navigation
@ -10,7 +10,7 @@
<PageTitle>Add New Pokémon</PageTitle> <PageTitle>Add New Pokémon</PageTitle>
<PokemonNavMenu /> <PokemonHeader />
@if (isSubmitting) @if (isSubmitting)
@ -19,14 +19,13 @@
} }
else else
{ {
<div class="container"> <div class="container mx-0 px-0">
<div class="row mt-3"> <div class="row mt-5">
<div class="d-flex justify-content-evenly p-0"> <div class="d-flex justify-content-evenly h-100 p-0">
<div class="mx-1 align-content-center"> <div class="mx-1 align-content-center">
<div class="addcard"> <div class="addcard">
<PokemonForm <PokemonAddForm
formUse="ADD"
OnPokemonReady="ReceivePokemon1" OnPokemonReady="ReceivePokemon1"
mostRecentForm=false mostRecentForm=false
/> />
@ -41,15 +40,13 @@ else
</div> </div>
} }
else if (pokemon2FormView && !pokemon3FormView) else if (pokemon2FormView && !pokemon3FormView)
{ {
<div class="mx-1 align-content-center"> <div class="mx-1 align-content-center">
<div class="addcard"> <div class="addcard">
<PokemonForm OnPokemonReady="ReceivePokemon2" <PokemonAddForm OnPokemonReady="ReceivePokemon2"
formUse="ADD" RemoveForm="TogglePokemon2FormView"
RemoveForm="TogglePokemon2FormView" mostRecentForm="@pokemon2FormView" />
mostRecentForm="@pokemon2FormView" />
</div> </div>
</div> </div>
<div class="mx-1 align-content-center"> <div class="mx-1 align-content-center">
@ -57,33 +54,29 @@ else
</div> </div>
} }
else if (!pokemon2FormView && pokemon3FormView) else if (!pokemon2FormView && pokemon3FormView)
{ {
<div class="mx-1 align-content-center"> <div class="mx-1 align-content-center">
<div class="addcard"> <div class="addcard">
<PokemonForm OnPokemonReady="ReceivePokemon2" <PokemonAddForm OnPokemonReady="ReceivePokemon2"
formUse="ADD" RemoveForm="TogglePokemon2FormView"
RemoveForm="TogglePokemon2FormView" mostRecentForm="@pokemon2FormView" />
mostRecentForm="@pokemon2FormView" />
</div> </div>
</div> </div>
<div class="mx-1 align-content-center"> <div class="mx-1 align-content-center">
<div class="addcard"> <div class="addcard">
<PokemonForm OnPokemonReady="ReceivePokemon3" <PokemonAddForm OnPokemonReady="ReceivePokemon3"
formUse="ADD" RemoveForm="TogglePokemon3FormView"
RemoveForm="TogglePokemon3FormView" mostRecentForm="@pokemon3FormView" />
mostRecentForm="@pokemon3FormView" />
</div> </div>
</div> </div>
} }
</div> </div>
</div> </div>
</div> </div>
<div class="d-flex justify-content-center">
<div class="d-flex justify-content-center mt-5">
<div class="btn-group"> <div class="btn-group">
<button @onclick="@HandleAdd" class="btn btn-primary rounded">Add Pokemon</button> <button @onclick="@HandleAdd" class="btn btn-primary rounded">Add Pokemon</button>
</div> </div>

View File

@ -25,35 +25,15 @@ namespace Portfolio.WebUI.Server.Components.Pages.Pokemon_Pages
TogglePokemon2FormView(); TogglePokemon2FormView();
} }
// Create up to 3 Pokemon
private Pokemon pokemon1 = new Pokemon
{
PokemonId = 0, // Or any default ID logic
PokemonName = string.Empty, // Required fields cannot be null
PokemonType = string.Empty,
SleepType = string.Empty,
Speciality = string.Empty,
IsVariation = false
};
private Pokemon pokemon2 = new Pokemon
{
PokemonId = 0, // Or any default ID logic
PokemonName = string.Empty, // Required fields cannot be null
PokemonType = string.Empty,
SleepType = string.Empty,
Speciality = string.Empty,
IsVariation = false
};
private Pokemon pokemon3 = new Pokemon
{
PokemonId = 0, // Or any default ID logic
PokemonName = string.Empty, // Required fields cannot be null
PokemonType = string.Empty,
SleepType = string.Empty,
Speciality = string.Empty,
IsVariation = false
};
private Pokemon pokemon1, pokemon2, pokemon3 = new Pokemon
{
PokemonId = 0, // Or any default ID logic
PokemonName = string.Empty, // Required fields cannot be null
SleepType = string.Empty,
Speciality = string.Empty,
IsVariation = false
};
private bool isSubmitting = false; private bool isSubmitting = false;
private bool ToggleVariationName { get; set; } private bool ToggleVariationName { get; set; }
@ -62,7 +42,68 @@ namespace Portfolio.WebUI.Server.Components.Pages.Pokemon_Pages
{ {
this.ToggleVariationName = true; this.ToggleVariationName = true;
} }
private bool IsComplete(Pokemon NewPokemon) =>
NewPokemon.PokemonId > 0 &&
!string.IsNullOrWhiteSpace(NewPokemon.PokemonName) &&
!string.IsNullOrWhiteSpace(NewPokemon.PokemonType) &&
!string.IsNullOrWhiteSpace(NewPokemon.SleepType) &&
!string.IsNullOrWhiteSpace(NewPokemon.Speciality) &&
(!NewPokemon.IsVariation || !string.IsNullOrWhiteSpace(NewPokemon.VariationName));
private async Task HandleAdd()
{
/*
Okay there are three versions of submits which need to be checked
1. Single submit, only one, if both pokemon#FormView is false
2. 2 Submit, if pokemon2FormView is true
3. 3 Submit, if pokemon3FormView is true
*/
if (!pokemon2FormView && !pokemon3FormView)
{
if(IsComplete(pokemon1))
{
await HandleSubmit(pokemon1);
Navigation.NavigateTo("/pokemon");
}
}
else if (pokemon2FormView)
{
if (IsComplete(pokemon1) && IsComplete(pokemon2))
{
await HandleSubmit(pokemon1);
await HandleSubmit(pokemon2);
Navigation.NavigateTo("/pokemon");
}
}
else if (pokemon3FormView)
{
if (IsComplete(pokemon1) && IsComplete(pokemon2) && IsComplete(pokemon3))
{
await HandleSubmit(pokemon1);
await HandleSubmit(pokemon2);
await HandleSubmit(pokemon3);
Navigation.NavigateTo("/pokemon");
}
}
}
private async Task HandleSubmit(Pokemon NewPokemon)
{
isSubmitting = true;
await PokemonService.AddPokemonAsync(NewPokemon);
isSubmitting = false;
}
protected void Cancel(MouseEventArgs e)
{
Console.WriteLine("Testing in Cancel");
Navigation.NavigateTo("/pokemon");
}
private async Task ReceivePokemon1(Pokemon p) private async Task ReceivePokemon1(Pokemon p)
{ {
@ -99,67 +140,6 @@ namespace Portfolio.WebUI.Server.Components.Pages.Pokemon_Pages
// Browser console // Browser console
await JS.InvokeVoidAsync("console.log", "Pokemon 3:", pokemon3); await JS.InvokeVoidAsync("console.log", "Pokemon 3:", pokemon3);
} }
private bool IsComplete(Pokemon NewPokemon) =>
NewPokemon.PokemonId > 0 &&
!string.IsNullOrWhiteSpace(NewPokemon.PokemonName) &&
!string.IsNullOrWhiteSpace(NewPokemon.PokemonType) &&
!string.IsNullOrWhiteSpace(NewPokemon.SleepType) &&
!string.IsNullOrWhiteSpace(NewPokemon.Speciality) &&
(!NewPokemon.IsVariation || !string.IsNullOrWhiteSpace(NewPokemon.VariationName));
private async Task HandleAdd()
{
/*
Okay there are three versions of submits which need to be checked
1. Single submit, only one, if both pokemon#FormView is false
2. 2 Submit, if pokemon2FormView is true
3. 3 Submit, if pokemon3FormView is true
*/
if (!pokemon2FormView && !pokemon3FormView)
{
//if(IsComplete(pokemon1))
//{
await HandleSubmit(pokemon1);
Navigation.NavigateTo("/pokemon-sleep/pokemon");
//}
}
else if (pokemon2FormView)
{
//if (IsComplete(pokemon1) && IsComplete(pokemon2))
//{
await HandleSubmit(pokemon1);
await HandleSubmit(pokemon2);
Navigation.NavigateTo("/pokemon-sleep/pokemon");
// }
}
else if (pokemon3FormView)
{
//if (IsComplete(pokemon1) && IsComplete(pokemon2) && IsComplete(pokemon3))
//{
await HandleSubmit(pokemon1);
await HandleSubmit(pokemon2);
await HandleSubmit(pokemon3);
Navigation.NavigateTo("/pokemon-sleep/pokemon");
//}
}
}
private async Task HandleSubmit(Pokemon NewPokemon)
{
isSubmitting = true;
await PokemonService.AddPokemonAsync(NewPokemon);
isSubmitting = false;
}
protected void Cancel(MouseEventArgs e)
{
Console.WriteLine("Testing in Cancel");
Navigation.NavigateTo("/pokemon-sleep/pokemon");
}
} }
} }

View File

@ -1,5 +1,10 @@
.addcard { .addcard {
width: 100%; width: 100%;
max-width: 25rem; max-width: 30rem;
flex: 0 0 auto; /* prevent flex shrink/grow */
display: flex;
justify-content: center;
align-items: center;
padding: 0.5rem;
} }

View File

@ -1,41 +1,133 @@
@page "/pokemon-sleep/edit-pokemon/{id:int}" @page "/pokemonsleep/edit/{id:int}"
@inject IPokemonService PokemonService @inject IPokemonService PokemonService
@inject NavigationManager Navigation @inject NavigationManager Navigation
@inject IJSRuntime JS @inject IJSRuntime JSRuntime
@attribute [StreamRendering] @attribute [StreamRendering]
@rendermode InteractiveServer @rendermode InteractiveServer
<PageTitle>Edit Pokémon</PageTitle> <PageTitle>Edit Pokémon</PageTitle>
<PokemonNavMenu /> <PokemonHeader />
@if (pokemon == null) @if (pokemon == null)
{ {
<Loading /> <p><em>Loading...</em></p>
} }
else else
{ {
<!-- Total Componenet-->
<div class="w-50 mt-3 m-auto bg-info edit-container">
<div class="container mt-5 w-50 mb-5"> <!-- Header -->
<div class="row d-flex flex-row mb-0 justify-content-center"> <div class="card-header bg-secondary ml-0 py-3 w-100 ">
<div class="w-50"> <div class="row">
<div class="editcard"> <div class="col-12 text-center">
<PokemonForm <h2 class="text-info">Edit Pokémon</h2>
formUse="EDIT"
OnPokemonReady="ReceivePokemon"
RemoveForm="Cancel"
mostRecentForm=true
PokemonToEdit="pokemon"
/>
</div> </div>
</div> </div>
</div> </div>
</div>
<div class="d-flex justify-content-center"> <!-- Body -->
<div class="btn-group"> <div class="p-3 w-100 flex-column ">
<button @onclick="@HandleSubmit" class="btn btn-primary rounded">Edit Pokemon</button> <EditForm class="col mb-3" Model="pokemon" OnValidSubmit="HandleSubmit">
<DataAnnotationsValidator />
<!-- Dex Number and Name -->
<div class="row ">
<div class="col-sm-3 input-group mb-3">
<span for="PokemonId" class="input-group-text">#</span>
<InputNumber min="0" id="PokemonId" @bind-Value="pokemon.PokemonId" class="form-control" required disabled />
<InputText id="PokemonName" @bind-Value="pokemon.PokemonName" class="form-control w-75" required />
</div>
</div>
<!-- Pokemon Type, Sleep Type, and Speciality -->
<div class="row">
<!-- Pokemon Type -->
<div class="col mb-3 m-auto">
<label for="PokemonType" class="form-label">Pokemon Type</label>
<InputSelect id="PokemonType" @bind-Value="pokemon.PokemonType" class="form-select">
<option dsabled value="">Select Type</option>
<option value="Grass">Grass</option>
<option value="Fire">Fire</option>
<option value="Water">Water</option>
<option value="Normal">Normal</option>
<option value="Flying">Flying</option>
<option value="Bug">Bug</option>
<option value="Poison">Poison</option>
<option value="Electric">Electric</option>
<option value="Ground">Ground</option>
<option value="Rock">Rock</option>
<option value="Ice">Ice</option>
<option value="Steel">Steel</option>
<option value="Fighting">Fighting</option>
<option value="Psychic">Psychic</option>
<option value="Dark">Dark</option>
<option value="Fairy">Fairy</option>
<option value="Ghost">Ghost</option>
<option value="Dragon">Dragon</option>
</InputSelect>
</div>
<!-- Sleep Type -->
<div class="col mb-3 m-auto">
<label for="SleepType" class="form-label">Sleep Type</label>
<InputSelect id="SleepType" @bind-Value="pokemon.SleepType" class="form-select">
<option value="Dozing">Dozing</option>
<option value="Snoozing">Snoozing</option>
<option value="Slumbering">Slumbering</option>
</InputSelect>
</div>
<!-- Speciality-->
<div class="col mb-3 m-auto">
<label for="Speciality" class="form-label">Specialty</label>
<InputSelect id="Speciality" @bind-Value="pokemon.Speciality" class="form-select">
<option value="Berries">Berries</option>
<option value="Ingredients">Ingredients</option>
<option value="Skills">Skills</option>
</InputSelect>
</div>
</div>
<!-- Variation Check -->
<div class="row">
<div class="input-group mb-3">
<!-- Variation Check -->
<div class=" d-inline-flex">
<InputCheckbox id="IsVariation" @bind-Value="pokemon.IsVariation" @onclick="@Toggle" class="form-check-input checkbox-styling p-3 mt-1" />
<span for="IsVariation" class="input-group-text m-1">Variation?</span>
</div>
<!-- Variation Region Input -->
<div class="w-75 mx-2 mt-1">
<InputText placeholder="What Variant? (Alolan, Paldean)" hidden="@HideLabel" id="VariationName" @bind-Value="pokemon.VariationName" class="form-control" />
</div>
</div>
</div>
<!-- Image URL Input -->
<div class="row mb-3 m-auto">
<label for="ImageUrl" class="form-label">Base Image URL</label>
<InputText id="ImageUrl" @bind-Value="pokemon.PokemonImageUrl" class="form-control" />
</div>
<!-- Shiny Image URL Input -->
<div class="row mb-3 m-auto">
<label for="ImageUrl" class="form-label">Shiny Image URL</label>
<InputText id="ImageUrl" @bind-Value="pokemon.PokemonShinyImageUrl" class="form-control" />
</div>
<!-- Flavor Text Input -->
<div class="row mb-3 m-auto">
<label for="FlavorText" class="form-label">Flavor Text</label>
<InputText id="FlavorText" @bind-Value="pokemon.FlavorText" class="form-control" />
</div>
<!-- Form Buttons -->
<div class="d-flex justify-content-between">
<button type="button" class="btn btn-secondary mb-3" @onclick="Cancel">Cancel</button>
<button type="submit" class="btn btn-primary mb-3">Save Changes</button>
</div>
</EditForm>
</div> </div>
</div> </div>
} }

View File

@ -14,28 +14,16 @@ namespace Portfolio.WebUI.Server.Components.Pages.Pokemon_Pages
pokemon = await PokemonService.GetPokemonByIdAsync(Id); pokemon = await PokemonService.GetPokemonByIdAsync(Id);
} }
private async Task ReceivePokemon(Pokemon p)
{
// Save received pokemon as Pokemon 1
pokemon = p;
// Server console (Blazor Server)
Console.WriteLine($"[Pokemon 1] #{pokemon.PokemonId} {pokemon.PokemonName} | {pokemon.PokemonType} | {pokemon.SleepType} | {pokemon.Speciality} | Var:{pokemon.IsVariation} {pokemon.VariationName}");
// Browser console
await JS.InvokeVoidAsync("console.log", "Pokemon 1:", pokemon);
}
private async Task HandleSubmit() private async Task HandleSubmit()
{ {
await PokemonService.UpdatePokemonAsync(pokemon); await PokemonService.UpdatePokemonAsync(pokemon);
//Navigation.NavigateTo("/pokemonsleep"); //Navigation.NavigateTo("/pokemonsleep");
await JS.InvokeVoidAsync("history.back"); await JSRuntime.InvokeVoidAsync("history.back");
} }
private async void Cancel() private async void Cancel()
{ {
await JS.InvokeVoidAsync("history.back"); await JSRuntime.InvokeVoidAsync("history.back");
} }

View File

@ -5,8 +5,3 @@
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(255,255, 255, 0.19); 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; border-radius: 15px;
} }
.editcard {
width: 100%;
max-width: 30rem;
}

View File

@ -1,4 +1,4 @@
@page "/pokemon-sleep/pokemon/{id:int}" @page "/pokemon/{id:int}"
@inject IPokemonService PokemonService @inject IPokemonService PokemonService
@inject NavigationManager Navigation @inject NavigationManager Navigation
@ -6,7 +6,7 @@
@rendermode InteractiveServer @rendermode InteractiveServer
<PokemonNavMenu /> <PokemonHeader />
@ -20,7 +20,7 @@ else
<!-- Total Componenet--> <!-- Total Componenet-->
<div class="container"> <div class="container">
<div class="w-75 lg row mt-5 m-auto"> <div class="w-75 row mt-4 m-auto">
<!-- Previous Pokemon Button --> <!-- Previous Pokemon Button -->
<div class="col-auto"> <div class="col-auto">

View File

@ -39,13 +39,13 @@ namespace Portfolio.WebUI.Server.Components.Pages.Pokemon_Pages
private void NavigateToNext() private void NavigateToNext()
{ {
if (_nextPokemonId.HasValue) if (_nextPokemonId.HasValue)
Navigation.NavigateTo($"/pokemon-sleep/pokemon/{_nextPokemonId.Value}"); Navigation.NavigateTo($"/pokemon/{_nextPokemonId.Value}");
} }
private void NavigateToPrevious() private void NavigateToPrevious()
{ {
if (_previousPokemonId.HasValue) if (_previousPokemonId.HasValue)
Navigation.NavigateTo($"/pokemon-sleep/pokemon/{_previousPokemonId.Value}"); Navigation.NavigateTo($"/pokemon/{_previousPokemonId.Value}");
} }
} }

View File

@ -1,4 +1,4 @@
@page "/pokemon-sleep/rate-pokemon" @page "/rate-pokemon"
@inject IPokemonService PokemonService @inject IPokemonService PokemonService
@inject IPokemonNatureService PokemonNatureService @inject IPokemonNatureService PokemonNatureService
@ -12,9 +12,9 @@
<PageTitle>Rate Pokémon</PageTitle> <PageTitle>Rate Pokémon</PageTitle>
<PokemonNavMenu /> <PokemonHeader />
<div class="container mt-4"> <div class="mt-4">
<div class="row"> <div class="row">
@if (PokemonList == null || NatureList == null || SubskillList == null) @if (PokemonList == null || NatureList == null || SubskillList == null)
{ {
@ -60,4 +60,5 @@
} }
</div> </div>
<hr class="mt-5"/>
</div> </div>

View File

@ -1,4 +1,4 @@
@page "/pokemon-sleep" @page "/pokemonsleep"
@attribute [StreamRendering] @attribute [StreamRendering]
@ -8,110 +8,43 @@
<PageTitle>Pokémon Sleep</PageTitle> <PageTitle>Pokémon Sleep</PageTitle>
<!-- <PokemonBackground PokemonImages="pokemonImageUrls" ShinyPokemonImages="pokemonShinyImageUrls" /> --> <!-- <PokemonBackground PokemonImages="pokemonImageUrls" ShinyPokemonImages="pokemonShinyImageUrls" /> -->
<PokemonNavMenu /> <PokemonHeader />
<!-- Large --> <!-- Card -->
<div class="container d-none d-lg-block d-md-none card shadow-sm border-0 p-3 pb-4 mt-5 w-50 mb-5 bg-white rounded "> <div class="container card shadow-sm border-0 p-3 pb-4 mt-4 m-auto w-75 mb-5 bg-white">
<!-- Top Row--> <!-- Top Row-->
<div class="row d-flex flex-row px-3 mb-0 pb-0"> <div class="row d-flex flex-row">
<!-- Image side --> <!-- Image side -->
<div class="col-4 p-0"> <div class="col-5 border-0 ">
<img class="shadow-sm m-auto img-fluid rounded" src="images/Pokemon_Sleep_ID.jpg" /> <img class="shadow-sm w-100 m-auto img-fluid" src="images/Pokemon_Sleep_ID.jpg" />
</div> </div>
<!-- Text side --> <!-- Text side -->
<div class="col w-50 p-3 ps-4 pb-0"> <div class="col w-50 p-3">
<div class="row"> <p class="fw-bold fst-italic fs-3">Pokémon Sleep? Really?</p>
<p class="fw-bold fst-italic fs-3 mb-0">Pokémon Sleep? Really?</p> <p class="fw-normal fs-6 text-start">
<p class="fw-normal fs-6 font-monospace"> Yes, really! Pokémon Sleep has become a fun addition to my day since it's release.
Yes, really! Pokémon Sleep has become a fun addition to my day since it's release. Scan the QR code in the Pokémon Sleep app to send me a friend request! </p>
</p> <p class="fw-bold fst-italic fs-3">But what do you even do?</p>
</div> <p class="fw-normal fs-6 text-start">
<div class="row"> That's harder to explain. See, it isn't as much a game, as it is a gamified sleep tracker. But it's fun to collect the Pokémon and gather their berries and ingredients and create silly little Pokémon-themed foods. Plus, it encourages me to try to get to bed in a timely manner; though, if I'm honest, I definitely put my Pokémon to bed ahead of when I do.
<p class="fw-bold fst-italic fs-3 mb-0">But what do you even do?</p> </p>
<p class="fw-normal fs-6 font-monospace">
That's harder to explain. See, it isn't as much a game, as it is a gamified sleep tracker. But it's fun to collect the Pokémon and gather their berries and ingredients and create silly little Pokémon-themed foods. Plus, it encourages me to try to get to bed in a timely manner; though, if I'm honest, I definitely put my Pokémon to bed ahead of when I do.
</p>
</div>
</div> </div>
</div> </div>
<!-- Second Row --> <!-- Second Row -->
<div class="row mt-0 pt-0"> <div class="row mt-3">
<p class="fw-bold fst-italic fs-3 mb-0">Okay, but why a whole section dedicated to Pokémon Sleep?</p> <p class="fw-bold fst-italic fs-3">Okay, but why a whole section dedicated to Pokémon Sleep?</p>
<p class="fw-normal fs-6 font-monospace">
Well, as it is in any Pokémon game, Natures (and in this case Subskills) matter, amongst other things. This was designed as a helpful tool in assessing new Pokémon acquired from Sleep Research.
</p>
</div>
<!-- Button Row-->
<div class="row d-flex justify-content-evenly mt-3 ">
<button class="btn btn-info rounded-4 d-flex justify-content-center" style="width:12rem;">
<NavLink class="nav-link d-flex align-items-center" href="/pokemon-sleep/pokemon">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-table" viewBox="0 0 16 16">
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm15 2h-4v3h4zm0 4h-4v3h4zm0 4h-4v3h3a1 1 0 0 0 1-1zm-5 3v-3H6v3zm-5 0v-3H1v2a1 1 0 0 0 1 1zm-4-4h4V8H1zm0-4h4V4H1zm5-3v3h4V4zm4 4H6v3h4z" />
</svg>
<span class="ps-1 text-white">Available Pokémon</span>
</NavLink>
</button>
<button class="btn btn-success rounded-4 d-flex justify-content-center" style="width:12rem;">
<NavLink class="nav-link d-flex align-items-center" href="/pokemon-sleep/rate-pokemon">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#FFF" class="bi bi-award-fill" viewBox="0 0 16 16">
<path d="m8 0 1.669.864 1.858.282.842 1.68 1.337 1.32L13.4 6l.306 1.854-1.337 1.32-.842 1.68-1.858.282L8 12l-1.669-.864-1.858-.282-.842-1.68-1.337-1.32L2.6 6l-.306-1.854 1.337-1.32.842-1.68L6.331.864z" />
<path d="M4 11.794V16l4-1 4 1v-4.206l-2.018.306L8 13.126 6.018 12.1z" />
</svg>
<span class="ps-1 text-white">Rate Pokémon</span>
</NavLink>
</button>
</div>
</div>
<!-- Medium -->
<div class="container d-none d-lg-none d-md-block mt-3">
<!-- Top Row-->
<div class="row d-flex flex-row justify-content-center">
<!-- Top side -->
<div class="col p-0" >
<img class="shadow-sm m-auto img-fluid rounded" src="images/Pokemon_Sleep_ID.jpg" />
</div>
<div class="col text-wrap p-1 ps-3" >
<div class="row d-flex flex-row justify-content-center">
<!-- Bottom side -->
<p class="fw-bold fst-italic fs-3 mb-1">Pokémon Sleep? Really?</p>
<p class="fw-normal fs-6 text-start">
Yes, really! Pokémon Sleep has become a fun addition to my day since it's release. Scan the QR code in the Pokémon Sleep app to send me a friend request!
</p>
</div>
<p class="fw-bold fst-italic fs-3 mb-0">But what do you even do?</p>
<div class="row d-flex flex-row justify-content-center">
<!-- Bottom side -->
<p class="fw-normal fs-6 text-start">
That's harder to explain. See, it isn't as much a game, as it is a gamified sleep tracker. But it's fun to collect the Pokémon and gather their berries and ingredients and create silly little Pokémon-themed foods. Plus, it encourages me to try to get to bed in a timely manner; though, if I'm honest, I definitely put my Pokémon to bed ahead of when I do.
</p>
</div>
</div>
</div>
<!-- Second Row -->
<div class="row d-flex flex-row justify-content-center p-1">
<p class="fw-bold fst-italic fs-3 mb-0">Okay, but why a whole section dedicated to Pokémon Sleep?</p>
<p class="fw-normal fs-6 text-start"> <p class="fw-normal fs-6 text-start">
Well, as it is in any Pokémon game, Natures (and in this case Subskills) matter, amongst other things. This was designed as a helpful tool in assessing new Pokémon acquired from Sleep Research. Well, as it is in any Pokémon game, Natures (and in this case Subskills) matter, amongst other things. This was designed as a helpful tool in assessing new Pokémon acquired from Sleep Research.
</p> </p>
</div> </div>
<!-- Button Row--> <!-- Button Row-->
<div class="row d-flex justify-content-evenly mt-3 "> <div class="d-flex justify-content-evenly mt-4 ">
<button class="btn btn-info rounded-4 d-flex justify-content-center" style="width:12rem;"> <button class="btn btn-info rounded-4 d-flex justify-content-center" style="width:12rem;">
<NavLink class="nav-link d-flex align-items-center" href="/pokemon-sleep/pokemon"> <NavLink class="nav-link d-flex align-items-center" href="/pokemon">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-table" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-table" viewBox="0 0 16 16">
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm15 2h-4v3h4zm0 4h-4v3h4zm0 4h-4v3h3a1 1 0 0 0 1-1zm-5 3v-3H6v3zm-5 0v-3H1v2a1 1 0 0 0 1 1zm-4-4h4V8H1zm0-4h4V4H1zm5-3v3h4V4zm4 4H6v3h4z" /> <path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm15 2h-4v3h4zm0 4h-4v3h4zm0 4h-4v3h3a1 1 0 0 0 1-1zm-5 3v-3H6v3zm-5 0v-3H1v2a1 1 0 0 0 1 1zm-4-4h4V8H1zm0-4h4V4H1zm5-3v3h4V4zm4 4H6v3h4z" />
</svg> </svg>
@ -120,7 +53,7 @@
</button> </button>
<button class="btn btn-success rounded-4 d-flex justify-content-center" style="width:12rem;"> <button class="btn btn-success rounded-4 d-flex justify-content-center" style="width:12rem;">
<NavLink class="nav-link d-flex align-items-center" href="/pokemon-sleep/rate-pokemon"> <NavLink class="nav-link d-flex align-items-center" href="/rate-pokemon">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#FFF" class="bi bi-award-fill" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#FFF" class="bi bi-award-fill" viewBox="0 0 16 16">
<path d="m8 0 1.669.864 1.858.282.842 1.68 1.337 1.32L13.4 6l.306 1.854-1.337 1.32-.842 1.68-1.858.282L8 12l-1.669-.864-1.858-.282-.842-1.68-1.337-1.32L2.6 6l-.306-1.854 1.337-1.32.842-1.68L6.331.864z" /> <path d="m8 0 1.669.864 1.858.282.842 1.68 1.337 1.32L13.4 6l.306 1.854-1.337 1.32-.842 1.68-1.858.282L8 12l-1.669-.864-1.858-.282-.842-1.68-1.337-1.32L2.6 6l-.306-1.854 1.337-1.32.842-1.68L6.331.864z" />
<path d="M4 11.794V16l4-1 4 1v-4.206l-2.018.306L8 13.126 6.018 12.1z" /> <path d="M4 11.794V16l4-1 4 1v-4.206l-2.018.306L8 13.126 6.018 12.1z" />
@ -130,56 +63,5 @@
</button> </button>
</div> </div>
</div>
<!-- Small -->
<div class="container d-inline d-lg-none d-md-none mt-3 mx-auto">
<!-- Image-->
<div class="row d-flex flex-row justify-content-center">
<!-- Top side -->
<div class="col-6">
<img class="img-fluid rounded p-0" src="images/Pokemon_Sleep_ID.jpg" />
</div>
</div>
<div class="row mt-2 w-75 mx-auto p-1 ps-3">
<p class="fw-bold fst-italic fs-4 mb-1">Pokémon Sleep? Really?</p>
<p class="fw-normal fs-6 font-monospace">
Yes, really! Pokémon Sleep has become a fun addition to my day since it's release. Scan the QR code in the Pokémon Sleep app to send me a friend request!
</p>
<p class="fw-bold fst-italic fs-4 mb-0">But what do you even do?</p>
<p class="fw-normal fs-6 font-monospace">
That's harder to explain. See, it isn't as much a game, as it is a gamified sleep tracker. But it's fun to collect the Pokémon and gather their berries and ingredients and create silly little Pokémon-themed foods. Plus, it encourages me to try to get to bed in a timely manner; though, if I'm honest, I definitely put my Pokémon to bed ahead of when I do.
</p>
<p class="fw-bold fst-italic fs-4 mb-0">Okay, but why a whole section dedicated to Pokémon Sleep?</p>
<p class="fw-normal fs-6 font-monospace">
Well, as it is in any Pokémon game, Natures (and in this case Subskills) matter, amongst other things. This was designed as a helpful tool in assessing new Pokémon acquired from Sleep Research.
</p>
</div>
<!-- Button Row-->
<div class="row d-flex justify-content-evenly mt-2">
<button class="btn btn-info rounded-4 d-flex justify-content-center" style="width:12rem;">
<NavLink class="nav-link d-flex align-items-center" href="/pokemon-sleep/pokemon">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-table" viewBox="0 0 16 16">
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm15 2h-4v3h4zm0 4h-4v3h4zm0 4h-4v3h3a1 1 0 0 0 1-1zm-5 3v-3H6v3zm-5 0v-3H1v2a1 1 0 0 0 1 1zm-4-4h4V8H1zm0-4h4V4H1zm5-3v3h4V4zm4 4H6v3h4z" />
</svg>
<span class="ps-1 text-white">Available Pokémon</span>
</NavLink>
</button>
<button class="btn btn-success rounded-4 d-flex justify-content-center" style="width:12rem;">
<NavLink class="nav-link d-flex align-items-center" href="/pokemon-sleep/rate-pokemon">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#FFF" class="bi bi-award-fill" viewBox="0 0 16 16">
<path d="m8 0 1.669.864 1.858.282.842 1.68 1.337 1.32L13.4 6l.306 1.854-1.337 1.32-.842 1.68-1.858.282L8 12l-1.669-.864-1.858-.282-.842-1.68-1.337-1.32L2.6 6l-.306-1.854 1.337-1.32.842-1.68L6.331.864z" />
<path d="M4 11.794V16l4-1 4 1v-4.206l-2.018.306L8 13.126 6.018 12.1z" />
</svg>
<span class="ps-1 text-white">Rate Pokémon</span>
</NavLink>
</button>
</div>
</div> </div>

View File

@ -1,4 +1,4 @@
@page "/pokemon-sleep/pokemon" @page "/pokemon"
@inject IPokemonService PokemonService @inject IPokemonService PokemonService
@ -10,13 +10,14 @@
<PageTitle>Pokémon Sleep</PageTitle> <PageTitle>Pokémon Sleep</PageTitle>
<!-- <PokemonBackground PokemonImages="pokemonImageUrls" ShinyPokemonImages="pokemonShinyImageUrls" /> --> <div class="w-100">
<!-- <PokemonBackground PokemonImages="pokemonImageUrls" ShinyPokemonImages="pokemonShinyImageUrls" /> -->
<PokemonNavMenu />
<PokemonTable AllPokemon="pokemons"/>
<PokemonHeader />
<PokemonTable AllPokemon="pokemons"/>
<hr class="mt-5" />
</div>

View File

@ -1,98 +0,0 @@
[
{
"name": "Large Leek",
"description": "Whether this is the kind of vegetable stalk that Farfetch'd like is unknown.",
"imageURL": "https://www.serebii.net/pokemonsleep/names/largeleek.png"
},
{
"name": "Tasty Mushroom",
"description": "A juicy mushroom with an abundance of umami flavor.",
"imageURL": "https://www.serebii.net/pokemonsleep/names/tastymushroom.png"
},
{
"name": "Fancy Egg",
"description": "A nutritious cooking name that goes well with all sorts of seasonings.",
"imageURL": "https://www.serebii.net/pokemonsleep/names/fancyegg.png"
},
{
"name": "Soft Potato",
"description": "Its mellow flavor makes both body and spirit feel warm and fuzzy.",
"imageURL": "https://www.serebii.net/pokemonsleep/names/softpotato.png"
},
{
"name": "Fancy Apple",
"description": "An apple chosen above others. It has spectacular form and a brilliant sheen.",
"imageURL": "https://www.serebii.net/pokemonsleep/names/fancyapple.png"
},
{
"name": "Fiery Herb",
"description": "The fiery taste of this bright-red herb will wake anyone right up.",
"imageURL": "https://www.serebii.net/pokemonsleep/names/fieryherb.png"
},
{
"name": "Bean Sausage",
"description": "A healthy sausage made from beans that Pok<6F>mon like to eat.",
"imageURL": "https://www.serebii.net/pokemonsleep/names/beansausage.png"
},
{
"name": "Moomoo Milk",
"description": "Highly nutritious milk. Pok<6F>mon that drink it become full of energy.",
"imageURL": "https://www.serebii.net/pokemonsleep/names/moomoomilk.png"
},
{
"name": "Honey",
"description": "A sweet honey collected by Pok<6F>mon.",
"imageURL": "https://www.serebii.net/pokemonsleep/names/honey.png"
},
{
"name": "Pure Oil",
"description": "All-purpose oil that can be used in any type of cuisine.",
"imageURL": "https://www.serebii.net/pokemonsleep/names/pureoil.png"
},
{
"name": "Warming Ginger",
"description": "Spicy ginger that warms the body better than any other name.",
"imageURL": "https://www.serebii.net/pokemonsleep/names/warmingginger.png"
},
{
"name": "Snoozy Tomato",
"description": "A bright-red tomato. Eat it and you'll sleep like a baby.",
"imageURL": "https://www.serebii.net/pokemonsleep/names/snoozytomato.png"
},
{
"name": "Soothing Cacao",
"description": "This cacao bean is time-consuming to process, but its soothing effects make the effort worthwhile.",
"imageURL": "https://www.serebii.net/pokemonsleep/names/soothingcacao.png"
},
{
"name": "Slowpoke Tail",
"description": "A very tasty tail of something. When it falls off, it grows back quickly.",
"imageURL": "https://www.serebii.net/pokemonsleep/names/slowpoketail.png"
},
{
"name": "Greengrass Soybeans",
"description": "This Greengrass Isle specialty is easy to process into foods that are great for training.",
"imageURL": "https://www.serebii.net/pokemonsleep/names/greengrasssoybeans.png"
},
{
"name": "Greengrass Corn",
"description": "This Greengrass Isle specialty can be eaten raw. It's remarkably sweet.",
"imageURL": "https://www.serebii.net/pokemonsleep/names/greengrasscorn.png"
},
{
"name": "Rousing Coffee",
"description": "You may have trouble sleeping if you drink too much of this. It may help make you feel more alert.",
"imageURL": "https://www.serebii.net/pokemonsleep/names/rousingcoffee.png"
},
{
"name": "Plump Pumpkin",
"description": "A big pumpkin packed full of pulp.",
"imageURL": "https://www.serebii.net/pokemonsleep/names/plumppumpkin.png"
},
{
"name": "Glossy Avocado",
"description": "The glossy green shine is a sign it' s freshly picked.",
"imageURL": "https://www.serebii.net/pokemonsleep/names/glossyavocado.png"
}
]

View File

@ -1,129 +0,0 @@
[
{
"type": "Grass",
"typeImageUrl": "https://www.serebii.net/pokemonsleep/pokemon/type/grass.png",
"berry": "Durin",
"berryDescription": "This Berry is tremendously bitter. Just one bite is enough to instantly stop hiccups.",
"berryImageURL": "https://www.serebii.net/pokemonsleep/berries/durinberry.png"
},
{
"type": "Fire",
"typeImageUrl": "https://www.serebii.net/pokemonsleep/pokemon/type/fire.png",
"berry": "Leppa",
"berryDescription": "It takes longer to grow than Berries such as Cheri. The smaller Berries taste better.",
"berryImageURL": "https://www.serebii.net/pokemonsleep/berries/leppaberry.png"
},
{
"type": "Water",
"typeImageUrl": "https://www.serebii.net/pokemonsleep/pokemon/type/water.png",
"berry": "Oran",
"berryDescription": "Nature's gifts came together as one in this Berry. It has a wondrous mix of flavors that spread in the mouth.",
"berryImageURL": "https://www.serebii.net/pokemonsleep/berries/oranberry.png"
},
{
"type": "Normal",
"typeImageUrl": "https://www.serebii.net/pokemonsleep/pokemon/type/normal.png",
"berry": "Persim",
"berryDaescription": "The more this Berry absorbs energy from sunlight, the more vividly colorful it grows.",
"berryImageURL": "https://www.serebii.net/pokemonsleep/berries/persimberry.png"
},
{
"type": "Flying",
"typeImageUrl": "https://www.serebii.net/pokemonsleep/pokemon/type/flying.png",
"berry": "Pamtre",
"berryDescription": "This Berry drifted from a faraway sea. It can now be cultivated even on this island.",
"berryImageURL": "https://www.serebii.net/pokemonsleep/berries/pamtreberry.png"
},
{
"type": "Bug",
"typeImageUrl": "https://www.serebii.net/pokemonsleep/pokemon/type/bug.png",
"berry": "Lum",
"berryDescription": "This Berry's gradual process of storing nutrients beneficial to Pok<6F>mon health causes it to mature slowly.",
"berryImageURL": "https://www.serebii.net/pokemonsleep/berries/lumberry.png"
},
{
"type": "Poison",
"typeImageUrl": "https://www.serebii.net/pokemonsleep/pokemon/type/poison.png",
"berry": "Chesto",
"berryDescription": "This Berry's thick skin and fruit are very tough and dry-tasting. However, every bit of it can be eaten.",
"berryImageURL": "https://www.serebii.net/pokemonsleep/berries/chestoberry.png"
},
{
"type": "Electric",
"typeImageUrl": "https://www.serebii.net/pokemonsleep/pokemon/type/electric.png",
"berry": "Grepa",
"berryDescription": "One bite of this very tender Berry fills the mouth with its sweet and tangy flavor.",
"berryImageURL": "https://www.serebii.net/pokemonsleep/berries/grepaberry.png"
},
{
"type": "Ground",
"typeImageUrl": "https://www.serebii.net/pokemonsleep/pokemon/type/ground.png",
"berry": "Figy",
"berryDescription": "This Berry is oddly shaped, appearing as if someone took a bite out of it. It's packed full of spicy substances.",
"berryImageURL": "https://www.serebii.net/pokemonsleep/berries/figyberry.png"
},
{
"type": "Rock",
"typeImageUrl": "https://www.serebii.net/pokemonsleep/pokemon/type/rock.png",
"berry": "Sitrus",
"berryDescription": "Sitrus came from the same family as Oran. It's larger and smoother- tasting than Oran.",
"berryImageURL": "https://www.serebii.net/pokemonsleep/berries/sitrusberry.png"
},
{
"type": "Ice",
"typeImageUrl": "https://www.serebii.net/pokemonsleep/pokemon/type/ice.png",
"berry": "Rawst",
"berryDescription": "If the leaves grow longer and curlier than average, this Berry will have a somewhat bitter taste.",
"berryImageURL": "https://www.serebii.net/pokemonsleep/berries/rawstberry.png"
},
{
"type": "Steel",
"typeImageUrl": "https://www.serebii.net/pokemonsleep/pokemon/type/steel.png",
"berry": "Belue",
"berryDescription": "This glossy and colorful Berry has a mouthwateringly delicious appearance. However, it's awfully sour.",
"berryImageURL": "https://www.serebii.net/pokemonsleep/berries/belueberry.png"
},
{
"type": "Fighting",
"typeImageUrl": "https://www.serebii.net/pokemonsleep/pokemon/type/fighting.png",
"berry": "Cheri",
"berryDescription": "This bright red Berry is very spicy and has a provocative flavor. It blooms with delicate, pretty flowers.",
"berryImageURL": "https://www.serebii.net/pokemonsleep/berries/cheriberry.png"
},
{
"type": "Psychic",
"typeImageUrl": "https://www.serebii.net/pokemonsleep/pokemon/type/psychic.png",
"berry": "Mago",
"berryDescription": "This Berry progressively curves as it grows. The curvier the Berry, the sweeter it tastes.",
"berryImageURL": "https://www.serebii.net/pokemonsleep/berries/magoberry.png"
},
{
"type": "Dark",
"typeImageUrl": "https://www.serebii.net/pokemonsleep/pokemon/type/dark.png",
"berry": "Wiki",
"berryDescription": "It's said that this Berry grew lumps to help Pok<6F>mon grip it, allowing propagation farther afield.",
"berryImageURL": "https://www.serebii.net/pokemonsleep/berries/wikiberry.png"
},
{
"type": "Fairy",
"typeImageUrl": "https://www.serebii.net/pokemonsleep/pokemon/type/fairy.png",
"berry": "Pecha",
"berryDescription": "Because of its hollow inside pocket, there isn't a lot to eat. What can be eaten is very sweet and delicious.",
"berryImageURL": "https://www.serebii.net/pokemonsleep/berries/pechaberry.png"
},
{
"type": "Ghost",
"typeImageUrl": "https://www.serebii.net/pokemonsleep/pokemon/type/ghost.png",
"berry": "Bluk",
"berryDescription": "Though this small, delicately skinned Berry is blue in color, it dyes the mouth black when eaten.",
"berryImageURL": "https://www.serebii.net/pokemonsleep/berries/blukberry.png"
},
{
"type": "Dragon",
"typeImageUrl": "https://www.serebii.net/pokemonsleep/pokemon/type/dragon.png",
"berry": "Yache",
"berryDescription": "This Berry has a refreshing flavor that strikes a good balance of dryness and sourness. It tastes better chilled.",
"berryImageURL": "https://www.serebii.net/pokemonsleep/berries/yacheberry.png"
}
]

View File

@ -8,7 +8,7 @@
"links": [ "links": [
{ {
"type": "internal", "type": "internal",
"url": "/temperature-blanket", "url": "/pokemonsleep",
"icon": "code" "icon": "code"
} }
] ]
@ -22,7 +22,7 @@
"links": [ "links": [
{ {
"type": "internal", "type": "internal",
"url": "/pokemon-sleep", "url": "/pokemonsleep",
"icon": "code" "icon": "code"
} }
] ]