support for recipe ingredient associations
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
using Amazon.S3;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Unbinder.Services;
|
using Unbinder.Services;
|
||||||
|
|
||||||
namespace Unbinder.Controllers
|
namespace Unbinder.Controllers
|
||||||
@@ -19,31 +18,13 @@ namespace Unbinder.Controllers
|
|||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
|
|
||||||
string keys = "";
|
|
||||||
foreach (var entry in response.S3Objects)
|
|
||||||
{
|
|
||||||
keys += entry.Key + ", ";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keys != "") logger.Log(LogLevel.Information, $"Found keys: {keys ?? "(none)"}");
|
|
||||||
return View(response.S3Objects);
|
return View(response.S3Objects);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
HandleError(ex, logger);
|
logger.Log(LogLevel.Error, ex.Message);
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void HandleError(Exception ex, ILogger logger)
|
|
||||||
{
|
|
||||||
if (ex is AmazonS3Exception s3Exception)
|
|
||||||
{
|
|
||||||
logger.Log(LogLevel.Warning, s3Exception.ErrorCode);
|
|
||||||
logger.Log(LogLevel.Warning, s3Exception.Message);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
logger.Log(LogLevel.Error, ex.Message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,12 +17,14 @@ namespace Unbinder.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Route("[controller]/{id}")]
|
[Route("[controller]/{id}")]
|
||||||
public IActionResult RecipeId(int id)
|
public IActionResult RecipeId(int id, bool editMode = false)
|
||||||
{
|
{
|
||||||
var result = _recipeRepository.GetById(id);
|
var result = _recipeRepository.GetById(id);
|
||||||
|
|
||||||
Console.WriteLine(result == null ? "No result found" : result);
|
Console.WriteLine(result == null ? "No result found" : result);
|
||||||
|
|
||||||
|
ViewBag.EditMode = editMode;
|
||||||
|
|
||||||
return result == null
|
return result == null
|
||||||
? NotFound()
|
? NotFound()
|
||||||
: View(result);
|
: View(result);
|
||||||
|
|||||||
15
Unbinder/Controllers/RecipeIngredientController.cs
Normal file
15
Unbinder/Controllers/RecipeIngredientController.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Unbinder.Repositories;
|
||||||
|
|
||||||
|
namespace Unbinder.Controllers
|
||||||
|
{
|
||||||
|
public class RecipeIngredientController(IRecipeIngredientRepository repository) : Controller
|
||||||
|
{
|
||||||
|
private readonly IRecipeIngredientRepository _repository = repository;
|
||||||
|
|
||||||
|
public IActionResult Index()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using Unbinder.Models;
|
using Unbinder.Models;
|
||||||
|
using Unbinder.Repositories;
|
||||||
|
|
||||||
namespace Unbinder.DB
|
namespace Unbinder.DB
|
||||||
{
|
{
|
||||||
@@ -6,32 +7,70 @@ namespace Unbinder.DB
|
|||||||
{
|
{
|
||||||
public static int Seed(IApplicationBuilder applicationBuilder)
|
public static int Seed(IApplicationBuilder applicationBuilder)
|
||||||
{
|
{
|
||||||
UnbinderDbContext context = applicationBuilder.ApplicationServices.CreateScope()
|
int totalInsertCount = 0;
|
||||||
|
|
||||||
|
using UnbinderDbContext context = applicationBuilder.ApplicationServices.CreateScope()
|
||||||
.ServiceProvider.GetRequiredService<UnbinderDbContext>();
|
.ServiceProvider.GetRequiredService<UnbinderDbContext>();
|
||||||
|
|
||||||
Console.WriteLine("Connection established, preparing to seed database...");
|
Console.WriteLine("Connection established, preparing to seed database...");
|
||||||
|
|
||||||
if (!context.Recipes.Any())
|
// if records are not already seeded, do an initial insert into DB
|
||||||
{
|
WriteIfNotInitialized(context.Recipes, SeedData.InitialRecipes, context.Recipes.AddRange);
|
||||||
context.Recipes.AddRange(SeedData.InitialRecipes);
|
WriteIfNotInitialized(context.Ingredients, SeedData.InitialIngredients, context.Ingredients.AddRange);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.WriteLine("Recipes already exist in the database");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!context.Ingredients.Any())
|
|
||||||
{
|
|
||||||
context.Ingredients.AddRange(SeedData.PadThaiIngredients);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.WriteLine("Ingredients already exist in the database");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// save changes so we can references them for establishing relations
|
||||||
int insertCount = context.SaveChanges();
|
int insertCount = context.SaveChanges();
|
||||||
Console.WriteLine($"Seeded {insertCount} records");
|
Console.WriteLine($"Seeded {insertCount} records");
|
||||||
return insertCount;
|
totalInsertCount += insertCount;
|
||||||
|
|
||||||
|
// establish relations if they do not already exist
|
||||||
|
Recipe? padThai = context.Recipes.Where(r => r.Name == "Pad Thai").FirstOrDefault();
|
||||||
|
Recipe? pancakes = context.Recipes.Where(r => r.Name == "Pancakes").FirstOrDefault();
|
||||||
|
|
||||||
|
if (padThai != null)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Found Pad Thai recipe, checking relations...");
|
||||||
|
var padThaiIngredientNames = SeedData.PadThaiIngredients.Select(i => i.Name);
|
||||||
|
AddRelations(context, padThaiIngredientNames, padThai.RecipeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pancakes != null)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Found Pancakes recipe, checking relations...");
|
||||||
|
var pancakeIngredientNames = SeedData.PancakeIngredients.Select(i => i.Name);
|
||||||
|
AddRelations(context, pancakeIngredientNames, pancakes.RecipeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
totalInsertCount += context.SaveChanges();
|
||||||
|
return totalInsertCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private delegate void Callback<T>(IEnumerable<T> seedData);
|
||||||
|
|
||||||
|
private static void WriteIfNotInitialized<T>(IEnumerable<T> existingItems, IEnumerable<T> seedData, Callback<T> addRange)
|
||||||
|
{
|
||||||
|
if (existingItems.Any()) {
|
||||||
|
Console.WriteLine("Record already exists in the database");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addRange(seedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddRelations(UnbinderDbContext context, IEnumerable<string> names, int id)
|
||||||
|
{
|
||||||
|
foreach (var ing in context.Ingredients)
|
||||||
|
{
|
||||||
|
if (names.Contains(ing.Name))
|
||||||
|
{
|
||||||
|
context.RecipeIngredients.Add(new RecipeIngredient
|
||||||
|
{
|
||||||
|
RecipeId = id,
|
||||||
|
IngredientId = ing.IngredientId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,10 +31,11 @@ namespace Unbinder.DB
|
|||||||
"3. Add the wet ingredients to the dry ingredients and whisk until just combined. Let the batter rest for 5 minutes.\n" +
|
"3. Add the wet ingredients to the dry ingredients and whisk until just combined. Let the batter rest for 5 minutes.\n" +
|
||||||
"4. Heat a large nonstick skillet or griddle over medium-low heat. Add a little butter to the pan and swirl to coat. Add ⅓ cup of the batter to the pan and cook until the edges are set and bubbles form on the surface, about 2 minutes. Flip and cook for 1 minute more. Repeat with the remaining batter.\n" +
|
"4. Heat a large nonstick skillet or griddle over medium-low heat. Add a little butter to the pan and swirl to coat. Add ⅓ cup of the batter to the pan and cook until the edges are set and bubbles form on the surface, about 2 minutes. Flip and cook for 1 minute more. Repeat with the remaining batter.\n" +
|
||||||
"5. Serve with butter and maple syrup.",
|
"5. Serve with butter and maple syrup.",
|
||||||
|
S3Url = "https://unbinder.s3.us-east-2.amazonaws.com/Pancake+Recipe.pdf",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Recipe[] InitialRecipes => new Recipe[] { PadThaiRecipe, PancakeRecipe };
|
public static Recipe[] InitialRecipes => [PadThaiRecipe, PancakeRecipe];
|
||||||
|
|
||||||
public static Ingredient[] PadThaiIngredients
|
public static Ingredient[] PadThaiIngredients
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,5 +11,6 @@ namespace Unbinder.DB
|
|||||||
|
|
||||||
public DbSet<Recipe> Recipes { get; set; }
|
public DbSet<Recipe> Recipes { get; set; }
|
||||||
public DbSet<Ingredient> Ingredients { get; set; }
|
public DbSet<Ingredient> Ingredients { get; set; }
|
||||||
|
public DbSet<RecipeIngredient> RecipeIngredients { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
107
Unbinder/Migrations/20231204172304_RecipeIngredientRelation.Designer.cs
generated
Normal file
107
Unbinder/Migrations/20231204172304_RecipeIngredientRelation.Designer.cs
generated
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Unbinder.DB;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Unbinder.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(UnbinderDbContext))]
|
||||||
|
[Migration("20231204172304_RecipeIngredientRelation")]
|
||||||
|
partial class RecipeIngredientRelation
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "8.0.0")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||||
|
|
||||||
|
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("Unbinder.Models.Ingredient", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("IngredientId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("IngredientId"));
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.HasKey("IngredientId");
|
||||||
|
|
||||||
|
b.ToTable("Ingredients");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Unbinder.Models.Recipe", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("RecipeId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("RecipeId"));
|
||||||
|
|
||||||
|
b.Property<string>("Author")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("MainImageUrl")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("RecipeText")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("S3Url")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("ShortDescription")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.HasKey("RecipeId");
|
||||||
|
|
||||||
|
b.ToTable("Recipes");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Unbinder.Models.RecipeIngredient", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("RecipeIngredientId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("RecipeIngredientId"));
|
||||||
|
|
||||||
|
b.Property<string>("Amount")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<int>("IngredientId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("RecipeId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("Unit")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.HasKey("RecipeIngredientId");
|
||||||
|
|
||||||
|
b.ToTable("RecipeIngredients");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Unbinder.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class RecipeIngredientRelation : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "ImageUrl",
|
||||||
|
table: "Recipes",
|
||||||
|
newName: "S3Url");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "MainImageUrl",
|
||||||
|
table: "Recipes",
|
||||||
|
type: "nvarchar(max)",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "RecipeIngredients",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
RecipeIngredientId = table.Column<int>(type: "int", nullable: false)
|
||||||
|
.Annotation("SqlServer:Identity", "1, 1"),
|
||||||
|
RecipeId = table.Column<int>(type: "int", nullable: false),
|
||||||
|
IngredientId = table.Column<int>(type: "int", nullable: false),
|
||||||
|
Amount = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||||
|
Unit = table.Column<string>(type: "nvarchar(max)", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_RecipeIngredients", x => x.RecipeIngredientId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "RecipeIngredients");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "MainImageUrl",
|
||||||
|
table: "Recipes");
|
||||||
|
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "S3Url",
|
||||||
|
table: "Recipes",
|
||||||
|
newName: "ImageUrl");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -52,7 +52,7 @@ namespace Unbinder.Migrations
|
|||||||
b.Property<string>("Author")
|
b.Property<string>("Author")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.Property<string>("ImageUrl")
|
b.Property<string>("MainImageUrl")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
@@ -62,6 +62,9 @@ namespace Unbinder.Migrations
|
|||||||
b.Property<string>("RecipeText")
|
b.Property<string>("RecipeText")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("S3Url")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.Property<string>("ShortDescription")
|
b.Property<string>("ShortDescription")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
@@ -70,6 +73,31 @@ namespace Unbinder.Migrations
|
|||||||
|
|
||||||
b.ToTable("Recipes");
|
b.ToTable("Recipes");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Unbinder.Models.RecipeIngredient", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("RecipeIngredientId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("RecipeIngredientId"));
|
||||||
|
|
||||||
|
b.Property<string>("Amount")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<int>("IngredientId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("RecipeId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("Unit")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.HasKey("RecipeIngredientId");
|
||||||
|
|
||||||
|
b.ToTable("RecipeIngredients");
|
||||||
|
});
|
||||||
#pragma warning restore 612, 618
|
#pragma warning restore 612, 618
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,13 +5,15 @@ namespace Unbinder.Models
|
|||||||
[Table("Recipes")]
|
[Table("Recipes")]
|
||||||
public record Recipe
|
public record Recipe
|
||||||
{
|
{
|
||||||
|
// required properties
|
||||||
public int RecipeId { get; init; }
|
public int RecipeId { get; init; }
|
||||||
public string Name {get; init; } = default!;
|
public string Name {get; init; } = default!;
|
||||||
public string ShortDescription { get; init; } = default!;
|
public string ShortDescription { get; init; } = default!;
|
||||||
|
|
||||||
|
// optional properties
|
||||||
|
public string? S3Url { get; init; }
|
||||||
public string? Author { get; init; }
|
public string? Author { get; init; }
|
||||||
|
|
||||||
public string? RecipeText { get; init; }
|
public string? RecipeText { get; init; }
|
||||||
|
public string? MainImageUrl { get; init; }
|
||||||
public string? ImageUrl { get; init; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
13
Unbinder/Models/RecipeImage.cs
Normal file
13
Unbinder/Models/RecipeImage.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
|
namespace Unbinder.Models
|
||||||
|
{
|
||||||
|
[Table("RecipeImages")]
|
||||||
|
public record RecipeImage
|
||||||
|
{
|
||||||
|
public int RecipeImageId { get; init; }
|
||||||
|
public int RecipeId { get; init; }
|
||||||
|
public string? ImageUrl { get; init; }
|
||||||
|
public string? ImageAlt { get; init; }
|
||||||
|
}
|
||||||
|
}
|
||||||
14
Unbinder/Models/RecipeIngredient.cs
Normal file
14
Unbinder/Models/RecipeIngredient.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
|
namespace Unbinder.Models
|
||||||
|
{
|
||||||
|
[Table("RecipeIngredients")]
|
||||||
|
public record RecipeIngredient
|
||||||
|
{
|
||||||
|
public int RecipeIngredientId { get; init; }
|
||||||
|
public int RecipeId { get; init; }
|
||||||
|
public int IngredientId { get; init; }
|
||||||
|
public string? Amount { get; init; }
|
||||||
|
public string? Unit { get; init; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
using Microsoft.Data.SqlClient;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Data.SqlClient;
|
||||||
using Unbinder.DB;
|
using Unbinder.DB;
|
||||||
using Unbinder.Repositories;
|
using Unbinder.Repositories;
|
||||||
using Unbinder.Services;
|
using Unbinder.Services;
|
||||||
|
|||||||
8
Unbinder/Repositories/IRecipeIngredientRepository.cs
Normal file
8
Unbinder/Repositories/IRecipeIngredientRepository.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
using Unbinder.Models;
|
||||||
|
|
||||||
|
namespace Unbinder.Repositories
|
||||||
|
{
|
||||||
|
public interface IRecipeIngredientRepository : IBaseRepository<RecipeIngredient>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
31
Unbinder/Repositories/RecipeIngredientRepository.cs
Normal file
31
Unbinder/Repositories/RecipeIngredientRepository.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
using Unbinder.DB;
|
||||||
|
using Unbinder.Models;
|
||||||
|
|
||||||
|
namespace Unbinder.Repositories
|
||||||
|
{
|
||||||
|
public class RecipeIngredientRepository(UnbinderDbContext context) : BaseRepository<RecipeIngredient>(context), IRecipeIngredientRepository
|
||||||
|
{
|
||||||
|
// inapplicable methods intentionally left blank
|
||||||
|
public override IEnumerable<RecipeIngredient>? GetAll => null;
|
||||||
|
public override RecipeIngredient? UpdateById(int id) => null;
|
||||||
|
|
||||||
|
// implemented methods:
|
||||||
|
public override RecipeIngredient? GetById(int id) => _dbContext.RecipeIngredients.Where(ri => ri.RecipeIngredientId == id).FirstOrDefault();
|
||||||
|
|
||||||
|
public override RecipeIngredient Post(RecipeIngredient entity)
|
||||||
|
{
|
||||||
|
_dbContext.RecipeIngredients.Add(entity);
|
||||||
|
_dbContext.SaveChanges();
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int DeleteById(int id)
|
||||||
|
{
|
||||||
|
var recipeIngredient = GetById(id);
|
||||||
|
if (recipeIngredient == null) return 0;
|
||||||
|
_dbContext.RecipeIngredients.Remove(recipeIngredient);
|
||||||
|
_dbContext.SaveChanges();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,6 +26,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="DB\SQL\" />
|
<Folder Include="DB\SQL\" />
|
||||||
<Folder Include="secrets\" />
|
<Folder Include="secrets\" />
|
||||||
|
<Folder Include="TagHelpers\" />
|
||||||
<Folder Include="__notes__\" />
|
<Folder Include="__notes__\" />
|
||||||
<Folder Include="ViewModels\" />
|
<Folder Include="ViewModels\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
13
Unbinder/Views/Recipe/Manage.cshtml
Normal file
13
Unbinder/Views/Recipe/Manage.cshtml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
@model IEnumerable<Recipe>
|
||||||
|
|
||||||
|
@{
|
||||||
|
ViewBag.Title = "Manage";
|
||||||
|
}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h1>Manage My Recipes</h1>
|
||||||
|
|
||||||
|
<div id="recipe-list-view">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -1,6 +1,17 @@
|
|||||||
@model Recipe
|
@model Recipe
|
||||||
|
|
||||||
|
@{
|
||||||
|
var editMode = ViewBag.EditMode ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
<div id="recipe-details-by-id">
|
<div id="recipe-details-by-id">
|
||||||
<h1>@Model.Name</h1>
|
<h1>@Model.Name</h1>
|
||||||
<p>@Model.ShortDescription</p>
|
<p>@Model.ShortDescription</p>
|
||||||
|
|
||||||
|
@if (Model.RecipeText != null)
|
||||||
|
{
|
||||||
|
<div id="recipe-text">
|
||||||
|
<p>@Model.RecipeText</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
8
Unbinder/Views/Shared/Partials/_IngredientList.cshtml
Normal file
8
Unbinder/Views/Shared/Partials/_IngredientList.cshtml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
@model IEnumerable<Ingredient>
|
||||||
|
|
||||||
|
<div id="ingredient-list">
|
||||||
|
@foreach (var ingredient in Model)
|
||||||
|
{
|
||||||
|
<p>@ingredient.Name</p>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
12
Unbinder/Views/Shared/Partials/_RecipeManagerItem.cshtml
Normal file
12
Unbinder/Views/Shared/Partials/_RecipeManagerItem.cshtml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
@model Recipe
|
||||||
|
|
||||||
|
<div class="w-full flex">
|
||||||
|
<div class="flex flex-col w-1/2">
|
||||||
|
<a class="text-xl" asp-controller="Recipe" asp-route-recipeId="@Model.RecipeId">@Model.Name</a>
|
||||||
|
<p>@Model.ShortDescription</p>
|
||||||
|
</div>
|
||||||
|
<div class="flex w-1/2">
|
||||||
|
<button>Edit</button>
|
||||||
|
<button>Delete</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
Reference in New Issue
Block a user