| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- @model Recepie.ViewModels.RecipeIndexViewModel
- @{
- ViewData["Title"] = "Recipe Search";
- }
- <div class="container-fluid mt-4">
- <div class="row">
- <div class="col-md-3">
- <!-- Search Panel -->
- <div class="card">
- <div class="card-header">
- <h5 class="mb-0">
- <i class="fas fa-search"></i> Search Recipes
- </h5>
- </div>
- <div class="card-body">
- <form method="get" asp-action="Index">
- <!-- Search Term -->
- <div class="mb-3">
- <label for="searchTerm" class="form-label">Search</label>
- <input type="text" class="form-control" id="searchTerm" name="searchTerm"
- value="@Model.SearchTerm" placeholder="Search title or description...">
- </div>
- <!-- Include Ingredients -->
- <div class="mb-3">
- <label for="includeIngredients" class="form-label">
- <i class="fas fa-plus text-success"></i> Must Have Ingredients
- </label>
- <input type="text" class="form-control" id="includeIngredients" name="includeIngredients"
- value="@Model.IncludeIngredients" placeholder="chicken, tomato, onion...">
- <div class="form-text">Comma-separated list</div>
- </div>
- <!-- Exclude Ingredients -->
- <div class="mb-3">
- <label for="excludeIngredients" class="form-label">
- <i class="fas fa-minus text-danger"></i> Exclude Ingredients
- </label>
- <input type="text" class="form-control" id="excludeIngredients" name="excludeIngredients"
- value="@Model.ExcludeIngredients" placeholder="nuts, dairy, gluten...">
- <div class="form-text">Comma-separated list</div>
- </div>
- <button type="submit" class="btn btn-primary w-100">
- <i class="fas fa-search"></i> Search & Filter
- </button>
- @if (!string.IsNullOrEmpty(Model.SearchTerm) || !string.IsNullOrEmpty(Model.IncludeIngredients)
- || !string.IsNullOrEmpty(Model.ExcludeIngredients))
- {
- <a href="@Url.Action("Index")" class="btn btn-secondary w-100 mt-2">
- <i class="fas fa-times"></i> Clear All Filters
- </a>
- }
- </form>
- </div>
- </div>
- <!-- Stats Panel -->
- <div class="card mt-3">
- <div class="card-body">
- <h6 class="card-title">Results</h6>
- <p class="card-text">
- Found <strong>@Model.Recipes.Count</strong> recipes
- </p>
- </div>
- </div>
- </div>
- <div class="col-md-9">
- <!-- Recipe Results -->
- <div class="d-flex justify-content-between align-items-center mb-3">
- <h2>Recipes</h2>
- <a href="@Url.Action("Create")" class="btn btn-success">
- <i class="fas fa-plus"></i> Add New Recipe
- </a>
- </div>
- @if (Model.Recipes.Any())
- {
- <div class="row">
- @foreach (var recipe in Model.Recipes)
- {
- <div class="col-md-6 col-lg-4 mb-4">
- <div class="card h-100">
- @* Small thumbnail image with error handling *@
- <img src="@Url.Action("GetImage", "Recipe", new { recipeId = recipe.Id })" class="card-img-top"
- alt="@recipe.Title" style="height: 200px; object-fit: cover; background-color: #f8f9fa;"
- onerror="this.style.display='none'; this.nextElementSibling.style.display='block';" />
- <div class="card-img-placeholder text-center p-3"
- style="display: none; height: 200px; background-color: #f8f9fa; align-items: center; justify-content: center;">
- <i class="fas fa-utensils fa-3x text-muted"></i>
- </div>
- <div class="card-body">
- <h5 class="card-title">@recipe.Title</h5>
- <p class="card-text">@recipe.Description</p>
- @if (!string.IsNullOrEmpty(recipe.Difficulty))
- {
- <div class="mb-2">
- <span class="badge bg-info">@recipe.Difficulty</span>
- </div>
- }
- @if (!string.IsNullOrEmpty(recipe.Time))
- {
- <div class="mb-2">
- <small class="text-muted">
- <i class="fas fa-clock"></i> @recipe.Time
- </small>
- </div>
- }
- @if (!string.IsNullOrEmpty(recipe.Url))
- {
- <div class="mb-2">
- <a href="@recipe.Url" target="_blank" class="btn btn-sm btn-outline-primary">
- <i class="fas fa-external-link-alt"></i> View Recipe
- </a>
- </div>
- }
- </div>
- <div class="card-footer">
- <div class="btn-group w-100" role="group">
- <a href="@Url.Action("Details", new { id = recipe.Id })"
- class="btn btn-outline-primary btn-sm">
- <i class="fas fa-eye"></i> Details
- </a>
- <a href="@Url.Action("Edit", new { id = recipe.Id })"
- class="btn btn-outline-warning btn-sm">
- <i class="fas fa-edit"></i> Edit
- </a>
- <a href="@Url.Action("Delete", new { id = recipe.Id })"
- class="btn btn-outline-danger btn-sm">
- <i class="fas fa-trash"></i> Delete
- </a>
- </div>
- </div>
- </div>
- </div>
- }
- </div>
- }
- else
- {
- <div class="alert alert-info">
- <i class="fas fa-info-circle"></i>
- @if (!string.IsNullOrEmpty(Model.SearchTerm))
- {
- <span>No recipes found matching your search criteria.</span>
- }
- else
- {
- <span>No recipes found in the database.</span>
- }
- </div>
- }
- </div>
- </div>
- </div>
- @section Scripts {
- <script>
- // Auto-submit search after typing (debounced)
- let searchTimeout;
- document.getElementById('searchTerm').addEventListener('input', function () {
- clearTimeout(searchTimeout);
- searchTimeout = setTimeout(() => {
- if (this.value.length > 2 || this.value.length === 0) {
- this.form.submit();
- }
- }, 500);
- });
- </script>
- }
|