This commit is contained in:
@@ -18,7 +18,11 @@ namespace Aberwyn.Controllers
|
|||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
_env = env;
|
_env = env;
|
||||||
}
|
}
|
||||||
|
[HttpGet("/meal")]
|
||||||
|
public IActionResult Index()
|
||||||
|
{
|
||||||
|
return View("Index");
|
||||||
|
}
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public IActionResult View(int? id, bool edit = false)
|
public IActionResult View(int? id, bool edit = false)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,11 +30,12 @@ namespace Aberwyn.Controllers
|
|||||||
[HttpGet("getMeals")]
|
[HttpGet("getMeals")]
|
||||||
public IActionResult GetMeals()
|
public IActionResult GetMeals()
|
||||||
{
|
{
|
||||||
var meals = _menuService.GetMealsDetailed(); // Hämtar med ImageData
|
var meals = _menuService.GetMealsSlim(true);
|
||||||
var mealDtos = meals.Select(MealDto.FromMeal).ToList();
|
var mealDtos = meals.Select(m => MealDto.FromMeal(m, includeThumbnail: true)).ToList(); // 👈 fix
|
||||||
return Ok(mealDtos);
|
return Ok(mealDtos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[HttpGet("getWeeklyMenu")]
|
[HttpGet("getWeeklyMenu")]
|
||||||
public IActionResult GetWeeklyMenu(int weekNumber, int year)
|
public IActionResult GetWeeklyMenu(int weekNumber, int year)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -165,9 +165,35 @@ public class MenuService
|
|||||||
_context.SaveChanges();
|
_context.SaveChanges();
|
||||||
return updatedCount;
|
return updatedCount;
|
||||||
}
|
}
|
||||||
|
public List<Meal> GetMealsSlim(bool includeThumbnail = false)
|
||||||
public List<WeeklyMenu> GetAllWeeklyMenus()
|
|
||||||
{
|
{
|
||||||
|
if (includeThumbnail)
|
||||||
|
{
|
||||||
|
return _context.Meals
|
||||||
|
.Select(m => new Meal
|
||||||
|
{
|
||||||
|
Id = m.Id,
|
||||||
|
Name = m.Name,
|
||||||
|
Description = m.Description,
|
||||||
|
ThumbnailData = m.ThumbnailData
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return _context.Meals
|
||||||
|
.Select(m => new Meal
|
||||||
|
{
|
||||||
|
Id = m.Id,
|
||||||
|
Name = m.Name,
|
||||||
|
Description = m.Description
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<WeeklyMenu> GetAllWeeklyMenus()
|
||||||
|
{
|
||||||
var menus = _context.WeeklyMenus.ToList();
|
var menus = _context.WeeklyMenus.ToList();
|
||||||
|
|
||||||
var allMeals = _context.Meals.ToDictionary(m => m.Id, m => m.Name);
|
var allMeals = _context.Meals.ToDictionary(m => m.Id, m => m.Name);
|
||||||
|
|||||||
@@ -104,20 +104,39 @@ public class WeeklyMenu
|
|||||||
public string? ImageData { get; set; } // base64
|
public string? ImageData { get; set; } // base64
|
||||||
public string? ImageMimeType { get; set; }
|
public string? ImageMimeType { get; set; }
|
||||||
|
|
||||||
public static MealDto FromMeal(Meal meal)
|
public static MealListDto FromMeal(Meal meal, bool includeThumbnail = false)
|
||||||
{
|
{
|
||||||
return new MealDto
|
return new MealListDto
|
||||||
{
|
{
|
||||||
Id = meal.Id,
|
Id = meal.Id,
|
||||||
Name = meal.Name,
|
Name = meal.Name,
|
||||||
Category = meal.Category,
|
Description = meal.Description,
|
||||||
IsAvailable = meal.IsAvailable,
|
ThumbnailData = includeThumbnail && meal.ThumbnailData != null
|
||||||
ImageUrl = meal.ImageUrl,
|
? Convert.ToBase64String(meal.ThumbnailData)
|
||||||
ImageMimeType = meal.ImageMimeType,
|
: null
|
||||||
ImageData = meal.ImageData != null ? Convert.ToBase64String(meal.ImageData) : null
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
public class MealListDto
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Name { get; set; } = "";
|
||||||
|
public string? Description { get; set; }
|
||||||
|
public string? ThumbnailData { get; set; }
|
||||||
|
|
||||||
|
public static MealListDto FromMeal(Meal meal, bool includeThumbnail = false)
|
||||||
|
{
|
||||||
|
return new MealListDto
|
||||||
|
{
|
||||||
|
Id = meal.Id,
|
||||||
|
Name = meal.Name,
|
||||||
|
Description = meal.Description,
|
||||||
|
ThumbnailData = includeThumbnail && meal.ThumbnailData != null
|
||||||
|
? Convert.ToBase64String(meal.ThumbnailData)
|
||||||
|
: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
48
Aberwyn/Views/Meal/Index.cshtml
Normal file
48
Aberwyn/Views/Meal/Index.cshtml
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="sv" ng-app="mealGalleryApp">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Måltider</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
|
||||||
|
<link rel="stylesheet" href="/css/meal-gallery.css">
|
||||||
|
</head>
|
||||||
|
<body ng-controller="MealGalleryController">
|
||||||
|
<div class="meal-gallery-container" ng-controller="MealGalleryController">
|
||||||
|
<div class="meal-gallery-header">
|
||||||
|
<h1>Recept</h1>
|
||||||
|
<div class="search-container">
|
||||||
|
<input type="text" ng-model="search" placeholder="Sök recept...">
|
||||||
|
<i class="fa-solid fa-magnifying-glass"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="meal-gallery-grid">
|
||||||
|
<div class="meal-card" ng-repeat="meal in meals | filter:search">
|
||||||
|
<img ng-src="{{ meal.ThumbnailData ? 'data:image/webp;base64,' + meal.ThumbnailData : '/images/fallback.jpg' }}"
|
||||||
|
alt="{{ meal.Name }}">
|
||||||
|
<div class="meal-card-content">
|
||||||
|
<h3>{{ meal.Name }}</h3>
|
||||||
|
<p ng-if="meal.Description">{{ meal.Description }}</p>
|
||||||
|
<a class="btn-readmore" ng-href="/meal/view/{{ meal.Id }}">Läs mer</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
angular.module("mealGalleryApp", []).controller("MealGalleryController", function ($scope, $http) {
|
||||||
|
$scope.meals = [];
|
||||||
|
$scope.search = "";
|
||||||
|
|
||||||
|
$http.get("/api/mealMenuApi/getMeals").then(res => {
|
||||||
|
$scope.meals = res.data;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
107
Aberwyn/wwwroot/css/meal-gallery.css
Normal file
107
Aberwyn/wwwroot/css/meal-gallery.css
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
body {
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
font-family: 'Segoe UI', sans-serif;
|
||||||
|
color: #222;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meal-gallery-container {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 2rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meal-gallery-header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meal-gallery-header h1 {
|
||||||
|
font-size: 2.4rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-container {
|
||||||
|
margin-top: 1rem;
|
||||||
|
position: relative;
|
||||||
|
max-width: 400px;
|
||||||
|
margin-inline: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-container input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px 38px 10px 12px;
|
||||||
|
border-radius: 25px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-container i {
|
||||||
|
position: absolute;
|
||||||
|
right: 12px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meal-gallery-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
|
||||||
|
gap: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meal-card {
|
||||||
|
background: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
|
||||||
|
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meal-card:hover {
|
||||||
|
transform: scale(1.015);
|
||||||
|
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.meal-card img {
|
||||||
|
width: 100%;
|
||||||
|
height: 200px;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meal-card-content {
|
||||||
|
padding: 16px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meal-card-content h3 {
|
||||||
|
margin: 0 0 8px;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: #111;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meal-card-content p {
|
||||||
|
flex-grow: 1;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-readmore {
|
||||||
|
align-self: flex-start;
|
||||||
|
background: #007d36;
|
||||||
|
color: white;
|
||||||
|
padding: 8px 12px;
|
||||||
|
border-radius: 6px;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-readmore:hover {
|
||||||
|
background: #005c27;
|
||||||
|
}
|
||||||
|
|
||||||
BIN
Aberwyn/wwwroot/images/fallback.jpg
Normal file
BIN
Aberwyn/wwwroot/images/fallback.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
Reference in New Issue
Block a user