From b43d7bab843d1e90ce84141a7b10b158778a1243 Mon Sep 17 00:00:00 2001 From: Harrison Deng Date: Wed, 21 Jul 2021 01:58:49 -0500 Subject: [PATCH] Ported progress from SPA and began scaffolding Identity UI. Laid some groundwork in backend. Began customizing Identity UI. --- Props/.vscode/tasks.json | 9 + .../Pages/Account/ConfirmEmail.cshtml | 7 + .../Pages/Account/ConfirmEmail.cshtml.cs | 48 +++ .../Areas/Identity/Pages/Account/Login.cshtml | 108 +++--- .../Identity/Pages/Account/Login.cshtml.cs | 7 +- .../Identity/Pages/Account/Logout.cshtml.cs | 1 + .../Pages/Account/Manage/ManageNavPages.cs | 50 +++ .../Pages/Account/Manage/_Layout.cshtml | 32 ++ .../Pages/Account/Manage/_ManageNav.cshtml | 15 + .../Account/Manage/_StatusMessage.cshtml | 10 + .../Pages/Account/Manage/_ViewImports.cshtml | 1 + .../Identity/Pages/Account/Register.cshtml | 79 ++--- .../Identity/Pages/Account/Register.cshtml.cs | 1 + .../Pages/Account/RegisterConfirmation.cshtml | 15 +- .../Account/RegisterConfirmation.cshtml.cs | 3 +- .../Areas/Identity/Pages/_ViewImports.cshtml | 2 +- Props/Content/About.json | 27 -- Props/Content/Index.json | 26 ++ Props/Data/ApplicationDbContext.cs | 1 + .../00000000000000_CreateIdentitySchema.cs | 217 ------------- ... 20210721064503_InitialCreate.Designer.cs} | 285 +++++++++++----- .../20210721064503_InitialCreate.cs | 307 ++++++++++++++++++ .../ApplicationDbContextModelSnapshot.cs | 281 +++++++++++----- .../{ => User}/ApplicationPreferences.cs | 3 +- Props/Models/{ => User}/ApplicationUser.cs | 4 +- Props/Models/{ => User}/ResultsPreferences.cs | 0 Props/Models/{ => User}/SearchOutline.cs | 0 Props/Pages/About.cshtml | 33 -- Props/Pages/Index.cshtml | 57 +++- .../{About.cshtml.cs => Search.cshtml.cs} | 2 +- Props/Pages/Shared/_Layout.cshtml | 17 +- Props/Pages/Shared/_LoginPartial.cshtml | 2 +- Props/Props.csproj | 3 +- .../ContentManager.cs} | 8 +- .../Services/{ => Content}/IContentManager.cs | 4 +- .../Modules/ShopAssemblyLoadContext.cs | 29 ++ Props/Startup.cs | 18 +- Props/appsettings.json | 8 +- Props/assets/scss/_variables.scss | 2 +- Props/assets/scss/main.scss | 39 ++- Props/package-lock.json | 38 +++ Props/package.json | 1 + Props/scripts/reset_db.py | 28 ++ Props/webpack.config.js | 17 +- 44 files changed, 1225 insertions(+), 620 deletions(-) create mode 100644 Props/Areas/Identity/Pages/Account/ConfirmEmail.cshtml create mode 100644 Props/Areas/Identity/Pages/Account/ConfirmEmail.cshtml.cs create mode 100644 Props/Areas/Identity/Pages/Account/Manage/ManageNavPages.cs create mode 100644 Props/Areas/Identity/Pages/Account/Manage/_Layout.cshtml create mode 100644 Props/Areas/Identity/Pages/Account/Manage/_ManageNav.cshtml create mode 100644 Props/Areas/Identity/Pages/Account/Manage/_StatusMessage.cshtml create mode 100644 Props/Areas/Identity/Pages/Account/Manage/_ViewImports.cshtml delete mode 100644 Props/Content/About.json delete mode 100644 Props/Data/Migrations/00000000000000_CreateIdentitySchema.cs rename Props/Data/Migrations/{00000000000000_CreateIdentitySchema.Designer.cs => 20210721064503_InitialCreate.Designer.cs} (58%) create mode 100644 Props/Data/Migrations/20210721064503_InitialCreate.cs rename Props/Models/{ => User}/ApplicationPreferences.cs (75%) rename Props/Models/{ => User}/ApplicationUser.cs (94%) rename Props/Models/{ => User}/ResultsPreferences.cs (100%) rename Props/Models/{ => User}/SearchOutline.cs (100%) delete mode 100644 Props/Pages/About.cshtml rename Props/Pages/{About.cshtml.cs => Search.cshtml.cs} (66%) rename Props/Services/{JsonContentManager.cs => Content/ContentManager.cs} (72%) rename Props/Services/{ => Content}/IContentManager.cs (50%) create mode 100644 Props/Services/Modules/ShopAssemblyLoadContext.cs create mode 100644 Props/scripts/reset_db.py diff --git a/Props/.vscode/tasks.json b/Props/.vscode/tasks.json index 595d638..c10cc38 100644 --- a/Props/.vscode/tasks.json +++ b/Props/.vscode/tasks.json @@ -37,6 +37,15 @@ "/consoleloggerparameters:NoSummary" ], "problemMatcher": "$msCompile" + }, + { + "label": "reset database", + "command": "py", + "type": "process", + "args": [ + "./scripts/reset_db.py" + ], + "problemMatcher": [] } ] } \ No newline at end of file diff --git a/Props/Areas/Identity/Pages/Account/ConfirmEmail.cshtml b/Props/Areas/Identity/Pages/Account/ConfirmEmail.cshtml new file mode 100644 index 0000000..26deba2 --- /dev/null +++ b/Props/Areas/Identity/Pages/Account/ConfirmEmail.cshtml @@ -0,0 +1,7 @@ +@page +@model ConfirmEmailModel +@{ + ViewData["Title"] = "Confirm email"; +} + +

@ViewData["Title"]

\ No newline at end of file diff --git a/Props/Areas/Identity/Pages/Account/ConfirmEmail.cshtml.cs b/Props/Areas/Identity/Pages/Account/ConfirmEmail.cshtml.cs new file mode 100644 index 0000000..894e8e8 --- /dev/null +++ b/Props/Areas/Identity/Pages/Account/ConfirmEmail.cshtml.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.AspNetCore.WebUtilities; +using Props.Models; +using Props.Models.User; + +namespace Props.Areas.Identity.Pages.Account +{ + [AllowAnonymous] + public class ConfirmEmailModel : PageModel + { + private readonly UserManager _userManager; + + public ConfirmEmailModel(UserManager userManager) + { + _userManager = userManager; + } + + [TempData] + public string StatusMessage { get; set; } + + public async Task OnGetAsync(string userId, string code) + { + if (userId == null || code == null) + { + return RedirectToPage("/Index"); + } + + var user = await _userManager.FindByIdAsync(userId); + if (user == null) + { + return NotFound($"Unable to load user with ID '{userId}'."); + } + + code = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(code)); + var result = await _userManager.ConfirmEmailAsync(user, code); + StatusMessage = result.Succeeded ? "Thank you for confirming your email." : "Error confirming your email."; + return Page(); + } + } +} diff --git a/Props/Areas/Identity/Pages/Account/Login.cshtml b/Props/Areas/Identity/Pages/Account/Login.cshtml index 72a567f..99d4780 100644 --- a/Props/Areas/Identity/Pages/Account/Login.cshtml +++ b/Props/Areas/Identity/Pages/Account/Login.cshtml @@ -5,65 +5,54 @@ ViewData["Title"] = "Log in"; } -

@ViewData["Title"]

-
-
-
-
-

Use a local account to log in.

-
-
-
- - - -
-
- - - -
-
-
- +
+
+

@ViewData["Title"]

+
+
+ +

Use a local account to log in.

+
+
+
+ + + +
+
+ + + +
+
+
+ + +
+
+
+
-
-
- -
- - -
-
-
-
-

Use another service to log in.

-
- @{ - if ((Model.ExternalLogins?.Count ?? 0) == 0) - {
-

- There are no external authentication services configured. See this article - for details on setting up this ASP.NET application to support logging in via external services. -

+ + +
- } - else - { + +
+ @if ((Model.ExternalLogins?.Count ?? 0) != 0) + { +
+

Use another service to log in.

+

@@ -74,12 +63,13 @@

- } +
} - +
+ @section Scripts { - + } diff --git a/Props/Areas/Identity/Pages/Account/Login.cshtml.cs b/Props/Areas/Identity/Pages/Account/Login.cshtml.cs index 7f1c4a5..be0f3a6 100644 --- a/Props/Areas/Identity/Pages/Account/Login.cshtml.cs +++ b/Props/Areas/Identity/Pages/Account/Login.cshtml.cs @@ -4,14 +4,15 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text.Encodings.Web; using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Logging; using Props.Models; +using Props.Models.User; namespace Props.Areas.Identity.Pages.Account { @@ -22,7 +23,7 @@ namespace Props.Areas.Identity.Pages.Account private readonly SignInManager _signInManager; private readonly ILogger _logger; - public LoginModel(SignInManager signInManager, + public LoginModel(SignInManager signInManager, ILogger logger, UserManager userManager) { @@ -77,7 +78,7 @@ namespace Props.Areas.Identity.Pages.Account returnUrl ??= Url.Content("~/"); ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); - + if (ModelState.IsValid) { // This doesn't count login failures towards account lockout diff --git a/Props/Areas/Identity/Pages/Account/Logout.cshtml.cs b/Props/Areas/Identity/Pages/Account/Logout.cshtml.cs index 9f57a37..55e3829 100644 --- a/Props/Areas/Identity/Pages/Account/Logout.cshtml.cs +++ b/Props/Areas/Identity/Pages/Account/Logout.cshtml.cs @@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Logging; using Props.Models; +using Props.Models.User; namespace Props.Areas.Identity.Pages.Account { diff --git a/Props/Areas/Identity/Pages/Account/Manage/ManageNavPages.cs b/Props/Areas/Identity/Pages/Account/Manage/ManageNavPages.cs new file mode 100644 index 0000000..921815d --- /dev/null +++ b/Props/Areas/Identity/Pages/Account/Manage/ManageNavPages.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Rendering; + +namespace Props.Areas.Identity.Pages.Account.Manage +{ + public static class ManageNavPages + { + public static string Index => "Index"; + + public static string Email => "Email"; + + public static string ChangePassword => "ChangePassword"; + + public static string DownloadPersonalData => "DownloadPersonalData"; + + public static string DeletePersonalData => "DeletePersonalData"; + + public static string ExternalLogins => "ExternalLogins"; + + public static string PersonalData => "PersonalData"; + + public static string TwoFactorAuthentication => "TwoFactorAuthentication"; + + public static string IndexNavClass(ViewContext viewContext) => PageNavClass(viewContext, Index); + + public static string EmailNavClass(ViewContext viewContext) => PageNavClass(viewContext, Email); + + public static string ChangePasswordNavClass(ViewContext viewContext) => PageNavClass(viewContext, ChangePassword); + + public static string DownloadPersonalDataNavClass(ViewContext viewContext) => PageNavClass(viewContext, DownloadPersonalData); + + public static string DeletePersonalDataNavClass(ViewContext viewContext) => PageNavClass(viewContext, DeletePersonalData); + + public static string ExternalLoginsNavClass(ViewContext viewContext) => PageNavClass(viewContext, ExternalLogins); + + public static string PersonalDataNavClass(ViewContext viewContext) => PageNavClass(viewContext, PersonalData); + + public static string TwoFactorAuthenticationNavClass(ViewContext viewContext) => PageNavClass(viewContext, TwoFactorAuthentication); + + private static string PageNavClass(ViewContext viewContext, string page) + { + var activePage = viewContext.ViewData["ActivePage"] as string + ?? System.IO.Path.GetFileNameWithoutExtension(viewContext.ActionDescriptor.DisplayName); + return string.Equals(activePage, page, StringComparison.OrdinalIgnoreCase) ? "active" : null; + } + } +} diff --git a/Props/Areas/Identity/Pages/Account/Manage/_Layout.cshtml b/Props/Areas/Identity/Pages/Account/Manage/_Layout.cshtml new file mode 100644 index 0000000..98918f6 --- /dev/null +++ b/Props/Areas/Identity/Pages/Account/Manage/_Layout.cshtml @@ -0,0 +1,32 @@ +@{ + if (ViewData.TryGetValue("ParentLayout", out var parentLayout)) + { + Layout = (string)parentLayout; + } + else + { + Layout = "/Areas/Identity/Pages/_Layout.cshtml"; + } +} + +
+

Manage your account

+ +
+

Change your account settings

+
+
+
+ +
+
+ @RenderBody() +
+
+
+
+ + +@section Scripts { +@RenderSection("Scripts", required: false) +} diff --git a/Props/Areas/Identity/Pages/Account/Manage/_ManageNav.cshtml b/Props/Areas/Identity/Pages/Account/Manage/_ManageNav.cshtml new file mode 100644 index 0000000..b5a56a7 --- /dev/null +++ b/Props/Areas/Identity/Pages/Account/Manage/_ManageNav.cshtml @@ -0,0 +1,15 @@ +@inject SignInManager SignInManager +@{ + var hasExternalLogins = (await SignInManager.GetExternalAuthenticationSchemesAsync()).Any(); +} + diff --git a/Props/Areas/Identity/Pages/Account/Manage/_StatusMessage.cshtml b/Props/Areas/Identity/Pages/Account/Manage/_StatusMessage.cshtml new file mode 100644 index 0000000..208a424 --- /dev/null +++ b/Props/Areas/Identity/Pages/Account/Manage/_StatusMessage.cshtml @@ -0,0 +1,10 @@ +@model string + +@if (!String.IsNullOrEmpty(Model)) +{ + var statusMessageClass = Model.StartsWith("Error") ? "danger" : "success"; + +} \ No newline at end of file diff --git a/Props/Areas/Identity/Pages/Account/Manage/_ViewImports.cshtml b/Props/Areas/Identity/Pages/Account/Manage/_ViewImports.cshtml new file mode 100644 index 0000000..5ccd3cd --- /dev/null +++ b/Props/Areas/Identity/Pages/Account/Manage/_ViewImports.cshtml @@ -0,0 +1 @@ +@using Props.Areas.Identity.Pages.Account.Manage diff --git a/Props/Areas/Identity/Pages/Account/Register.cshtml b/Props/Areas/Identity/Pages/Account/Register.cshtml index 96e6a9a..3df0a65 100644 --- a/Props/Areas/Identity/Pages/Account/Register.cshtml +++ b/Props/Areas/Identity/Pages/Account/Register.cshtml @@ -4,48 +4,38 @@ ViewData["Title"] = "Register"; } -

@ViewData["Title"]

- -
-
-
-

Create a new account.

-
-
-
- - - -
-
- - - -
-
- - - -
- -
-
-
-
-

Use another service to register.

-
- @{ - if ((Model.ExternalLogins?.Count ?? 0) == 0) - { -
-

- There are no external authentication services configured. See this article - for details on setting up this ASP.NET application to support logging in via external services. -

+
+
+

@ViewData["Title"]

+
+
+
+

Create a new account.

+
+
+
+ + +
- } - else - { +
+ + + +
+
+ + + +
+ +
+
+ @if ((Model.ExternalLogins?.Count ?? 0) != 0) + { +
+

Use another service to register.

+

@@ -56,12 +46,13 @@

- } +
} -
+
+ @section Scripts { - + } diff --git a/Props/Areas/Identity/Pages/Account/Register.cshtml.cs b/Props/Areas/Identity/Pages/Account/Register.cshtml.cs index ddd665c..9e47078 100644 --- a/Props/Areas/Identity/Pages/Account/Register.cshtml.cs +++ b/Props/Areas/Identity/Pages/Account/Register.cshtml.cs @@ -14,6 +14,7 @@ using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.WebUtilities; using Microsoft.Extensions.Logging; using Props.Models; +using Props.Models.User; namespace Props.Areas.Identity.Pages.Account { diff --git a/Props/Areas/Identity/Pages/Account/RegisterConfirmation.cshtml b/Props/Areas/Identity/Pages/Account/RegisterConfirmation.cshtml index c7c5d90..6c20a6d 100644 --- a/Props/Areas/Identity/Pages/Account/RegisterConfirmation.cshtml +++ b/Props/Areas/Identity/Pages/Account/RegisterConfirmation.cshtml @@ -8,15 +8,16 @@ @{ if (@Model.DisplayConfirmAccountLink) { -

- This app does not currently have a real email sender registered, see these docs for how to configure a real email sender. - Normally this would be emailed: Click here to confirm your account -

+

+ This app does not currently have a real email sender registered, see these docs for how to configure a real email sender. + Normally this would be emailed: Click here to confirm your account +

} else { -

- Please check your email to confirm your account. -

+

+ Please check your email to confirm your account. +

} } +@* TODO: https://aka.ms/aspaccountconf *@ \ No newline at end of file diff --git a/Props/Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs b/Props/Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs index c12b1ca..c5703f5 100644 --- a/Props/Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs +++ b/Props/Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs @@ -1,12 +1,13 @@ -using Microsoft.AspNetCore.Authorization; using System.Text; using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.WebUtilities; using Props.Models; +using Props.Models.User; namespace Props.Areas.Identity.Pages.Account { diff --git a/Props/Areas/Identity/Pages/_ViewImports.cshtml b/Props/Areas/Identity/Pages/_ViewImports.cshtml index 4ea9aaa..f43b3bb 100644 --- a/Props/Areas/Identity/Pages/_ViewImports.cshtml +++ b/Props/Areas/Identity/Pages/_ViewImports.cshtml @@ -2,4 +2,4 @@ @using Props.Areas.Identity @using Props.Areas.Identity.Pages @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers -@using Props.Models +@using Props.Models.User \ No newline at end of file diff --git a/Props/Content/About.json b/Props/Content/About.json deleted file mode 100644 index 6513d22..0000000 --- a/Props/Content/About.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "features": { - "description": "Props strives to be a platform where people can find and organize the material they need to complete their projects. Our features are therefore tailored to the community helping each other, as well as smart tools to quickly compare different products from different stores.", - "list": [ - { - "title": "Shopping List", - "subtitle": "We'll do it so you don't need to.", - "text": "We'll help you track the components you need. You can add descriptions, and mark things as purchased, or shipped at your convenience. You can even add components from stores that Props doesn't know about yet!" - }, - { - "title": "Product Comparison", - "subtitle": "So many shops to look through...", - "text": "There's so many online retailers nowadays that it's becoming more and more work to check all of them for what you need. With us, we'll do the searching for you. All you need to do is decide if the shipping time, cost, ratings and reviews are suitable!" - }, - { - "title": "Auto Listing Search", - "subtitle": "Need a starting point?", - "text": "Some project parts commonly used. We'll try and find these parts for you automatically. This means you can create a shopping list, and we'll try and the best fitting products for you based on your shopping list entries." - }, - { - "title": "Share It!", - "subtitle": "Show off your work!", - "text": "Have a project that you're excited about? Want to tell all your friends? We'll help. Each of your projects has a privacy setting. You can have it publically listed, unlisted, or completely private. Short link included." - } - ] - } -} \ No newline at end of file diff --git a/Props/Content/Index.json b/Props/Content/Index.json index e6a4c7e..b8ec1e7 100644 --- a/Props/Content/Index.json +++ b/Props/Content/Index.json @@ -4,5 +4,31 @@ "title": "Getting Started", "searchIntroduction": "Props is a site designed to help with the online project component shopping experience. Create project component lists and search across multiple commonly used online retail stores to find the ideal purchase.", "additionalInfo": "Take advantage of our project component manager, where you can add detailed descriptions of what things are for, as well as overall project summaries." + }, + "mission": "Our mission is to bring become digital project workshop for anyone who likes Do It Yourself (DIY), Internet Of Things (IOT), or really any project that needs a home for all the materials, ideas, and thoughts. We also strive to build a community of builders, crafters and creators in hopes that we can all learn from each other's projects.", + "features": { + "description": "Props strives to be a platform where people can find and organize the material they need to complete their projects. Our features are therefore tailored to the community helping each other, as well as smart tools to quickly compare different products from different stores.", + "list": [ + { + "title": "Shopping List", + "subtitle": "We'll do it so you don't need to.", + "text": "We'll help you track the components you need. You can add descriptions, and mark things as purchased, or shipped at your convenience. You can even add components from stores that Props doesn't know about yet!" + }, + { + "title": "Product Comparison", + "subtitle": "So many shops to look through...", + "text": "There's so many online retailers nowadays that it's becoming more and more work to check all of them for what you need. With us, we'll do the searching for you. All you need to do is decide if the shipping time, cost, ratings and reviews are suitable!" + }, + { + "title": "Auto Listing Search", + "subtitle": "Need a starting point?", + "text": "Some project parts commonly used. We'll try and find these parts for you automatically. This means you can create a shopping list, and we'll try and the best fitting products for you based on your shopping list entries." + }, + { + "title": "Share It!", + "subtitle": "Show off your work!", + "text": "Have a project that you're excited about? Want to tell all your friends? We'll help. Each of your projects has a privacy setting. You can have it publically listed, unlisted, or completely private. Short link included." + } + ] } } \ No newline at end of file diff --git a/Props/Data/ApplicationDbContext.cs b/Props/Data/ApplicationDbContext.cs index 4e1e5f6..523db02 100644 --- a/Props/Data/ApplicationDbContext.cs +++ b/Props/Data/ApplicationDbContext.cs @@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.ChangeTracking; using Props.Models; +using Props.Models.User; using Props.Shop.Framework; namespace Props.Data diff --git a/Props/Data/Migrations/00000000000000_CreateIdentitySchema.cs b/Props/Data/Migrations/00000000000000_CreateIdentitySchema.cs deleted file mode 100644 index 4b9f0b9..0000000 --- a/Props/Data/Migrations/00000000000000_CreateIdentitySchema.cs +++ /dev/null @@ -1,217 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -namespace Props.Data.Migrations -{ - public partial class CreateIdentitySchema : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "AspNetRoles", - columns: table => new - { - Id = table.Column(nullable: false), - Name = table.Column(maxLength: 256, nullable: true), - NormalizedName = table.Column(maxLength: 256, nullable: true), - ConcurrencyStamp = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetRoles", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "AspNetUsers", - columns: table => new - { - Id = table.Column(nullable: false), - UserName = table.Column(maxLength: 256, nullable: true), - NormalizedUserName = table.Column(maxLength: 256, nullable: true), - Email = table.Column(maxLength: 256, nullable: true), - NormalizedEmail = table.Column(maxLength: 256, nullable: true), - EmailConfirmed = table.Column(nullable: false), - PasswordHash = table.Column(nullable: true), - SecurityStamp = table.Column(nullable: true), - ConcurrencyStamp = table.Column(nullable: true), - PhoneNumber = table.Column(nullable: true), - PhoneNumberConfirmed = table.Column(nullable: false), - TwoFactorEnabled = table.Column(nullable: false), - LockoutEnd = table.Column(nullable: true), - LockoutEnabled = table.Column(nullable: false), - AccessFailedCount = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUsers", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "AspNetRoleClaims", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Sqlite:Autoincrement", true), - RoleId = table.Column(nullable: false), - ClaimType = table.Column(nullable: true), - ClaimValue = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id); - table.ForeignKey( - name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", - column: x => x.RoleId, - principalTable: "AspNetRoles", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AspNetUserClaims", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Sqlite:Autoincrement", true), - UserId = table.Column(nullable: false), - ClaimType = table.Column(nullable: true), - ClaimValue = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUserClaims", x => x.Id); - table.ForeignKey( - name: "FK_AspNetUserClaims_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AspNetUserLogins", - columns: table => new - { - LoginProvider = table.Column(maxLength: 128, nullable: false), - ProviderKey = table.Column(maxLength: 128, nullable: false), - ProviderDisplayName = table.Column(nullable: true), - UserId = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); - table.ForeignKey( - name: "FK_AspNetUserLogins_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AspNetUserRoles", - columns: table => new - { - UserId = table.Column(nullable: false), - RoleId = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId }); - table.ForeignKey( - name: "FK_AspNetUserRoles_AspNetRoles_RoleId", - column: x => x.RoleId, - principalTable: "AspNetRoles", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_AspNetUserRoles_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AspNetUserTokens", - columns: table => new - { - UserId = table.Column(nullable: false), - LoginProvider = table.Column(maxLength: 128, nullable: false), - Name = table.Column(maxLength: 128, nullable: false), - Value = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); - table.ForeignKey( - name: "FK_AspNetUserTokens_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "IX_AspNetRoleClaims_RoleId", - table: "AspNetRoleClaims", - column: "RoleId"); - - migrationBuilder.CreateIndex( - name: "RoleNameIndex", - table: "AspNetRoles", - column: "NormalizedName", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_AspNetUserClaims_UserId", - table: "AspNetUserClaims", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_AspNetUserLogins_UserId", - table: "AspNetUserLogins", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_AspNetUserRoles_RoleId", - table: "AspNetUserRoles", - column: "RoleId"); - - migrationBuilder.CreateIndex( - name: "EmailIndex", - table: "AspNetUsers", - column: "NormalizedEmail"); - - migrationBuilder.CreateIndex( - name: "UserNameIndex", - table: "AspNetUsers", - column: "NormalizedUserName", - unique: true); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "AspNetRoleClaims"); - - migrationBuilder.DropTable( - name: "AspNetUserClaims"); - - migrationBuilder.DropTable( - name: "AspNetUserLogins"); - - migrationBuilder.DropTable( - name: "AspNetUserRoles"); - - migrationBuilder.DropTable( - name: "AspNetUserTokens"); - - migrationBuilder.DropTable( - name: "AspNetRoles"); - - migrationBuilder.DropTable( - name: "AspNetUsers"); - } - } -} diff --git a/Props/Data/Migrations/00000000000000_CreateIdentitySchema.Designer.cs b/Props/Data/Migrations/20210721064503_InitialCreate.Designer.cs similarity index 58% rename from Props/Data/Migrations/00000000000000_CreateIdentitySchema.Designer.cs rename to Props/Data/Migrations/20210721064503_InitialCreate.Designer.cs index 968de3d..1672d28 100644 --- a/Props/Data/Migrations/00000000000000_CreateIdentitySchema.Designer.cs +++ b/Props/Data/Migrations/20210721064503_InitialCreate.Designer.cs @@ -1,22 +1,22 @@ -// +// using System; -using Props.Data; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Props.Data; namespace Props.Data.Migrations { [DbContext(typeof(ApplicationDbContext))] - [Migration("00000000000000_CreateIdentitySchema")] - partial class CreateIdentitySchema + [Migration("20210721064503_InitialCreate")] + partial class InitialCreate { protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "3.0.0"); + .HasAnnotation("ProductVersion", "5.0.8"); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => { @@ -28,18 +28,18 @@ namespace Props.Data.Migrations .HasColumnType("TEXT"); b.Property("Name") - .HasColumnType("TEXT") - .HasMaxLength(256); + .HasMaxLength(256) + .HasColumnType("TEXT"); b.Property("NormalizedName") - .HasColumnType("TEXT") - .HasMaxLength(256); + .HasMaxLength(256) + .HasColumnType("TEXT"); b.HasKey("Id"); b.HasIndex("NormalizedName") .IsUnique() - .HasName("RoleNameIndex"); + .HasDatabaseName("RoleNameIndex"); b.ToTable("AspNetRoles"); }); @@ -67,70 +67,6 @@ namespace Props.Data.Migrations b.ToTable("AspNetRoleClaims"); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => - { - b.Property("Id") - .HasColumnType("TEXT"); - - b.Property("AccessFailedCount") - .HasColumnType("INTEGER"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("TEXT"); - - b.Property("Email") - .HasColumnType("TEXT") - .HasMaxLength(256); - - b.Property("EmailConfirmed") - .HasColumnType("INTEGER"); - - b.Property("LockoutEnabled") - .HasColumnType("INTEGER"); - - b.Property("LockoutEnd") - .HasColumnType("TEXT"); - - b.Property("NormalizedEmail") - .HasColumnType("TEXT") - .HasMaxLength(256); - - b.Property("NormalizedUserName") - .HasColumnType("TEXT") - .HasMaxLength(256); - - b.Property("PasswordHash") - .HasColumnType("TEXT"); - - b.Property("PhoneNumber") - .HasColumnType("TEXT"); - - b.Property("PhoneNumberConfirmed") - .HasColumnType("INTEGER"); - - b.Property("SecurityStamp") - .HasColumnType("TEXT"); - - b.Property("TwoFactorEnabled") - .HasColumnType("INTEGER"); - - b.Property("UserName") - .HasColumnType("TEXT") - .HasMaxLength(256); - - b.HasKey("Id"); - - b.HasIndex("NormalizedEmail") - .HasName("EmailIndex"); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasName("UserNameIndex"); - - b.ToTable("AspNetUsers"); - }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { b.Property("Id") @@ -157,12 +93,12 @@ namespace Props.Data.Migrations modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => { b.Property("LoginProvider") - .HasColumnType("TEXT") - .HasMaxLength(128); + .HasMaxLength(128) + .HasColumnType("TEXT"); b.Property("ProviderKey") - .HasColumnType("TEXT") - .HasMaxLength(128); + .HasMaxLength(128) + .HasColumnType("TEXT"); b.Property("ProviderDisplayName") .HasColumnType("TEXT"); @@ -199,12 +135,12 @@ namespace Props.Data.Migrations .HasColumnType("TEXT"); b.Property("LoginProvider") - .HasColumnType("TEXT") - .HasMaxLength(128); + .HasMaxLength(128) + .HasColumnType("TEXT"); b.Property("Name") - .HasColumnType("TEXT") - .HasMaxLength(128); + .HasMaxLength(128) + .HasColumnType("TEXT"); b.Property("Value") .HasColumnType("TEXT"); @@ -214,6 +150,144 @@ namespace Props.Data.Migrations b.ToTable("AspNetUserTokens"); }); + modelBuilder.Entity("Props.Models.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Props.Models.ResultsPreferences", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApplicationUserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Order") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationUserId") + .IsUnique(); + + b.ToTable("ResultsPreferences"); + }); + + modelBuilder.Entity("Props.Models.SearchOutline", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApplicationUserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Filters") + .HasColumnType("TEXT"); + + b.Property("MaxResults") + .HasColumnType("INTEGER"); + + b.Property("ShopStates") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationUserId") + .IsUnique(); + + b.ToTable("SearchOutline"); + }); + + modelBuilder.Entity("Props.Shared.Models.User.ApplicationPreferences", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApplicationUserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DarkMode") + .HasColumnType("INTEGER"); + + b.Property("EnableSearchHistory") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationUserId") + .IsUnique(); + + b.ToTable("ApplicationPreferences"); + }); + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => { b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) @@ -225,7 +299,7 @@ namespace Props.Data.Migrations modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + b.HasOne("Props.Models.ApplicationUser", null) .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) @@ -234,7 +308,7 @@ namespace Props.Data.Migrations modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + b.HasOne("Props.Models.ApplicationUser", null) .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) @@ -249,7 +323,7 @@ namespace Props.Data.Migrations .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + b.HasOne("Props.Models.ApplicationUser", null) .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) @@ -258,12 +332,51 @@ namespace Props.Data.Migrations modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + b.HasOne("Props.Models.ApplicationUser", null) .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); + + modelBuilder.Entity("Props.Models.ResultsPreferences", b => + { + b.HasOne("Props.Models.ApplicationUser", null) + .WithOne("ResultsPreferences") + .HasForeignKey("Props.Models.ResultsPreferences", "ApplicationUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Props.Models.SearchOutline", b => + { + b.HasOne("Props.Models.ApplicationUser", null) + .WithOne("SearchOutline") + .HasForeignKey("Props.Models.SearchOutline", "ApplicationUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Props.Shared.Models.User.ApplicationPreferences", b => + { + b.HasOne("Props.Models.ApplicationUser", null) + .WithOne("ApplicationPreferences") + .HasForeignKey("Props.Shared.Models.User.ApplicationPreferences", "ApplicationUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Props.Models.ApplicationUser", b => + { + b.Navigation("ApplicationPreferences") + .IsRequired(); + + b.Navigation("ResultsPreferences") + .IsRequired(); + + b.Navigation("SearchOutline") + .IsRequired(); + }); #pragma warning restore 612, 618 } } diff --git a/Props/Data/Migrations/20210721064503_InitialCreate.cs b/Props/Data/Migrations/20210721064503_InitialCreate.cs new file mode 100644 index 0000000..da1d645 --- /dev/null +++ b/Props/Data/Migrations/20210721064503_InitialCreate.cs @@ -0,0 +1,307 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Props.Data.Migrations +{ + public partial class InitialCreate : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "AspNetRoles", + columns: table => new + { + Id = table.Column(type: "TEXT", nullable: false), + Name = table.Column(type: "TEXT", maxLength: 256, nullable: true), + NormalizedName = table.Column(type: "TEXT", maxLength: 256, nullable: true), + ConcurrencyStamp = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoles", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetUsers", + columns: table => new + { + Id = table.Column(type: "TEXT", nullable: false), + UserName = table.Column(type: "TEXT", maxLength: 256, nullable: true), + NormalizedUserName = table.Column(type: "TEXT", maxLength: 256, nullable: true), + Email = table.Column(type: "TEXT", maxLength: 256, nullable: true), + NormalizedEmail = table.Column(type: "TEXT", maxLength: 256, nullable: true), + EmailConfirmed = table.Column(type: "INTEGER", nullable: false), + PasswordHash = table.Column(type: "TEXT", nullable: true), + SecurityStamp = table.Column(type: "TEXT", nullable: true), + ConcurrencyStamp = table.Column(type: "TEXT", nullable: true), + PhoneNumber = table.Column(type: "TEXT", nullable: true), + PhoneNumberConfirmed = table.Column(type: "INTEGER", nullable: false), + TwoFactorEnabled = table.Column(type: "INTEGER", nullable: false), + LockoutEnd = table.Column(type: "TEXT", nullable: true), + LockoutEnabled = table.Column(type: "INTEGER", nullable: false), + AccessFailedCount = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUsers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetRoleClaims", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + RoleId = table.Column(type: "TEXT", nullable: false), + ClaimType = table.Column(type: "TEXT", nullable: true), + ClaimValue = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ApplicationPreferences", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + ApplicationUserId = table.Column(type: "TEXT", nullable: false), + EnableSearchHistory = table.Column(type: "INTEGER", nullable: false), + DarkMode = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApplicationPreferences", x => x.Id); + table.ForeignKey( + name: "FK_ApplicationPreferences_AspNetUsers_ApplicationUserId", + column: x => x.ApplicationUserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserClaims", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + UserId = table.Column(type: "TEXT", nullable: false), + ClaimType = table.Column(type: "TEXT", nullable: true), + ClaimValue = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetUserClaims_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserLogins", + columns: table => new + { + LoginProvider = table.Column(type: "TEXT", maxLength: 128, nullable: false), + ProviderKey = table.Column(type: "TEXT", maxLength: 128, nullable: false), + ProviderDisplayName = table.Column(type: "TEXT", nullable: true), + UserId = table.Column(type: "TEXT", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); + table.ForeignKey( + name: "FK_AspNetUserLogins_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserRoles", + columns: table => new + { + UserId = table.Column(type: "TEXT", nullable: false), + RoleId = table.Column(type: "TEXT", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId }); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserTokens", + columns: table => new + { + UserId = table.Column(type: "TEXT", nullable: false), + LoginProvider = table.Column(type: "TEXT", maxLength: 128, nullable: false), + Name = table.Column(type: "TEXT", maxLength: 128, nullable: false), + Value = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_AspNetUserTokens_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ResultsPreferences", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + ApplicationUserId = table.Column(type: "TEXT", nullable: false), + Order = table.Column(type: "TEXT", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ResultsPreferences", x => x.Id); + table.ForeignKey( + name: "FK_ResultsPreferences_AspNetUsers_ApplicationUserId", + column: x => x.ApplicationUserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "SearchOutline", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + ApplicationUserId = table.Column(type: "TEXT", nullable: false), + Filters = table.Column(type: "TEXT", nullable: true), + MaxResults = table.Column(type: "INTEGER", nullable: false), + ShopStates = table.Column(type: "TEXT", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_SearchOutline", x => x.Id); + table.ForeignKey( + name: "FK_SearchOutline_AspNetUsers_ApplicationUserId", + column: x => x.ApplicationUserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_ApplicationPreferences_ApplicationUserId", + table: "ApplicationPreferences", + column: "ApplicationUserId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_AspNetRoleClaims_RoleId", + table: "AspNetRoleClaims", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "RoleNameIndex", + table: "AspNetRoles", + column: "NormalizedName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserClaims_UserId", + table: "AspNetUserClaims", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserLogins_UserId", + table: "AspNetUserLogins", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserRoles_RoleId", + table: "AspNetUserRoles", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "EmailIndex", + table: "AspNetUsers", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + table: "AspNetUsers", + column: "NormalizedUserName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_ResultsPreferences_ApplicationUserId", + table: "ResultsPreferences", + column: "ApplicationUserId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_SearchOutline_ApplicationUserId", + table: "SearchOutline", + column: "ApplicationUserId", + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ApplicationPreferences"); + + migrationBuilder.DropTable( + name: "AspNetRoleClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserLogins"); + + migrationBuilder.DropTable( + name: "AspNetUserRoles"); + + migrationBuilder.DropTable( + name: "AspNetUserTokens"); + + migrationBuilder.DropTable( + name: "ResultsPreferences"); + + migrationBuilder.DropTable( + name: "SearchOutline"); + + migrationBuilder.DropTable( + name: "AspNetRoles"); + + migrationBuilder.DropTable( + name: "AspNetUsers"); + } + } +} diff --git a/Props/Data/Migrations/ApplicationDbContextModelSnapshot.cs b/Props/Data/Migrations/ApplicationDbContextModelSnapshot.cs index 0ff3ad7..5039d0f 100644 --- a/Props/Data/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/Props/Data/Migrations/ApplicationDbContextModelSnapshot.cs @@ -1,9 +1,9 @@ -// +// using System; -using Props.Data; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Props.Data; namespace Props.Data.Migrations { @@ -14,7 +14,7 @@ namespace Props.Data.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "3.0.0"); + .HasAnnotation("ProductVersion", "5.0.8"); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => { @@ -26,18 +26,18 @@ namespace Props.Data.Migrations .HasColumnType("TEXT"); b.Property("Name") - .HasColumnType("TEXT") - .HasMaxLength(256); + .HasMaxLength(256) + .HasColumnType("TEXT"); b.Property("NormalizedName") - .HasColumnType("TEXT") - .HasMaxLength(256); + .HasMaxLength(256) + .HasColumnType("TEXT"); b.HasKey("Id"); b.HasIndex("NormalizedName") .IsUnique() - .HasName("RoleNameIndex"); + .HasDatabaseName("RoleNameIndex"); b.ToTable("AspNetRoles"); }); @@ -65,70 +65,6 @@ namespace Props.Data.Migrations b.ToTable("AspNetRoleClaims"); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => - { - b.Property("Id") - .HasColumnType("TEXT"); - - b.Property("AccessFailedCount") - .HasColumnType("INTEGER"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("TEXT"); - - b.Property("Email") - .HasColumnType("TEXT") - .HasMaxLength(256); - - b.Property("EmailConfirmed") - .HasColumnType("INTEGER"); - - b.Property("LockoutEnabled") - .HasColumnType("INTEGER"); - - b.Property("LockoutEnd") - .HasColumnType("TEXT"); - - b.Property("NormalizedEmail") - .HasColumnType("TEXT") - .HasMaxLength(256); - - b.Property("NormalizedUserName") - .HasColumnType("TEXT") - .HasMaxLength(256); - - b.Property("PasswordHash") - .HasColumnType("TEXT"); - - b.Property("PhoneNumber") - .HasColumnType("TEXT"); - - b.Property("PhoneNumberConfirmed") - .HasColumnType("INTEGER"); - - b.Property("SecurityStamp") - .HasColumnType("TEXT"); - - b.Property("TwoFactorEnabled") - .HasColumnType("INTEGER"); - - b.Property("UserName") - .HasColumnType("TEXT") - .HasMaxLength(256); - - b.HasKey("Id"); - - b.HasIndex("NormalizedEmail") - .HasName("EmailIndex"); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasName("UserNameIndex"); - - b.ToTable("AspNetUsers"); - }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { b.Property("Id") @@ -155,12 +91,12 @@ namespace Props.Data.Migrations modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => { b.Property("LoginProvider") - .HasColumnType("TEXT") - .HasMaxLength(128); + .HasMaxLength(128) + .HasColumnType("TEXT"); b.Property("ProviderKey") - .HasColumnType("TEXT") - .HasMaxLength(128); + .HasMaxLength(128) + .HasColumnType("TEXT"); b.Property("ProviderDisplayName") .HasColumnType("TEXT"); @@ -197,12 +133,12 @@ namespace Props.Data.Migrations .HasColumnType("TEXT"); b.Property("LoginProvider") - .HasColumnType("TEXT") - .HasMaxLength(128); + .HasMaxLength(128) + .HasColumnType("TEXT"); b.Property("Name") - .HasColumnType("TEXT") - .HasMaxLength(128); + .HasMaxLength(128) + .HasColumnType("TEXT"); b.Property("Value") .HasColumnType("TEXT"); @@ -212,6 +148,144 @@ namespace Props.Data.Migrations b.ToTable("AspNetUserTokens"); }); + modelBuilder.Entity("Props.Models.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Props.Models.ResultsPreferences", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApplicationUserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Order") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationUserId") + .IsUnique(); + + b.ToTable("ResultsPreferences"); + }); + + modelBuilder.Entity("Props.Models.SearchOutline", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApplicationUserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Filters") + .HasColumnType("TEXT"); + + b.Property("MaxResults") + .HasColumnType("INTEGER"); + + b.Property("ShopStates") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationUserId") + .IsUnique(); + + b.ToTable("SearchOutline"); + }); + + modelBuilder.Entity("Props.Shared.Models.User.ApplicationPreferences", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApplicationUserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DarkMode") + .HasColumnType("INTEGER"); + + b.Property("EnableSearchHistory") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationUserId") + .IsUnique(); + + b.ToTable("ApplicationPreferences"); + }); + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => { b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) @@ -223,7 +297,7 @@ namespace Props.Data.Migrations modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + b.HasOne("Props.Models.ApplicationUser", null) .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) @@ -232,7 +306,7 @@ namespace Props.Data.Migrations modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + b.HasOne("Props.Models.ApplicationUser", null) .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) @@ -247,7 +321,7 @@ namespace Props.Data.Migrations .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + b.HasOne("Props.Models.ApplicationUser", null) .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) @@ -256,12 +330,51 @@ namespace Props.Data.Migrations modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + b.HasOne("Props.Models.ApplicationUser", null) .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); + + modelBuilder.Entity("Props.Models.ResultsPreferences", b => + { + b.HasOne("Props.Models.ApplicationUser", null) + .WithOne("ResultsPreferences") + .HasForeignKey("Props.Models.ResultsPreferences", "ApplicationUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Props.Models.SearchOutline", b => + { + b.HasOne("Props.Models.ApplicationUser", null) + .WithOne("SearchOutline") + .HasForeignKey("Props.Models.SearchOutline", "ApplicationUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Props.Shared.Models.User.ApplicationPreferences", b => + { + b.HasOne("Props.Models.ApplicationUser", null) + .WithOne("ApplicationPreferences") + .HasForeignKey("Props.Shared.Models.User.ApplicationPreferences", "ApplicationUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Props.Models.ApplicationUser", b => + { + b.Navigation("ApplicationPreferences") + .IsRequired(); + + b.Navigation("ResultsPreferences") + .IsRequired(); + + b.Navigation("SearchOutline") + .IsRequired(); + }); #pragma warning restore 612, 618 } } diff --git a/Props/Models/ApplicationPreferences.cs b/Props/Models/User/ApplicationPreferences.cs similarity index 75% rename from Props/Models/ApplicationPreferences.cs rename to Props/Models/User/ApplicationPreferences.cs index 0750f8a..970ffe9 100644 --- a/Props/Models/ApplicationPreferences.cs +++ b/Props/Models/User/ApplicationPreferences.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations; -namespace Props.Shared.Models +namespace Props.Shared.Models.User { public class ApplicationPreferences { @@ -10,5 +10,6 @@ namespace Props.Shared.Models public string ApplicationUserId { get; set; } public bool EnableSearchHistory { get; set; } = true; + public bool DarkMode { get; set; } = false; } } \ No newline at end of file diff --git a/Props/Models/ApplicationUser.cs b/Props/Models/User/ApplicationUser.cs similarity index 94% rename from Props/Models/ApplicationUser.cs rename to Props/Models/User/ApplicationUser.cs index 0a90868..af9c4d9 100644 --- a/Props/Models/ApplicationUser.cs +++ b/Props/Models/User/ApplicationUser.cs @@ -4,9 +4,9 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Identity; -using Props.Shared.Models; +using Props.Shared.Models.User; -namespace Props.Models +namespace Props.Models.User { public class ApplicationUser : IdentityUser { diff --git a/Props/Models/ResultsPreferences.cs b/Props/Models/User/ResultsPreferences.cs similarity index 100% rename from Props/Models/ResultsPreferences.cs rename to Props/Models/User/ResultsPreferences.cs diff --git a/Props/Models/SearchOutline.cs b/Props/Models/User/SearchOutline.cs similarity index 100% rename from Props/Models/SearchOutline.cs rename to Props/Models/User/SearchOutline.cs diff --git a/Props/Pages/About.cshtml b/Props/Pages/About.cshtml deleted file mode 100644 index 4660198..0000000 --- a/Props/Pages/About.cshtml +++ /dev/null @@ -1,33 +0,0 @@ -@page -@using Props.Services -@inject IContentManager ContentManager - -@{ - ViewData["Title"] = "About"; -} -
-
-

Features

-

- @ContentManager.Content.features.description -

-
-
-
- @foreach (dynamic feature in ContentManager.Content.features.list) - { -
-
-
@feature.title
-
- @feature.subtitle -
-

- @feature.text -

-
-
- } -
-
-
\ No newline at end of file diff --git a/Props/Pages/Index.cshtml b/Props/Pages/Index.cshtml index 80bd51f..276623d 100644 --- a/Props/Pages/Index.cshtml +++ b/Props/Pages/Index.cshtml @@ -1,26 +1,27 @@ @page -@using Props.Services +@using Props.Services.Content @model IndexModel @inject IContentManager ContentManager @{ ViewData["Title"] = "Home page"; } -
+
Props logo

Props

- @ContentManager.Content.description + @ContentManager.Json.description

-
-
-
+ + +
+
-

@ContentManager.Content.help.title

+

@ContentManager.Json.help.title

@@ -28,10 +29,46 @@

- @ContentManager.Content.help.searchIntroduction + @ContentManager.Json.help.searchIntroduction

- @ContentManager.Content.help.additionalInfo + @ContentManager.Json.help.additionalInfo

-
\ No newline at end of file + + +
+

Our Mission

+

+ @ContentManager.Json.mission +

+
+ +
+ +
+
+

Features

+

+ @ContentManager.Json.features.description +

+
+
+
+ @foreach (dynamic feature in ContentManager.Json.features.list) + { +
+
+
@feature.title
+
+ @feature.subtitle +
+

+ @feature.text +

+
+
+ } +
+
+
\ No newline at end of file diff --git a/Props/Pages/About.cshtml.cs b/Props/Pages/Search.cshtml.cs similarity index 66% rename from Props/Pages/About.cshtml.cs rename to Props/Pages/Search.cshtml.cs index 1788c21..74e9cd0 100644 --- a/Props/Pages/About.cshtml.cs +++ b/Props/Pages/Search.cshtml.cs @@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Mvc.RazorPages; namespace Props.Pages { - public class AboutModel : PageModel + public class SearchModel : PageModel { } diff --git a/Props/Pages/Shared/_Layout.cshtml b/Props/Pages/Shared/_Layout.cshtml index 04bc0c6..287215d 100644 --- a/Props/Pages/Shared/_Layout.cshtml +++ b/Props/Pages/Shared/_Layout.cshtml @@ -1,5 +1,5 @@ @using Microsoft.AspNetCore.Identity -@using Props.Models +@using Props.Models.User @inject SignInManager SignInManager @inject UserManager UserManager @@ -21,27 +21,24 @@