diff --git a/Model/Question.cs b/Model/Question.cs index 9aa9724..44675eb 100644 --- a/Model/Question.cs +++ b/Model/Question.cs @@ -9,16 +9,19 @@ namespace Model { public class Question { + public Question() + { + Answers=new List(); + } public int Id { get; set; } public string? Text { get; set; } public QuestionType Type { get; set; } - // Foreign key for Questionnaire - - public int QuestionnaireId { get; set; } // Foreign key for Questionnaire + + public int QuestionnaireId { get; set; } [ForeignKey("QuestionnaireId")] public Questionnaire? Questionnaire { get; set; } - public List? Answers { get; set; } + public List Answers { get; set; } } } diff --git a/Model/Questionnaire.cs b/Model/Questionnaire.cs index 7ea572d..38caed3 100644 --- a/Model/Questionnaire.cs +++ b/Model/Questionnaire.cs @@ -8,6 +8,10 @@ namespace Model { public class Questionnaire { + public Questionnaire() + { + Questions = new List(); + } public int Id { get; set; } public string? Title { get; set; } public string? Description { get; set; } diff --git a/Services/Implemnetation/QuestionRepository.cs b/Services/Implemnetation/QuestionRepository.cs new file mode 100644 index 0000000..85761b7 --- /dev/null +++ b/Services/Implemnetation/QuestionRepository.cs @@ -0,0 +1,40 @@ +using Data; +using Model; +using Services.Interaces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Services.Implemnetation +{ + public class QuestionRepository : IQuestionRepository + { + private readonly SurveyContext _context; + + public QuestionRepository(SurveyContext context) + { + _context = context; + } + public void Add(Question question) + { + _context.Questions.Add(question); + } + + public async Task commitAsync() + { + await _context.SaveChangesAsync(); + } + + public List GetAllQuestions() + { + throw new NotImplementedException(); + } + + public Question GetQuestionById(int id) + { + throw new NotImplementedException(); + } + } +} diff --git a/Services/Interaces/IQuestionRepository.cs b/Services/Interaces/IQuestionRepository.cs new file mode 100644 index 0000000..cc23652 --- /dev/null +++ b/Services/Interaces/IQuestionRepository.cs @@ -0,0 +1,20 @@ +using Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Services.Interaces +{ + public interface IQuestionRepository + { + List GetAllQuestions(); + + Question GetQuestionById(int id); + + void Add(Question question); + + Task commitAsync(); + } +} diff --git a/Web/Areas/Admin/Controllers/QuestionnaireController.cs b/Web/Areas/Admin/Controllers/QuestionnaireController.cs index 0851d7b..b7f967c 100644 --- a/Web/Areas/Admin/Controllers/QuestionnaireController.cs +++ b/Web/Areas/Admin/Controllers/QuestionnaireController.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Mvc; +using Data; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; using Model; using Services.Interaces; @@ -9,10 +10,14 @@ namespace Web.Areas.Admin.Controllers public class QuestionnaireController : Controller { private readonly IQuestionnaireRepository _questionnaire; + private readonly SurveyContext _context; + private readonly IQuestionRepository _question; - public QuestionnaireController(IQuestionnaireRepository Questionnaire) + public QuestionnaireController(IQuestionnaireRepository Questionnaire,SurveyContext Context, IQuestionRepository Question) { _questionnaire = Questionnaire; + _context = Context; + _question = Question; } public IActionResult Index() { @@ -37,45 +42,113 @@ namespace Web.Areas.Admin.Controllers } [HttpGet] public IActionResult Create() + + { var questionTypes = Enum.GetValues(typeof(QuestionType)).Cast(); + ViewBag.QuestionTypes = new SelectList(questionTypes); + var questionnaire = new QuestionnaireViewModel { - Questions = new List() + + Questions = new List(), + Answers = new List() + + + }; + + + return View(questionnaire); } [HttpPost] - public IActionResult Create(QuestionnaireViewModel viewmodel) + public async Task Create(QuestionnaireViewModel viewmodel) { - if(ModelState.IsValid) + + + + if (ModelState.IsValid) { var questionnaire = new Questionnaire { - Id = viewmodel.Id, - Title = viewmodel.Title, - Description = viewmodel.Description, - + Id=viewmodel.Id, + Title=viewmodel.Title, + Description=viewmodel.Description, }; - foreach (var item in viewmodel.Questions) + + var questions = viewmodel.Questions; + + foreach (var questionViewModel in viewmodel.Questions) { - questionnaire.Questions.Add(item); + var question = new Question + { + QuestionnaireId=questionViewModel.QuestionnaireId, + Text = questionViewModel.Text, + Type = questionViewModel.Type, + Answers = new List() // Initialize the list of answers for each question + }; + + foreach (var answerViewModel in questionViewModel.Answers) + { + var answer = new Answer + { + Text = answerViewModel.Text, + QuestionId=answerViewModel.QuestionId, + + }; + + // Add the answer to the list of answers for the current question + question.Answers.Add(answer); + } + + // Add the question to the list of questions for the questionnaire + questionnaire.Questions.Add(question); } + + //var answers = questions.Where(x => x.Answers == viewmodel.Answers); + + + //foreach (var question in questions) + //{ + + // questionnaire.Questions.Add(new Question + // { + // Id = question.Id, + // Text=question.Text, + // Type=question.Type, + // QuestionnaireId=questionnaire.Id, + + + // }); + + // //foreach(var answer in answers) + // //{ + // // question.Answers.Add(new Answer + // // { + // // Id=answer + // // }); + // //} + + + //} + _questionnaire.Add(questionnaire); - - _questionnaire.commitAsync(); + await _questionnaire.commitAsync(); + TempData["Success"] = "Questionnaire created successfully"; - return RedirectToAction(nameof(Index)); + + return RedirectToAction("Index"); } - return View(viewmodel); } + } } diff --git a/Web/Areas/Admin/Views/Banner/Create.cshtml b/Web/Areas/Admin/Views/Banner/Create.cshtml index fb8e1f7..0a27309 100644 --- a/Web/Areas/Admin/Views/Banner/Create.cshtml +++ b/Web/Areas/Admin/Views/Banner/Create.cshtml @@ -66,3 +66,111 @@ +@*
+
+
+
Create Survey
+ +
+ + +
+
+ +
+ + + +
+
+ + + +
+ @foreach (var item in Model.Questions) + { + + + + + + + } +
+
+

Create Questions

+
+ @for (int i = 0; i < Model.Questions?.Count; i++) + { +
+ + + + + + +
+ } +
+ + +
+ | + + | Back to list +
+ + +
+
+
+
+
+
+ + + + +@section Scripts { + + @{ + + } + + +} *@ \ No newline at end of file diff --git a/Web/Areas/Admin/Views/Questionnaire/Create.cshtml b/Web/Areas/Admin/Views/Questionnaire/Create.cshtml index a4b9f64..9e92226 100644 --- a/Web/Areas/Admin/Views/Questionnaire/Create.cshtml +++ b/Web/Areas/Admin/Views/Questionnaire/Create.cshtml @@ -1,8 +1,10 @@ -@model Web.ViewModel.QuestionnaireVM.QuestionnaireViewModel + +@model QuestionnaireViewModel @{ ViewData["Title"] = "Create"; } +
@@ -24,7 +26,37 @@
-
+
+

Create Questions

+
+ @for (int i = 0; i < Model.Questions?.Count; i++) + { +
+ + + +
+
+ + @for (int j = 0; j < Model.Answers?.Count; j++) + { +
+ + +
+ } + + + +
+ } +
+
+ + + @*

Create Questions

@@ -32,36 +64,41 @@ {
- -
-
-
- - -
- - - + +
+
+ + @for (int j = 1; j < Model.Questions?[i].Answers?.Count; j++) + { +
+ + +
+ } + + + +
+ + + }
+
- | - - | Back to list -
+ + +
*@ - + + | Back to list +
@@ -73,36 +110,263 @@ @section Scripts { - - + @{ } + + + @* *@ + + + + + + + + + @* *@ + + @* *@ + + + + + + + + @* *@ + +} \ No newline at end of file diff --git a/Web/Areas/Admin/Views/Questionnaire/Index.cshtml b/Web/Areas/Admin/Views/Questionnaire/Index.cshtml index bc847c9..a0179ab 100644 --- a/Web/Areas/Admin/Views/Questionnaire/Index.cshtml +++ b/Web/Areas/Admin/Views/Questionnaire/Index.cshtml @@ -1,47 +1,65 @@ -@model IEnumerable +@model IEnumerable @{ - ViewData["Title"] = "Index"; + ViewData["Title"] = "Questionnaire"; } +
+ + + +
+
Questionnaire
+
+

Questionnaire list

+

+ Create New +

+ + + + + + + + + + + + + + @foreach (var item in Model) + { + + + + + + + + + + + + } + + + +
IdTitleDescriptionQaustion & Questions TypeAction
@item.Id @item.Title@item.Description + + @foreach (var question in item.Questions) + { + + Question:@question.Text + Type: @question.Type + } + + + Delete | + Edit +
+ +
+
+
-

Index

-

- Create New -

- - - - - - - - - - -@foreach (var item in Model) { - - - - - - -} - -
- @Html.DisplayNameFor(model => model.Id) - - @Html.DisplayNameFor(model => model.Title) - - @Html.DisplayNameFor(model => model.Description) -
- @Html.DisplayFor(modelItem => item.Id) - - @Html.DisplayFor(modelItem => item.Title) - - @Html.DisplayFor(modelItem => item.Description) - - @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) | - @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) | - @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ }) -
diff --git a/Web/Areas/Admin/Views/_ViewImports.cshtml b/Web/Areas/Admin/Views/_ViewImports.cshtml index 7663194..a5c3cd7 100644 --- a/Web/Areas/Admin/Views/_ViewImports.cshtml +++ b/Web/Areas/Admin/Views/_ViewImports.cshtml @@ -1,4 +1,5 @@ @using Web +@using Model @using Web.Models @using Web.ViewModel @using Web.ViewModel.AddressVM diff --git a/Web/Extesions/ServicesExtesions.cs b/Web/Extesions/ServicesExtesions.cs index 9c7de82..5d5af46 100644 --- a/Web/Extesions/ServicesExtesions.cs +++ b/Web/Extesions/ServicesExtesions.cs @@ -42,5 +42,9 @@ namespace Web.Extesions { services.AddScoped(); } + public static void ConfigureQuestion(this IServiceCollection services) + { + services.AddScoped(); + } } } diff --git a/Web/Migrations/20240308144608_DifferntTypeofQuestionAdded.Designer.cs b/Web/Migrations/20240308144608_DifferntTypeofQuestionAdded.Designer.cs new file mode 100644 index 0000000..dacd948 --- /dev/null +++ b/Web/Migrations/20240308144608_DifferntTypeofQuestionAdded.Designer.cs @@ -0,0 +1,371 @@ +// +using System; +using Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Web.Migrations +{ + [DbContext(typeof(SurveyContext))] + [Migration("20240308144608_DifferntTypeofQuestionAdded")] + partial class DifferntTypeofQuestionAdded + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.2") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Model.Address", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CVR") + .HasColumnType("nvarchar(max)"); + + b.Property("City") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Mobile") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PostalCode") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("State") + .HasColumnType("nvarchar(max)"); + + b.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Addresss"); + }); + + modelBuilder.Entity("Model.Answer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("QuestionId") + .HasColumnType("int"); + + b.Property("Text") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("QuestionId"); + + b.ToTable("Answers"); + }); + + modelBuilder.Entity("Model.Banner", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Content") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ImageUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LinkUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Banners"); + }); + + modelBuilder.Entity("Model.Footer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Content") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ImageUlr") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastUpdated") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Owner") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Sitecopyright") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Footers"); + }); + + modelBuilder.Entity("Model.FooterSocialMedia", b => + { + b.Property("FooterId") + .HasColumnType("int"); + + b.Property("SocialId") + .HasColumnType("int"); + + b.HasKey("FooterId", "SocialId"); + + b.HasIndex("SocialId"); + + b.ToTable("FooterSocialMedias"); + }); + + modelBuilder.Entity("Model.Page", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("BannerId") + .HasColumnType("int"); + + b.Property("Content") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Slug") + .HasColumnType("nvarchar(max)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("BannerId"); + + b.ToTable("Pages"); + }); + + modelBuilder.Entity("Model.Question", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("QuestionnaireId") + .HasColumnType("int"); + + b.Property("Text") + .HasColumnType("nvarchar(max)"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("QuestionnaireId"); + + b.ToTable("Questions"); + }); + + modelBuilder.Entity("Model.QuestionTypeEntities", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("QuestionTypeEntities"); + }); + + modelBuilder.Entity("Model.Questionnaire", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("Title") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Questionnaires"); + }); + + modelBuilder.Entity("Model.SocialMedia", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Url") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("SocialMedia"); + }); + + modelBuilder.Entity("Model.Answer", b => + { + b.HasOne("Model.Question", "Question") + .WithMany("Answers") + .HasForeignKey("QuestionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Question"); + }); + + modelBuilder.Entity("Model.FooterSocialMedia", b => + { + b.HasOne("Model.Footer", "Footer") + .WithMany("FooterSocialMedias") + .HasForeignKey("FooterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Model.SocialMedia", "SocialMedia") + .WithMany("FooterSocialMedias") + .HasForeignKey("SocialId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Footer"); + + b.Navigation("SocialMedia"); + }); + + modelBuilder.Entity("Model.Page", b => + { + b.HasOne("Model.Banner", "banner") + .WithMany() + .HasForeignKey("BannerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("banner"); + }); + + modelBuilder.Entity("Model.Question", b => + { + b.HasOne("Model.Questionnaire", "Questionnaire") + .WithMany("Questions") + .HasForeignKey("QuestionnaireId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Questionnaire"); + }); + + modelBuilder.Entity("Model.Footer", b => + { + b.Navigation("FooterSocialMedias"); + }); + + modelBuilder.Entity("Model.Question", b => + { + b.Navigation("Answers"); + }); + + modelBuilder.Entity("Model.Questionnaire", b => + { + b.Navigation("Questions"); + }); + + modelBuilder.Entity("Model.SocialMedia", b => + { + b.Navigation("FooterSocialMedias"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Web/Migrations/20240308144608_DifferntTypeofQuestionAdded.cs b/Web/Migrations/20240308144608_DifferntTypeofQuestionAdded.cs new file mode 100644 index 0000000..0ac3556 --- /dev/null +++ b/Web/Migrations/20240308144608_DifferntTypeofQuestionAdded.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Web.Migrations +{ + /// + public partial class DifferntTypeofQuestionAdded : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/Web/Program.cs b/Web/Program.cs index 5fb33d4..7d42286 100644 --- a/Web/Program.cs +++ b/Web/Program.cs @@ -19,6 +19,7 @@ builder.Services.ConfigureAddress(); builder.Services.ConfigureSocialMedia(); builder.Services.ConfigureFooter(); builder.Services.ConfigureQuestionnarie(); +builder.Services.ConfigureQuestion(); //builder.Services.AddScoped(); var app = builder.Build(); diff --git a/Web/ViewModel/AnswerVM/AnswerViewModel.cs b/Web/ViewModel/AnswerVM/AnswerViewModel.cs new file mode 100644 index 0000000..b661381 --- /dev/null +++ b/Web/ViewModel/AnswerVM/AnswerViewModel.cs @@ -0,0 +1,14 @@ +using Model; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Web.ViewModel.AnswerVM +{ + public class AnswerViewModel + { + public int Id { get; set; } + public string? Text { get; set; } + public int QuestionId { get; set; } // Foreign key for Question + [ForeignKey("QuestionId")] + public Question? Question { get; set; } + } +} diff --git a/Web/ViewModel/QuestionVM/QuestionViewModel.cs b/Web/ViewModel/QuestionVM/QuestionViewModel.cs new file mode 100644 index 0000000..7e0ba31 --- /dev/null +++ b/Web/ViewModel/QuestionVM/QuestionViewModel.cs @@ -0,0 +1,24 @@ +using Model; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using Web.ViewModel.AnswerVM; + + +namespace Web.ViewModel.QuestionVM +{ + public class QuestionViewModel + { + public int Id { get; set; } + [Required] + public string? Text { get; set; } + public QuestionType Type { get; set; } + + // Foreign key for Questionnaire + + public int QuestionnaireId { get; set; } // Foreign key for Questionnaire + [ForeignKey("QuestionnaireId")] + public Questionnaire? Questionnaire { get; set; } + + public List? AnswersViewModel { get; set; }=new List(); + } +} diff --git a/Web/ViewModel/QuestionnaireVM/QuestionnaireViewModel.cs b/Web/ViewModel/QuestionnaireVM/QuestionnaireViewModel.cs index 94d0326..6daac1b 100644 --- a/Web/ViewModel/QuestionnaireVM/QuestionnaireViewModel.cs +++ b/Web/ViewModel/QuestionnaireVM/QuestionnaireViewModel.cs @@ -1,5 +1,7 @@ using Model; using System.ComponentModel.DataAnnotations; +using Web.ViewModel.AnswerVM; +using Web.ViewModel.QuestionVM; namespace Web.ViewModel.QuestionnaireVM { @@ -8,12 +10,21 @@ namespace Web.ViewModel.QuestionnaireVM public QuestionnaireViewModel() { Questions = new List(); + + } public int Id { get; set; } [Required] public string? Title { get; set; } [Required] public string? Description { get; set; } + public List? Questions { get; set; } + public List? Answers { get; set; } + + + + + } }