public async Task <IActionResult> Index(RecipeKeyModel key)
        {
            var(book, recipe) = await GetRecipeAsync(key);

            if (recipe == null)
            {
                return(NotFound());
            }

            if (!ModelState.IsValid)
            {
                return(BadRequest());
            }

            var(ingredients, caloriesPerServing, proteinPerServing) =
                await _dataService.GetRecipeViewComponentsAsync(recipe.BookId, recipe.RecipeId);

            return(View(new RecipeViewModel
            {
                Book = book,
                Recipe = recipe,
                Ingredients = ingredients,
                CaloriesPerServing = caloriesPerServing,
                ProteinPerServing = proteinPerServing
            }));
        }
        public async Task <IActionResult> AddIngredients(RecipeKeyModel key)
        {
            var(book, recipe) = await GetRecipeAsync(key);

            if (recipe == null)
            {
                return(NotFound());
            }

            if (!ModelState.IsValid)
            {
                return(BadRequest());
            }

            var ingredients0 = await _dataService
                               .GetIngredientsAsync(recipe.BookId, recipe.RecipeId);

            var ingredients = ingredients0.AsList();

            var viewModels = ingredients
                             .Select(ingredient => new EditIngredientViewModel
            {
                IngredientNo       = ingredient.IngredientNo,
                Name               = ingredient.Name,
                Quantity           = ingredient.Quantity,
                QuantityUnit       = $"{ingredient.QuantityType},{ingredient.QuantityUnit}",
                Serving            = ingredient.Serving,
                ServingUnit        = $"{ingredient.ServingType},{ingredient.ServingUnit}",
                CaloriesPerServing = ingredient.CaloriesPerServing,
                ProteinPerServing  = ingredient.ProteinPerServing
            })
                             .ToList();

            int lastIngredientNo = ingredients.Count > 0
                ? ingredients[ingredients.Count - 1].IngredientNo
                : 0;

            viewModels.Add(new EditIngredientViewModel
            {
                IngredientNo = lastIngredientNo + 1,
                AutoFocus    = true
            });

            var units = await _dataService.GetUnitsAsync();

            return(View("EditIngredients", new EditIngredientsViewModel
            {
                Book = book,
                Recipe = recipe,
                Ingredients = viewModels,
                Units = units,
                IsAddingMode = true,
                ShowBulkActions = false
            }));
        }
        public async Task <IActionResult> Delete(RecipeKeyModel key)
        {
            var(book, recipe) = await GetRecipeAsync(key);

            if (recipe == null)
            {
                return(NotFound());
            }

            if (!ModelState.IsValid)
            {
                return(BadRequest());
            }

            return(View(recipe));
        }
        public async Task <IActionResult> Delete(RecipeKeyModel key, DeleteRecipeModel model)
        {
            var(book, recipe) = await GetRecipeAsync(key);

            if (recipe == null)
            {
                return(NotFound());
            }

            if (!ModelState.IsValid)
            {
                return(View(recipe));
            }

            await _dataService.DeleteRecipeAsync(recipe.BookId, recipe.RecipeId);

            return(RedirectToAction("Index", "Book"));
        }
        public async Task <IActionResult> Edit(RecipeKeyModel key)
        {
            var(book, recipe) = await GetRecipeAsync(key);

            if (recipe == null)
            {
                return(NotFound());
            }

            if (!ModelState.IsValid)
            {
                return(BadRequest());
            }

            return(View(new EditRecipeModel
            {
                Name = recipe.Name,
                Description = recipe.Description,
                Servings = recipe.Servings
            }));
        }
 private async Task <(BookModel, RecipeModel)> GetRecipeAsync(RecipeKeyModel key)
 {
     if (key == null || key.BookId == null || key.Token == null || key.RecipeId == null)
     {
         return(default);
        public async Task <IActionResult> SaveIngredients(RecipeKeyModel key, EditIngredientsModel model)
        {
            var(book, recipe) = await GetRecipeAsync(key);

            if (recipe == null)
            {
                return(NotFound());
            }

            if (!ModelState.IsValid)
            {
                var units = await _dataService.GetUnitsAsync();

                var showBulkActions = !model.IsAddingMode;
                var viewModels      = model.Ingredients
                                      .Select(ingredient => new EditIngredientViewModel
                {
                    Checked            = ingredient.Checked,
                    IngredientNo       = ingredient.IngredientNo,
                    Name               = ingredient.Name,
                    Quantity           = ingredient.Quantity,
                    QuantityUnit       = ingredient.QuantityUnit,
                    Serving            = ingredient.Serving,
                    ServingUnit        = ingredient.ServingUnit,
                    CaloriesPerServing = ingredient.CaloriesPerServing,
                    ProteinPerServing  = ingredient.ProteinPerServing
                })
                                      .ToList();

                return(View("EditIngredients", new EditIngredientsViewModel
                {
                    Book = book,
                    Recipe = recipe,
                    Ingredients = viewModels,
                    Units = units,
                    IsAddingMode = model.IsAddingMode,
                    ShowBulkActions = showBulkActions
                }));
            }

            List <EditIngredientModel> ingredients = model.Ingredients;

            if (model.SaveAction == SaveActionType.RemoveChecked)
            {
                ingredients = ingredients
                              .Where(ingredient => ingredient.Checked == false)
                              .ToList();
            }

            await _dataService
            .SaveIngredientsAsync(recipe.BookId, recipe.RecipeId, ingredients);

            switch (model.SaveAction)
            {
            case SaveActionType.AddNew:
                return(RedirectToAction("AddIngredients"));

            case SaveActionType.RemoveChecked:
                if (ingredients.Count > 0)
                {
                    return(RedirectToAction("EditIngredients"));
                }
                else
                {
                    return(RedirectToAction("AddIngredients"));
                }

            default:
                return(RedirectToAction("Index"));
            }
        }