Compare commits
3 Commits
dev
...
3b0ea79748
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b0ea79748 | ||
|
|
600df026d5 | ||
|
|
801e21842a |
@@ -3,9 +3,6 @@ using Microsoft.AspNetCore.Identity;
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Aberwyn.Models;
|
using Aberwyn.Models;
|
||||||
using Aberwyn.Data;
|
using Aberwyn.Data;
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.Hosting;
|
|
||||||
|
|
||||||
|
|
||||||
namespace Aberwyn.Controllers
|
namespace Aberwyn.Controllers
|
||||||
{
|
{
|
||||||
@@ -17,27 +14,21 @@ namespace Aberwyn.Controllers
|
|||||||
private readonly RoleManager<IdentityRole> _roleManager;
|
private readonly RoleManager<IdentityRole> _roleManager;
|
||||||
private readonly IConfiguration _configuration;
|
private readonly IConfiguration _configuration;
|
||||||
private readonly IHostEnvironment _env;
|
private readonly IHostEnvironment _env;
|
||||||
private readonly MenuService _menuService;
|
private readonly ApplicationDbContext _context;
|
||||||
|
|
||||||
private readonly ApplicationDbContext _context;
|
|
||||||
|
|
||||||
public AdminController(
|
|
||||||
IConfiguration configuration,
|
|
||||||
IHostEnvironment env,
|
|
||||||
MenuService menuService,
|
|
||||||
ApplicationDbContext context,
|
|
||||||
UserManager<ApplicationUser> userManager,
|
|
||||||
RoleManager<IdentityRole> roleManager)
|
|
||||||
{
|
|
||||||
_configuration = configuration;
|
|
||||||
_env = env;
|
|
||||||
_menuService = menuService;
|
|
||||||
_context = context;
|
|
||||||
_userManager = userManager;
|
|
||||||
_roleManager = roleManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
public AdminController(
|
||||||
|
UserManager<ApplicationUser> userManager,
|
||||||
|
RoleManager<IdentityRole> roleManager,
|
||||||
|
IConfiguration configuration,
|
||||||
|
IHostEnvironment env,
|
||||||
|
ApplicationDbContext context)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_roleManager = roleManager;
|
||||||
|
_configuration = configuration;
|
||||||
|
_env = env;
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<IActionResult> Index()
|
public async Task<IActionResult> Index()
|
||||||
{
|
{
|
||||||
@@ -148,8 +139,6 @@ public IActionResult ImportMealsFromProd()
|
|||||||
}
|
}
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Authorize(Roles = "Admin")]
|
[Authorize(Roles = "Admin")]
|
||||||
[HttpPost]
|
|
||||||
[Authorize(Roles = "Admin")]
|
|
||||||
public IActionResult ImportMenusFromProd()
|
public IActionResult ImportMenusFromProd()
|
||||||
{
|
{
|
||||||
var prodService = MenuService.CreateWithConfig(_configuration, _env, useProdDb: true);
|
var prodService = MenuService.CreateWithConfig(_configuration, _env, useProdDb: true);
|
||||||
@@ -158,35 +147,10 @@ public IActionResult ImportMenusFromProd()
|
|||||||
var allProdMenus = prodService.GetAllWeeklyMenus();
|
var allProdMenus = prodService.GetAllWeeklyMenus();
|
||||||
var allMeals = devService.GetMeals();
|
var allMeals = devService.GetMeals();
|
||||||
|
|
||||||
foreach (var menu in allProdMenus)
|
return RedirectToAction("Index");
|
||||||
{
|
}
|
||||||
var newMenu = new WeeklyMenu
|
|
||||||
{
|
|
||||||
DayOfWeek = menu.DayOfWeek,
|
|
||||||
BreakfastMealId = menu.BreakfastMealName != null
|
|
||||||
? allMeals.FirstOrDefault(m => m.Name == menu.BreakfastMealName)?.Id
|
|
||||||
: null,
|
|
||||||
LunchMealId = menu.LunchMealName != null
|
|
||||||
? allMeals.FirstOrDefault(m => m.Name == menu.LunchMealName)?.Id
|
|
||||||
: null,
|
|
||||||
DinnerMealId = menu.DinnerMealName != null
|
|
||||||
? allMeals.FirstOrDefault(m => m.Name == menu.DinnerMealName)?.Id
|
|
||||||
: null,
|
|
||||||
WeekNumber = menu.WeekNumber,
|
|
||||||
Year = menu.Year,
|
|
||||||
Cook = menu.Cook
|
|
||||||
};
|
|
||||||
|
|
||||||
_context.WeeklyMenus.Add(newMenu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_context.SaveChanges();
|
|
||||||
TempData["Message"] = "Import av veckomenyer klar.";
|
|
||||||
return RedirectToAction("Index");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AdminUserViewModel
|
public class AdminUserViewModel
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,10 +27,6 @@ namespace Aberwyn.Data
|
|||||||
public DbSet<AppSetting> AppSettings { get; set; }
|
public DbSet<AppSetting> AppSettings { get; set; }
|
||||||
public DbSet<BudgetItemDefinition> BudgetItemDefinitions { get; set; }
|
public DbSet<BudgetItemDefinition> BudgetItemDefinitions { get; set; }
|
||||||
public DbSet<BudgetCategoryDefinition> BudgetCategoryDefinitions { get; set; }
|
public DbSet<BudgetCategoryDefinition> BudgetCategoryDefinitions { get; set; }
|
||||||
public DbSet<Meal> Meals { get; set; }
|
|
||||||
public DbSet<Ingredient> Ingredients { get; set; }
|
|
||||||
public DbSet<WeeklyMenu> WeeklyMenus { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,6 +157,12 @@ public List<WeeklyMenu> GetAllWeeklyMenus()
|
|||||||
.OrderBy(m => m.Name)
|
.OrderBy(m => m.Name)
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
public List<WeeklyMenu> GetWeeklyMenu(int weekNumber, int year)
|
||||||
|
{
|
||||||
|
return _context.WeeklyMenus
|
||||||
|
.Where(m => m.WeekNumber == weekNumber && m.Year == year)
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
public List<WeeklyMenu> GetMenuEntriesByDateRange(DateTime startDate, DateTime endDate)
|
public List<WeeklyMenu> GetMenuEntriesByDateRange(DateTime startDate, DateTime endDate)
|
||||||
{
|
{
|
||||||
|
|||||||
541
Aberwyn/Migrations/20250529183339_CreateTodoTaskTable.Designer.cs
generated
Normal file
541
Aberwyn/Migrations/20250529183339_CreateTodoTaskTable.Designer.cs
generated
Normal file
@@ -0,0 +1,541 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Aberwyn.Data;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Aberwyn.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(ApplicationDbContext))]
|
||||||
|
[Migration("20250529183339_CreateTodoTaskTable")]
|
||||||
|
partial class CreateTodoTaskTable
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "6.0.36")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||||
|
|
||||||
|
modelBuilder.Entity("Aberwyn.Models.ApplicationUser", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasColumnType("varchar(255)");
|
||||||
|
|
||||||
|
b.Property<int>("AccessFailedCount")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
|
b.Property<bool>("EmailConfirmed")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<bool>("LockoutEnabled")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedEmail")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedUserName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
|
b.Property<string>("PasswordHash")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("PhoneNumber")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<bool>("PhoneNumberConfirmed")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<string>("SecurityStamp")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<bool>("TwoFactorEnabled")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<string>("UserName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedEmail")
|
||||||
|
.HasDatabaseName("EmailIndex");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedUserName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("UserNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUsers", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Aberwyn.Models.AppSetting", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("Key")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("AppSettings");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int?>("BudgetCategoryDefinitionId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("BudgetPeriodId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("Color")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<int>("Order")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("BudgetCategoryDefinitionId");
|
||||||
|
|
||||||
|
b.HasIndex("BudgetPeriodId");
|
||||||
|
|
||||||
|
b.ToTable("BudgetCategories");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Aberwyn.Models.BudgetCategoryDefinition", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("Color")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("BudgetCategoryDefinitions");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<decimal>("Amount")
|
||||||
|
.HasColumnType("decimal(65,30)");
|
||||||
|
|
||||||
|
b.Property<int>("BudgetCategoryId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int?>("BudgetItemDefinitionId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<bool>("IncludeInSummary")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<bool>("IsExpense")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<int>("Order")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("BudgetCategoryId");
|
||||||
|
|
||||||
|
b.HasIndex("BudgetItemDefinitionId");
|
||||||
|
|
||||||
|
b.ToTable("BudgetItems");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Aberwyn.Models.BudgetItemDefinition", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("DefaultCategory")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<bool>("IncludeInSummary")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<bool>("IsExpense")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("BudgetItemDefinitions");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Aberwyn.Models.BudgetPeriod", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("Month")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("Order")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("Year")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("BudgetPeriods");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Aberwyn.Models.PizzaOrder", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("CustomerName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("IngredientsJson")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<DateTime>("OrderedAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<string>("PizzaName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("Status")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("PizzaOrders");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Aberwyn.Models.PushSubscriber", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("Auth")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("Endpoint")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("P256DH")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("PushSubscribers");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Aberwyn.Models.TodoTask", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<int>("Priority")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("Status")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("Title")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("TodoTasks");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasColumnType("varchar(255)");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("RoleNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoles", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("varchar(255)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoleClaims", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("varchar(255)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserClaims", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("LoginProvider")
|
||||||
|
.HasColumnType("varchar(255)");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderKey")
|
||||||
|
.HasColumnType("varchar(255)");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderDisplayName")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("varchar(255)");
|
||||||
|
|
||||||
|
b.HasKey("LoginProvider", "ProviderKey");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserLogins", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.HasColumnType("varchar(255)");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.HasColumnType("varchar(255)");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "RoleId");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserRoles", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.HasColumnType("varchar(255)");
|
||||||
|
|
||||||
|
b.Property<string>("LoginProvider")
|
||||||
|
.HasColumnType("varchar(255)");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("varchar(255)");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "LoginProvider", "Name");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserTokens", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Aberwyn.Models.BudgetCategoryDefinition", "Definition")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("BudgetCategoryDefinitionId");
|
||||||
|
|
||||||
|
b.HasOne("Aberwyn.Models.BudgetPeriod", "BudgetPeriod")
|
||||||
|
.WithMany("Categories")
|
||||||
|
.HasForeignKey("BudgetPeriodId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("BudgetPeriod");
|
||||||
|
|
||||||
|
b.Navigation("Definition");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Aberwyn.Models.BudgetCategory", "BudgetCategory")
|
||||||
|
.WithMany("Items")
|
||||||
|
.HasForeignKey("BudgetCategoryId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Aberwyn.Models.BudgetItemDefinition", "BudgetItemDefinition")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("BudgetItemDefinitionId");
|
||||||
|
|
||||||
|
b.Navigation("BudgetCategory");
|
||||||
|
|
||||||
|
b.Navigation("BudgetItemDefinition");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Aberwyn.Models.ApplicationUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Aberwyn.Models.ApplicationUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Aberwyn.Models.ApplicationUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Aberwyn.Models.ApplicationUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Items");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Aberwyn.Models.BudgetPeriod", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Categories");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
39
Aberwyn/Migrations/20250529183339_CreateTodoTaskTable.cs
Normal file
39
Aberwyn/Migrations/20250529183339_CreateTodoTaskTable.cs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Aberwyn.Migrations
|
||||||
|
{
|
||||||
|
public partial class CreateTodoTaskTable : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "TodoTasks",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "int", nullable: false)
|
||||||
|
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||||
|
Title = table.Column<string>(type: "longtext", nullable: false)
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||||
|
Status = table.Column<string>(type: "longtext", nullable: false)
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||||
|
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||||
|
Priority = table.Column<int>(type: "int", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_TodoTasks", x => x.Id);
|
||||||
|
})
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "TodoTasks");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -358,50 +358,6 @@ namespace Aberwyn.Migrations
|
|||||||
b.ToTable("PushSubscribers");
|
b.ToTable("PushSubscribers");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Aberwyn.Models.WeeklyMenu", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int?>("BreakfastMealId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("BreakfastMealName")
|
|
||||||
.HasColumnType("longtext");
|
|
||||||
|
|
||||||
b.Property<string>("Cook")
|
|
||||||
.HasColumnType("longtext");
|
|
||||||
|
|
||||||
b.Property<DateTime>("Date")
|
|
||||||
.HasColumnType("datetime(6)");
|
|
||||||
|
|
||||||
b.Property<int>("DayOfWeek")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int?>("DinnerMealId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("DinnerMealName")
|
|
||||||
.HasColumnType("longtext");
|
|
||||||
|
|
||||||
b.Property<int?>("LunchMealId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("LunchMealName")
|
|
||||||
.HasColumnType("longtext");
|
|
||||||
|
|
||||||
b.Property<int>("WeekNumber")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("Year")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("WeeklyMenu", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||||
{
|
{
|
||||||
b.Property<string>("Id")
|
b.Property<string>("Id")
|
||||||
|
|||||||
@@ -7,4 +7,14 @@
|
|||||||
public string Value { get; set; }
|
public string Value { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class TodoTask
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Title { get; set; }
|
||||||
|
public string Status { get; set; } // "ideas", "doing", "done"
|
||||||
|
public DateTime CreatedAt { get; set; }
|
||||||
|
public int Priority { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
223
Aberwyn/Views/Admin/Todo.cshtml
Normal file
223
Aberwyn/Views/Admin/Todo.cshtml
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
@{
|
||||||
|
ViewData["Title"] = "Todo";
|
||||||
|
}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="sv" ng-app="todoApp">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>@ViewData["Title"]</title>
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
|
||||||
|
<style>
|
||||||
|
.todo-board {
|
||||||
|
padding: 20px;
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
.todo-columns {
|
||||||
|
display: flex;
|
||||||
|
gap: 16px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.todo-column {
|
||||||
|
background: #f1f5f9;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 10px;
|
||||||
|
width: 250px;
|
||||||
|
min-height: 200px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
.todo-column h2 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
.todo-task {
|
||||||
|
background: white;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 6px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||||||
|
cursor: move;
|
||||||
|
}
|
||||||
|
input[type="text"] {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 8px;
|
||||||
|
padding: 6px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
margin-top: 6px;
|
||||||
|
padding: 6px 10px;
|
||||||
|
background-color: #3b82f6;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.priority-low {
|
||||||
|
border-left: 4px solid #10b981;
|
||||||
|
}
|
||||||
|
.priority-medium {
|
||||||
|
border-left: 4px solid #f59e0b;
|
||||||
|
}
|
||||||
|
.priority-high {
|
||||||
|
border-left: 4px solid #ef4444;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body ng-controller="TodoController" class="todo-board" ng-init="loadTasks()">
|
||||||
|
|
||||||
|
<h1>🗂️ Min idé-board</h1>
|
||||||
|
|
||||||
|
<div class="todo-columns">
|
||||||
|
<div class="todo-column" ng-repeat="col in columns">
|
||||||
|
<h2>{{ col.title }}</h2>
|
||||||
|
|
||||||
|
<div class="todo-task {{ priorityClass(task.priority) }}"
|
||||||
|
ng-repeat="task in filteredTasks(col.id) track by task.id"
|
||||||
|
draggable-task
|
||||||
|
task="task"
|
||||||
|
on-task-drop="moveTask(task, col.id)">
|
||||||
|
{{ task.title }}
|
||||||
|
<div>
|
||||||
|
<small>Prioritet:
|
||||||
|
<select ng-model="task.priority" ng-change="updatePriority(task)">
|
||||||
|
<option value="1">Låg</option>
|
||||||
|
<option value="2">Medel</option>
|
||||||
|
<option value="3">Hög</option>
|
||||||
|
</select>
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ng-if="col.id === 'ideas'">
|
||||||
|
<input type="text" ng-model="newTask.title" placeholder="Ny idé..." />
|
||||||
|
<select ng-model="newTask.priority">
|
||||||
|
<option value="1">Låg</option>
|
||||||
|
<option value="2">Medel</option>
|
||||||
|
<option value="3">Hög</option>
|
||||||
|
</select>
|
||||||
|
<button type="button" ng-click="addTask()">Lägg till</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var app = angular.module("todoApp", []);
|
||||||
|
|
||||||
|
app.controller("TodoController", function ($scope, $http) {
|
||||||
|
$scope.columns = [
|
||||||
|
{ id: "ideas", title: "💡 Idéer" },
|
||||||
|
{ id: "doing", title: "🔧 Pågående" },
|
||||||
|
{ id: "done", title: "✅ Klart" }
|
||||||
|
];
|
||||||
|
|
||||||
|
$scope.tasks = [];
|
||||||
|
$scope.newTask = {
|
||||||
|
title: '',
|
||||||
|
priority: 2
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.loadTasks = function () {
|
||||||
|
$http.get("/Admin/GetTodoTasks").then(res => {
|
||||||
|
$scope.tasks = res.data;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.addTask = function () {
|
||||||
|
console.log("addTask:");
|
||||||
|
|
||||||
|
const title = $scope.newTask.title;
|
||||||
|
const priority = $scope.newTask.priority;
|
||||||
|
|
||||||
|
if (typeof title !== 'string' || !title.trim()) {
|
||||||
|
console.warn("Titel är tom eller ogiltig:", title);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log("post check");
|
||||||
|
|
||||||
|
const task = {
|
||||||
|
title: title.trim(),
|
||||||
|
status: "ideas",
|
||||||
|
priority: priority
|
||||||
|
};
|
||||||
|
console.log("post title trim");
|
||||||
|
|
||||||
|
$http.post("/Admin/AddTodoTask", task, {
|
||||||
|
headers: { 'Content-Type': 'application/json' }
|
||||||
|
}).then(res => {
|
||||||
|
$scope.tasks.push(res.data);
|
||||||
|
$scope.newTask.title = '';
|
||||||
|
$scope.newTask.priority = 2;
|
||||||
|
console.log("Created task");
|
||||||
|
}, err => {
|
||||||
|
console.error("Fel vid POST:", err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.moveTask = function (task, newStatus) {
|
||||||
|
task.status = newStatus;
|
||||||
|
$http.post("/Admin/UpdateTodoTask", task);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.updatePriority = function (task) {
|
||||||
|
$http.post("/Admin/UpdateTodoTask", task);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.priorityClass = function (priority) {
|
||||||
|
return {
|
||||||
|
1: 'priority-low',
|
||||||
|
2: 'priority-medium',
|
||||||
|
3: 'priority-high'
|
||||||
|
}[priority];
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.filteredTasks = function (status) {
|
||||||
|
if (!$scope.tasks || !$scope.tasks.length) return [];
|
||||||
|
|
||||||
|
// För säkerhets skull jämför lowercase
|
||||||
|
return $scope.tasks.filter(t => (t.status || '').toLowerCase() === status.toLowerCase());
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.loadTasks();
|
||||||
|
});
|
||||||
|
|
||||||
|
app.directive("draggableTask", function () {
|
||||||
|
return {
|
||||||
|
restrict: "A",
|
||||||
|
scope: {
|
||||||
|
task: "=",
|
||||||
|
onTaskDrop: "&"
|
||||||
|
},
|
||||||
|
link: function (scope, element) {
|
||||||
|
element.attr("draggable", true);
|
||||||
|
element.on("dragstart", function (e) {
|
||||||
|
e.dataTransfer.setData("text/plain", JSON.stringify(scope.task));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
app.directive("ngRepeat", function () {
|
||||||
|
return {
|
||||||
|
restrict: "A",
|
||||||
|
link: function (scope, element) {
|
||||||
|
element.on("dragover", function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
element.css("background-color", "#e0f2fe");
|
||||||
|
});
|
||||||
|
element.on("dragleave", function () {
|
||||||
|
element.css("background-color", "");
|
||||||
|
});
|
||||||
|
element.on("drop", function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const data = e.dataTransfer.getData("text/plain");
|
||||||
|
const task = JSON.parse(data);
|
||||||
|
scope.onTaskDrop({ task });
|
||||||
|
element.css("background-color", "");
|
||||||
|
scope.$apply();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user