From 51037a9acecb784c53696d1852e5e9182f3131a5 Mon Sep 17 00:00:00 2001 From: Scott Date: Wed, 29 Jan 2025 17:04:36 -0800 Subject: [PATCH 01/22] Add Feedback class to PC2.Models with properties A new Feedback class has been added to the PC2.Models namespace. The class includes properties: Id, FoundResource, Comments, and SubmittedAt. The Comments property uses the MaxLength attribute from System.ComponentModel.DataAnnotations to limit its length to 500 characters. --- PC2/Models/Feedback.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 PC2/Models/Feedback.cs diff --git a/PC2/Models/Feedback.cs b/PC2/Models/Feedback.cs new file mode 100644 index 00000000..b187c346 --- /dev/null +++ b/PC2/Models/Feedback.cs @@ -0,0 +1,16 @@ +using System.ComponentModel.DataAnnotations; + +namespace PC2.Models +{ + public class Feedback + { + public int Id { get; set; } // Primary key + + public bool FoundResource { get; set; } // True for "Yes", False for "No" + + [MaxLength(500)] + public string? Comments { get; set; } // Optional comments from the user + + public DateTime SubmittedAt { get; set; } // Timestamp when feedback is submitted + } +} From c6e74d0d8e9119ab8a9e5cbbc6ec0a42e4d77d3e Mon Sep 17 00:00:00 2001 From: Scott Date: Wed, 29 Jan 2025 17:09:28 -0800 Subject: [PATCH 02/22] Add DbSet to ApplicationDbContext The ApplicationDbContext class in the PC2.Data namespace now includes a new DbSet property. This addition enables CRUD operations for a new Feedback table in the database, allowing the application to store and manage user feedback. --- PC2/Data/ApplicationDbContext.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/PC2/Data/ApplicationDbContext.cs b/PC2/Data/ApplicationDbContext.cs index bddbf5ae..64f5a501 100644 --- a/PC2/Data/ApplicationDbContext.cs +++ b/PC2/Data/ApplicationDbContext.cs @@ -42,6 +42,7 @@ protected override void ConfigureConventions(ModelConfigurationBuilder builder) public virtual DbSet NewsletterFile { get; set; } public virtual DbSet HousingProgram { get; set; } + public DbSet Feedback { get; set; } // Feedback table, responsible for storing feedback from users/CRUD } internal class DateOnlyConverter : ValueConverter From d27489f1900fa3141e7297881699dc68c183be53 Mon Sep 17 00:00:00 2001 From: Scott Date: Wed, 29 Jan 2025 17:21:30 -0800 Subject: [PATCH 03/22] Add Feedback table and update Discriminator column Introduce migration 20250130011311_AddFeedbackTable to add a new Feedback table with Id, FoundResource, Comments, and SubmittedAt columns. Update the Discriminator column in the People table to have a max length of 21 characters. Reflect these changes in ApplicationDbContextModelSnapshot and update ProductVersion to 8.0.11. Remove explicit seed values in UseIdentityColumns method calls. Update BuildTargetModel in Designer file and implement Up and Down methods for the migration. --- ...0250130011311_AddFeedbackTable.Designer.cs | 557 ++++++++++++++++++ .../20250130011311_AddFeedbackTable.cs | 55 ++ .../ApplicationDbContextModelSnapshot.cs | 48 +- 3 files changed, 649 insertions(+), 11 deletions(-) create mode 100644 PC2/Data/Migrations/20250130011311_AddFeedbackTable.Designer.cs create mode 100644 PC2/Data/Migrations/20250130011311_AddFeedbackTable.cs diff --git a/PC2/Data/Migrations/20250130011311_AddFeedbackTable.Designer.cs b/PC2/Data/Migrations/20250130011311_AddFeedbackTable.Designer.cs new file mode 100644 index 00000000..a9a03ce3 --- /dev/null +++ b/PC2/Data/Migrations/20250130011311_AddFeedbackTable.Designer.cs @@ -0,0 +1,557 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using PC2.Data; + +#nullable disable + +namespace PC2.Data.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20250130011311_AddFeedbackTable")] + partial class AddFeedbackTable + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.11") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("AgencyAgencyCategory", b => + { + b.Property("AgenciesAgencyId") + .HasColumnType("int"); + + b.Property("AgencyCategoriesAgencyCategoryId") + .HasColumnType("int"); + + b.HasKey("AgenciesAgencyId", "AgencyCategoriesAgencyCategoryId"); + + b.HasIndex("AgencyCategoriesAgencyCategoryId"); + + b.ToTable("AgencyAgencyCategory"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("RoleId") + .HasColumnType("nvarchar(450)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("PC2.Models.Agency", b => + { + b.Property("AgencyId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("AgencyId")); + + b.Property("Address1") + .HasColumnType("nvarchar(max)"); + + b.Property("Address2") + .HasColumnType("nvarchar(max)"); + + b.Property("AgencyName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("AgencyName2") + .HasColumnType("nvarchar(max)"); + + b.Property("City") + .HasColumnType("nvarchar(max)"); + + b.Property("Contact") + .HasColumnType("nvarchar(max)"); + + b.Property("CrisisHelpHotline") + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .HasColumnType("nvarchar(max)"); + + b.Property("Fax") + .HasColumnType("nvarchar(max)"); + + b.Property("MailingAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("Phone") + .HasColumnType("nvarchar(max)"); + + b.Property("State") + .HasColumnType("nvarchar(max)"); + + b.Property("TDD") + .HasColumnType("nvarchar(max)"); + + b.Property("TTY") + .HasColumnType("nvarchar(max)"); + + b.Property("TollFree") + .HasColumnType("nvarchar(max)"); + + b.Property("Website") + .HasColumnType("nvarchar(max)"); + + b.Property("Zip") + .HasColumnType("nvarchar(max)"); + + b.HasKey("AgencyId"); + + b.ToTable("Agency"); + }); + + modelBuilder.Entity("PC2.Models.AgencyCategory", b => + { + b.Property("AgencyCategoryId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("AgencyCategoryId")); + + b.Property("AgencyCategoryName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("AgencyCategoryId"); + + b.ToTable("AgencyCategory"); + }); + + modelBuilder.Entity("PC2.Models.CalendarEvent", b => + { + b.Property("CalendarEventID") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("CalendarEventID")); + + b.Property("CountyEvent") + .HasColumnType("bit"); + + b.Property("DateOfEvent") + .HasColumnType("date"); + + b.Property("EndingTime") + .HasColumnType("time"); + + b.Property("EventDescription") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PC2Event") + .HasColumnType("bit"); + + b.Property("StartingTime") + .HasColumnType("time"); + + b.HasKey("CalendarEventID"); + + b.ToTable("CalendarEvents"); + }); + + modelBuilder.Entity("PC2.Models.Feedback", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Comments") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("FoundResource") + .HasColumnType("bit"); + + b.Property("SubmittedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("Feedback"); + }); + + modelBuilder.Entity("PC2.Models.HousingProgram", b => + { + b.Property("HouseHoldSize") + .HasColumnType("int"); + + b.Property("LastUpdated") + .HasColumnType("datetime2"); + + b.Property("MaximumIncome") + .HasColumnType("float"); + + b.HasKey("HouseHoldSize"); + + b.ToTable("HousingProgram"); + }); + + modelBuilder.Entity("PC2.Models.NewsletterFile", b => + { + b.Property("NewsletterId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("NewsletterId")); + + b.Property("Location") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("NewsletterId"); + + b.ToTable("NewsletterFile"); + }); + + modelBuilder.Entity("PC2.Models.People", b => + { + b.Property("ID") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("ID")); + + b.Property("Discriminator") + .IsRequired() + .HasMaxLength(21) + .HasColumnType("nvarchar(21)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PriorityOrder") + .HasColumnType("tinyint"); + + b.Property("Title") + .HasColumnType("nvarchar(max)"); + + b.HasKey("ID"); + + b.ToTable("People"); + + b.HasDiscriminator().HasValue("People"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("PC2.Models.Board", b => + { + b.HasBaseType("PC2.Models.People"); + + b.Property("MembershipStart") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasDiscriminator().HasValue("Board"); + }); + + modelBuilder.Entity("PC2.Models.Staff", b => + { + b.HasBaseType("PC2.Models.People"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Extension") + .HasColumnType("int"); + + b.Property("Phone") + .HasColumnType("nvarchar(max)"); + + b.HasDiscriminator().HasValue("Staff"); + }); + + modelBuilder.Entity("PC2.Models.SteeringCommittee", b => + { + b.HasBaseType("PC2.Models.People"); + + b.HasDiscriminator().HasValue("SteeringCommittee"); + }); + + modelBuilder.Entity("AgencyAgencyCategory", b => + { + b.HasOne("PC2.Models.Agency", null) + .WithMany() + .HasForeignKey("AgenciesAgencyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("PC2.Models.AgencyCategory", null) + .WithMany() + .HasForeignKey("AgencyCategoriesAgencyCategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/PC2/Data/Migrations/20250130011311_AddFeedbackTable.cs b/PC2/Data/Migrations/20250130011311_AddFeedbackTable.cs new file mode 100644 index 00000000..a5989ac0 --- /dev/null +++ b/PC2/Data/Migrations/20250130011311_AddFeedbackTable.cs @@ -0,0 +1,55 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace PC2.Data.Migrations +{ + /// + public partial class AddFeedbackTable : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Discriminator", + table: "People", + type: "nvarchar(21)", + maxLength: 21, + nullable: false, + oldClrType: typeof(string), + oldType: "nvarchar(max)"); + + migrationBuilder.CreateTable( + name: "Feedback", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + FoundResource = table.Column(type: "bit", nullable: false), + Comments = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: true), + SubmittedAt = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Feedback", x => x.Id); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Feedback"); + + migrationBuilder.AlterColumn( + name: "Discriminator", + table: "People", + type: "nvarchar(max)", + nullable: false, + oldClrType: typeof(string), + oldType: "nvarchar(21)", + oldMaxLength: 21); + } + } +} diff --git a/PC2/Data/Migrations/ApplicationDbContextModelSnapshot.cs b/PC2/Data/Migrations/ApplicationDbContextModelSnapshot.cs index c875ee5b..03fd92b3 100644 --- a/PC2/Data/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/PC2/Data/Migrations/ApplicationDbContextModelSnapshot.cs @@ -17,10 +17,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "6.0.5") + .HasAnnotation("ProductVersion", "8.0.11") .HasAnnotation("Relational:MaxIdentifierLength", 128); - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); modelBuilder.Entity("AgencyAgencyCategory", b => { @@ -70,7 +70,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("int"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); b.Property("ClaimType") .HasColumnType("nvarchar(max)"); @@ -160,7 +160,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("int"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); b.Property("ClaimType") .HasColumnType("nvarchar(max)"); @@ -245,7 +245,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("int"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("AgencyId"), 1L, 1); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("AgencyId")); b.Property("Address1") .HasColumnType("nvarchar(max)"); @@ -313,7 +313,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("int"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("AgencyCategoryId"), 1L, 1); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("AgencyCategoryId")); b.Property("AgencyCategoryName") .IsRequired() @@ -330,7 +330,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("int"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("CalendarEventID"), 1L, 1); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("CalendarEventID")); b.Property("CountyEvent") .HasColumnType("bit"); @@ -356,6 +356,29 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("CalendarEvents"); }); + modelBuilder.Entity("PC2.Models.Feedback", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Comments") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("FoundResource") + .HasColumnType("bit"); + + b.Property("SubmittedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("Feedback"); + }); + modelBuilder.Entity("PC2.Models.HousingProgram", b => { b.Property("HouseHoldSize") @@ -378,7 +401,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("int"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("NewsletterId"), 1L, 1); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("NewsletterId")); b.Property("Location") .IsRequired() @@ -399,11 +422,12 @@ protected override void BuildModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("int"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("ID"), 1L, 1); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("ID")); b.Property("Discriminator") .IsRequired() - .HasColumnType("nvarchar(max)"); + .HasMaxLength(21) + .HasColumnType("nvarchar(21)"); b.Property("Name") .IsRequired() @@ -419,7 +443,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("People"); - b.HasDiscriminator("Discriminator").HasValue("People"); + b.HasDiscriminator().HasValue("People"); + + b.UseTphMappingStrategy(); }); modelBuilder.Entity("PC2.Models.Board", b => From 95014756b0618a96a666fae7abafd25be8e76f56 Mon Sep 17 00:00:00 2001 From: Scott Date: Wed, 29 Jan 2025 18:36:55 -0800 Subject: [PATCH 04/22] Add FeedbackViewModel class to PC2.Models namespace Introduced a new `FeedbackViewModel` class within the `PC2.Models` namespace. This class includes properties for handling feedback data: `Id` (integer identifier), `FoundResource` (string representation of a boolean value), `Comments` (user comments), and `FormattedSubmittedAt` (formatted date string for readability). --- PC2/Models/FeedbackViewModel.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 PC2/Models/FeedbackViewModel.cs diff --git a/PC2/Models/FeedbackViewModel.cs b/PC2/Models/FeedbackViewModel.cs new file mode 100644 index 00000000..9f435ce8 --- /dev/null +++ b/PC2/Models/FeedbackViewModel.cs @@ -0,0 +1,15 @@ +namespace PC2.Models +{ + public class FeedbackViewModel + { + public int Id { get; set; } + + // Convert the boolean FoundResource to a string ("Yes"/"No") for display + public string FoundResource { get; set; } + + public string Comments { get; set; } + + // Format the date for better readability + public string FormattedSubmittedAt { get; set; } + } +} From 51efcb631500a3cfdec08c3ee79d9afe623d49cd Mon Sep 17 00:00:00 2001 From: Scott Date: Wed, 29 Jan 2025 19:45:37 -0800 Subject: [PATCH 05/22] Add "View Feedback" link to navigation menu Added a new navigation menu item for "View Feedback" in the `_Layout.cshtml` file. This link directs users to the `ViewFeedback` action in the `Resources` controller and is positioned between the "Housing Program Data" link and the "Calendar" dropdown menu. --- PC2/Views/Shared/_Layout.cshtml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/PC2/Views/Shared/_Layout.cshtml b/PC2/Views/Shared/_Layout.cshtml index da1ac818..295b4d35 100644 --- a/PC2/Views/Shared/_Layout.cshtml +++ b/PC2/Views/Shared/_Layout.cshtml @@ -86,6 +86,11 @@ cfg: { // Application Insights Configuration + ////////////// + + //////////////