Merge pull request #2 from francesco448/feature/Show-ShoppingList-Of-Active-RecipeCard

Feature/show shopping list of active recipe card
This commit is contained in:
francesco448
2026-03-02 16:39:41 +01:00
committed by GitHub
7 changed files with 68 additions and 38 deletions
@@ -5,7 +5,6 @@
using Francesco.Recipes.World.Repositories.Favorit;
using Microsoft.AspNetCore.Mvc;
[Route("Favorite")]
public class FavoriteController : Controller
{
private readonly IFavoriteRepository _favoriteRepository;
@@ -2,7 +2,6 @@
{
using Francesco.Recipes.World.Repositories.Category;
using Francesco.Recipes.World.Repositories.Recipe;
using Francesco.Recipes.World.Views.Category;
using Microsoft.AspNetCore.Mvc;
public class HomeController : Controller
@@ -19,15 +18,8 @@
[HttpGet]
public async Task<IActionResult> Index()
{
var categories = await _categoryRepository.GetAllCategoriesWithRecipesAsync();
var viewModel = categories.Select(category => new CategoryRecipesViewModel
{
Category = category,
Recipes = category.Recipes,
});
return View("Index", viewModel);
var categoriesWithRecipes = await _categoryRepository.GetAllCategoriesWithRecipesViewModelAsync();
return View(categoriesWithRecipes);
}
[HttpGet("/Home/Search")]
@@ -12,7 +12,6 @@
using Francesco.Recipes.World.Repositories.MediaFile;
using Francesco.Recipes.World.Repositories.Recipe;
using Francesco.Recipes.World.Repositories.Unit;
using Francesco.Recipes.World.Views.Category;
using Francesco.Recipes.World.Views.Recipe;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
@@ -91,15 +90,8 @@
[HttpGet("CategoryRecipes")]
public async Task<IActionResult> CategoryRecipes()
{
var categories = await _categoryRepository.GetAllCategoriesWithRecipesAsync();
var viewModel = categories.Select(c => new CategoryRecipesViewModel
{
Category = c,
Recipes = c.Recipes,
}).ToList();
return View(viewModel);
var categoryViewModels = await _categoryRepository.GetAllCategoriesWithRecipesAsync();
return View(categoryViewModels);
}
// POST: /Recipe/{recipeId}/AddOrCreateIngredient
@@ -424,34 +416,35 @@
return View(favoriteRecipes);
}
// POST: /Recipe/AddFavorite
[HttpPost("AddFavorite")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> AddFavorite(Guid recipeId)
{
await _favoriteRepository.AddFavoriteAsync(recipeId);
var recipe = await _recipeRepository.GetRecipeByIdAsync(recipeId);
if (recipe == null)
// We only need to know the Id and IsFavorite status
var viewModel = new FavoritButtonViewModel
{
return NotFound("Recipe not found.");
Id = recipeId,
IsFavorite = true,
};
return PartialView("_FavoriteButton", viewModel);
}
return PartialView("_FavoriteButton", recipe);
}
// POST: /Recipe/RemoveFavorite
[HttpPost("RemoveFavorite")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> RemoveFavorite(Guid recipeId)
{
await _favoriteRepository.RemoveFavoriteAsync(recipeId);
var recipe = await _recipeRepository.GetRecipeByIdAsync(recipeId);
if (recipe == null)
{
return NotFound("Recipe not found.");
}
return PartialView("_FavoriteButton", recipe);
var viewModel = new FavoritButtonViewModel
{
Id = recipeId,
IsFavorite = false,
};
return PartialView("_FavoriteButton", viewModel);
}
// GET: /Recipe/{recipeId}/GetIngredients
@@ -497,7 +490,6 @@
return View(recipe);
}
// DELETE: /Recipe/{recipeId}/Delete
[HttpDelete("{recipeId}/Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(Guid recipeId)
@@ -506,12 +498,24 @@
if (deleted)
{
TempData["SuccessMessage"] = "Rezept wurde erfolgreich gelöscht.";
if (Request.Headers.ContainsKey("HX-Request"))
{
Response.Headers["HX-Redirect"] = Url.Action("Index", "Home");
return Ok();
}
return RedirectToAction("Index", "Home");
}
else
{
TempData["ErrorMessage"] = "Rezept nicht gefunden oder konnte nicht gelöscht werden.";
if (Request.Headers.ContainsKey("HX-Request"))
{
Response.Headers["HX-Redirect"] = Url.Action("Details", new { recipeId });
return Ok();
}
return RedirectToAction("Details", new { recipeId });
}
}
@@ -6,7 +6,7 @@ using Francesco.Recipes.World.Models.BackendModels.Instruction;
using Francesco.Recipes.World.Models.BackendModels.MediaFile;
using Francesco.Recipes.World.Models.BackendModels.RecipeIngredient;
public class Recipe : ITimeStampedEntity
public class Recipe : ITimeStampedEntity, IFavoritable
{
public Guid Id { get; set; }
@@ -0,0 +1,9 @@
namespace Francesco.Recipes.World.Models
{
public class FavoritButtonViewModel : IFavoritable
{
public Guid Id { get; set; }
public bool IsFavorite { get; set; }
}
}
@@ -0,0 +1,9 @@
namespace Francesco.Recipes.World.Models
{
public interface IFavoritable
{
Guid Id { get; set; }
bool IsFavorite { get; set; }
}
}
@@ -0,0 +1,17 @@
namespace Francesco.Recipes.World.Models
{
public class RecipeCardViewModel : IFavoritable
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
public TimeSpan CookingTime { get; set; }
public bool IsFavorite { get; set; }
public byte[]? ImageData { get; set; }
public string? MimeType { get; set; }
}
}