diff --git a/Lieb/Data/DbInitializer.cs b/Lieb/Data/DbInitializer.cs new file mode 100644 index 0000000..02a19ac --- /dev/null +++ b/Lieb/Data/DbInitializer.cs @@ -0,0 +1,27 @@ +using Lieb.Models; + +namespace Lieb.Data +{ + public class DbInitializer + { + public static void Initialize(LiebContext context) + { + // Look for any students. + if (context.Users.Any()) + { + return; // DB has been seeded + } + + var users = new User[] + { + new User{DiscordUserId=0, Name="Sarah",Birthday=DateTime.Parse("1992-01-15")}, + new User{DiscordUserId=0, Name="Lisa",Birthday=DateTime.Parse("1991-02-15")}, + new User{DiscordUserId=0, Name="Simon",Birthday=DateTime.Parse("2019-09-01")} + }; + + context.Users.AddRange(users); + context.SaveChanges(); + + } + } +} diff --git a/Lieb/Data/LiebContext.cs b/Lieb/Data/LiebContext.cs new file mode 100644 index 0000000..629a211 --- /dev/null +++ b/Lieb/Data/LiebContext.cs @@ -0,0 +1,47 @@ +#nullable disable +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Lieb.Models; +using Lieb.Models.Raid; + +namespace Lieb.Data +{ + public class LiebContext : DbContext + { + public LiebContext (DbContextOptions options) + : base(options) + { + } + + public DbSet Users { get; set; } + public DbSet GuildWars2Account { get; set; } + public DbSet Equipped { get; set; } + public DbSet RaidRoles { get; set; } + public DbSet PlannedRaids { get; set; } + public DbSet PlannedRaidRoles { get; set; } + public DbSet Raids { get; set; } + public DbSet RaidReminders { get; set; } + public DbSet RaidSignUps { get; set; } + public DbSet RandomRaids { get; set; } + public DbSet SignUpHistories { get; set; } + + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity().ToTable("User"); + modelBuilder.Entity().ToTable("GuildWars2Account"); + modelBuilder.Entity().ToTable("Equipped"); + modelBuilder.Entity().ToTable("RaidRole"); + modelBuilder.Entity().ToTable("PlannedRaid"); + modelBuilder.Entity().ToTable("PlannedRaidRole"); + modelBuilder.Entity().ToTable("Raid"); + modelBuilder.Entity().ToTable("RaidReminder"); + modelBuilder.Entity().ToTable("RaidSignUp"); + modelBuilder.Entity().ToTable("RandomRaid"); + modelBuilder.Entity().ToTable("SignUpHistory"); + } + } +} diff --git a/Lieb/Lieb.csproj b/Lieb/Lieb.csproj index c78c9c7..5cfee68 100644 --- a/Lieb/Lieb.csproj +++ b/Lieb/Lieb.csproj @@ -6,4 +6,18 @@ enable + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + diff --git a/Lieb/Models/User.cs b/Lieb/Models/User.cs index 12c4063..b8f678b 100644 --- a/Lieb/Models/User.cs +++ b/Lieb/Models/User.cs @@ -5,7 +5,7 @@ public int UserId { get; set; } public ulong DiscordUserId { get; set; } public string Name { get; set; } = string.Empty; - public DateTime Birthday { get; set; } + public DateTime? Birthday { get; set; } public ICollection GuildWars2Accounts { get; set; } = new List(); } } diff --git a/Lieb/Pages/Users/Create.cshtml b/Lieb/Pages/Users/Create.cshtml new file mode 100644 index 0000000..3705ab8 --- /dev/null +++ b/Lieb/Pages/Users/Create.cshtml @@ -0,0 +1,44 @@ +@page +@model Lieb.Pages.Users.CreateModel + +@{ + ViewData["Title"] = "Create"; +} + +

Create

+ +

User

+
+
+
+
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ +
+
+
+
+ + + +@section Scripts { + @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} +} diff --git a/Lieb/Pages/Users/Create.cshtml.cs b/Lieb/Pages/Users/Create.cshtml.cs new file mode 100644 index 0000000..5b93e17 --- /dev/null +++ b/Lieb/Pages/Users/Create.cshtml.cs @@ -0,0 +1,45 @@ +#nullable disable +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.AspNetCore.Mvc.Rendering; +using Lieb.Data; +using Lieb.Models; + +namespace Lieb.Pages.Users +{ + public class CreateModel : PageModel + { + private readonly Lieb.Data.LiebContext _context; + + public CreateModel(Lieb.Data.LiebContext context) + { + _context = context; + } + + public IActionResult OnGet() + { + return Page(); + } + + [BindProperty] + public User User { get; set; } + + // To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD + public async Task OnPostAsync() + { + if (!ModelState.IsValid) + { + return Page(); + } + + _context.Users.Add(User); + await _context.SaveChangesAsync(); + + return RedirectToPage("./Index"); + } + } +} diff --git a/Lieb/Pages/Users/Delete.cshtml b/Lieb/Pages/Users/Delete.cshtml new file mode 100644 index 0000000..3ef308f --- /dev/null +++ b/Lieb/Pages/Users/Delete.cshtml @@ -0,0 +1,40 @@ +@page +@model Lieb.Pages.Users.DeleteModel + +@{ + ViewData["Title"] = "Delete"; +} + +

Delete

+ +

Are you sure you want to delete this?

+
+

User

+
+
+
+ @Html.DisplayNameFor(model => model.User.DiscordUserId) +
+
+ @Html.DisplayFor(model => model.User.DiscordUserId) +
+
+ @Html.DisplayNameFor(model => model.User.Name) +
+
+ @Html.DisplayFor(model => model.User.Name) +
+
+ @Html.DisplayNameFor(model => model.User.Birthday) +
+
+ @Html.DisplayFor(model => model.User.Birthday) +
+
+ +
+ + | + Back to List +
+
diff --git a/Lieb/Pages/Users/Delete.cshtml.cs b/Lieb/Pages/Users/Delete.cshtml.cs new file mode 100644 index 0000000..3d2389b --- /dev/null +++ b/Lieb/Pages/Users/Delete.cshtml.cs @@ -0,0 +1,60 @@ +#nullable disable +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.EntityFrameworkCore; +using Lieb.Data; +using Lieb.Models; + +namespace Lieb.Pages.Users +{ + public class DeleteModel : PageModel + { + private readonly Lieb.Data.LiebContext _context; + + public DeleteModel(Lieb.Data.LiebContext context) + { + _context = context; + } + + [BindProperty] + public User User { get; set; } + + public async Task OnGetAsync(int? id) + { + if (id == null) + { + return NotFound(); + } + + User = await _context.Users.FirstOrDefaultAsync(m => m.UserId == id); + + if (User == null) + { + return NotFound(); + } + return Page(); + } + + public async Task OnPostAsync(int? id) + { + if (id == null) + { + return NotFound(); + } + + User = await _context.Users.FindAsync(id); + + if (User != null) + { + _context.Users.Remove(User); + await _context.SaveChangesAsync(); + } + + return RedirectToPage("./Index"); + } + } +} diff --git a/Lieb/Pages/Users/Details.cshtml b/Lieb/Pages/Users/Details.cshtml new file mode 100644 index 0000000..950e4d3 --- /dev/null +++ b/Lieb/Pages/Users/Details.cshtml @@ -0,0 +1,37 @@ +@page +@model Lieb.Pages.Users.DetailsModel + +@{ + ViewData["Title"] = "Details"; +} + +

Details

+ +
+

User

+
+
+
+ @Html.DisplayNameFor(model => model.User.DiscordUserId) +
+
+ @Html.DisplayFor(model => model.User.DiscordUserId) +
+
+ @Html.DisplayNameFor(model => model.User.Name) +
+
+ @Html.DisplayFor(model => model.User.Name) +
+
+ @Html.DisplayNameFor(model => model.User.Birthday) +
+
+ @Html.DisplayFor(model => model.User.Birthday) +
+
+
+ diff --git a/Lieb/Pages/Users/Details.cshtml.cs b/Lieb/Pages/Users/Details.cshtml.cs new file mode 100644 index 0000000..865bae2 --- /dev/null +++ b/Lieb/Pages/Users/Details.cshtml.cs @@ -0,0 +1,41 @@ +#nullable disable +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.EntityFrameworkCore; +using Lieb.Data; +using Lieb.Models; + +namespace Lieb.Pages.Users +{ + public class DetailsModel : PageModel + { + private readonly Lieb.Data.LiebContext _context; + + public DetailsModel(Lieb.Data.LiebContext context) + { + _context = context; + } + + public User User { get; set; } + + public async Task OnGetAsync(int? id) + { + if (id == null) + { + return NotFound(); + } + + User = await _context.Users.FirstOrDefaultAsync(m => m.UserId == id); + + if (User == null) + { + return NotFound(); + } + return Page(); + } + } +} diff --git a/Lieb/Pages/Users/Edit.cshtml b/Lieb/Pages/Users/Edit.cshtml new file mode 100644 index 0000000..5d53b71 --- /dev/null +++ b/Lieb/Pages/Users/Edit.cshtml @@ -0,0 +1,45 @@ +@page +@model Lieb.Pages.Users.EditModel + +@{ + ViewData["Title"] = "Edit"; +} + +

Edit

+ +

User

+
+
+
+
+
+ +
+ + + +
+
+ + + +
+
+ + + +
+
+ +
+
+
+
+ + + +@section Scripts { + @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} +} diff --git a/Lieb/Pages/Users/Edit.cshtml.cs b/Lieb/Pages/Users/Edit.cshtml.cs new file mode 100644 index 0000000..3c5b6bf --- /dev/null +++ b/Lieb/Pages/Users/Edit.cshtml.cs @@ -0,0 +1,78 @@ +#nullable disable +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.EntityFrameworkCore; +using Lieb.Data; +using Lieb.Models; + +namespace Lieb.Pages.Users +{ + public class EditModel : PageModel + { + private readonly Lieb.Data.LiebContext _context; + + public EditModel(Lieb.Data.LiebContext context) + { + _context = context; + } + + [BindProperty] + public User User { get; set; } + + public async Task OnGetAsync(int? id) + { + if (id == null) + { + return NotFound(); + } + + User = await _context.Users.FirstOrDefaultAsync(m => m.UserId == id); + + if (User == null) + { + return NotFound(); + } + return Page(); + } + + // To protect from overposting attacks, enable the specific properties you want to bind to. + // For more details, see https://aka.ms/RazorPagesCRUD. + public async Task OnPostAsync() + { + if (!ModelState.IsValid) + { + return Page(); + } + + _context.Attach(User).State = EntityState.Modified; + + try + { + await _context.SaveChangesAsync(); + } + catch (DbUpdateConcurrencyException) + { + if (!UserExists(User.UserId)) + { + return NotFound(); + } + else + { + throw; + } + } + + return RedirectToPage("./Index"); + } + + private bool UserExists(int id) + { + return _context.Users.Any(e => e.UserId == id); + } + } +} diff --git a/Lieb/Pages/Users/Index.cshtml b/Lieb/Pages/Users/Index.cshtml new file mode 100644 index 0000000..58cc046 --- /dev/null +++ b/Lieb/Pages/Users/Index.cshtml @@ -0,0 +1,48 @@ +@page +@model Lieb.Pages.Users.IndexModel + +@{ + ViewData["Title"] = "Index"; +} + +

Index

+ +

+ Create New +

+ + + + + + + + + + +@foreach (var item in Model.User) { + + + + + + +} + +
+ @Html.DisplayNameFor(model => model.User[0].DiscordUserId) + + @Html.DisplayNameFor(model => model.User[0].Name) + + @Html.DisplayNameFor(model => model.User[0].Birthday) +
+ @Html.DisplayFor(modelItem => item.DiscordUserId) + + @Html.DisplayFor(modelItem => item.Name) + + @Html.DisplayFor(modelItem => item.Birthday) + + Edit | + Details | + Delete +
diff --git a/Lieb/Pages/Users/Index.cshtml.cs b/Lieb/Pages/Users/Index.cshtml.cs new file mode 100644 index 0000000..5857ba2 --- /dev/null +++ b/Lieb/Pages/Users/Index.cshtml.cs @@ -0,0 +1,30 @@ +#nullable disable +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.EntityFrameworkCore; +using Lieb.Data; +using Lieb.Models; + +namespace Lieb.Pages.Users +{ + public class IndexModel : PageModel + { + private readonly Lieb.Data.LiebContext _context; + + public IndexModel(Lieb.Data.LiebContext context) + { + _context = context; + } + + public IList User { get;set; } + + public async Task OnGetAsync() + { + User = await _context.Users.ToListAsync(); + } + } +} diff --git a/Lieb/Pages/_ValidationScriptsPartial.cshtml b/Lieb/Pages/_ValidationScriptsPartial.cshtml new file mode 100644 index 0000000..d8a48e3 --- /dev/null +++ b/Lieb/Pages/_ValidationScriptsPartial.cshtml @@ -0,0 +1,18 @@ + + + + + + + + \ No newline at end of file diff --git a/Lieb/Program.cs b/Lieb/Program.cs index 40674ce..9869132 100644 --- a/Lieb/Program.cs +++ b/Lieb/Program.cs @@ -1,13 +1,21 @@ -using Discord.OAuth2; +using Discord.OAuth2; using Lieb.Data; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddRazorPages(); + +builder.Services.AddDbContext(options => + options.UseSqlServer(builder.Configuration.GetConnectionString("LiebContext"))); + +builder.Services.AddDatabaseDeveloperPageExceptionFilter(); + builder.Services.AddServerSideBlazor(); builder.Services.AddAuthentication(opt => { @@ -33,7 +41,20 @@ if (!app.Environment.IsDevelopment()) // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } +else +{ + app.UseDeveloperExceptionPage(); + app.UseMigrationsEndPoint(); +} +using (var scope = app.Services.CreateScope()) +{ + var services = scope.ServiceProvider; + + var context = services.GetRequiredService(); + context.Database.EnsureCreated(); + DbInitializer.Initialize(context); +} app.UseHttpsRedirection(); diff --git a/Lieb/Properties/serviceDependencies.json b/Lieb/Properties/serviceDependencies.json new file mode 100644 index 0000000..589d5e5 --- /dev/null +++ b/Lieb/Properties/serviceDependencies.json @@ -0,0 +1,8 @@ +{ + "dependencies": { + "mssql1": { + "type": "mssql", + "connectionId": "ConnectionStrings:LiebContext" + } + } +} \ No newline at end of file diff --git a/Lieb/Properties/serviceDependencies.local.json b/Lieb/Properties/serviceDependencies.local.json new file mode 100644 index 0000000..82611c9 --- /dev/null +++ b/Lieb/Properties/serviceDependencies.local.json @@ -0,0 +1,8 @@ +{ + "dependencies": { + "mssql1": { + "type": "mssql.local", + "connectionId": "ConnectionStrings:LiebContext" + } + } +} \ No newline at end of file diff --git a/Lieb/appsettings.json b/Lieb/appsettings.json index 51206b8..2731b61 100644 --- a/Lieb/appsettings.json +++ b/Lieb/appsettings.json @@ -9,5 +9,8 @@ "AppId": "942448872335220806", "AppSecret": "5tsNxK9LtFpNqxqQnLkSJ1B0HJ7P7YUF" }, - "AllowedHosts": "*" -} + "AllowedHosts": "*", + "ConnectionStrings": { + "LiebContext": "Server=(localdb)\\mssqllocaldb;Database=LiebContext-f9dae0eb-8d5c-495d-ab99-da7951e0638b;Trusted_Connection=True;MultipleActiveResultSets=true" + } +} \ No newline at end of file