Add 'Other' option to questionnaire for custom user input
This commit is contained in:
parent
908e241fd8
commit
d9f9b600d7
16 changed files with 3769 additions and 492 deletions
|
|
@ -21,6 +21,7 @@ namespace Model
|
|||
[ForeignKey("QuestionId")]
|
||||
public Question? Question { get; set; }
|
||||
|
||||
public bool IsOtherOption { get; set; } = false;
|
||||
public string? ConditionJson { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ namespace Model
|
|||
public QuestionType QuestionType { get; set; }
|
||||
public string? TextResponse { get; set; }
|
||||
public List<ResponseAnswer> ResponseAnswers { get; set; } = new List<ResponseAnswer>();
|
||||
|
||||
public string? OtherText { get; set; }
|
||||
public ResponseStatus Status { get; set; } = ResponseStatus.Shown;
|
||||
public string? SkipReason { get; set; } // Why it was skipped (JSON of condition)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,12 +93,8 @@ namespace Web.Areas.Admin.Controllers
|
|||
[HttpPost]
|
||||
public async Task<IActionResult> Create(QuestionnaireViewModel viewmodel)
|
||||
{
|
||||
|
||||
|
||||
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
|
||||
var questionnaire = new Questionnaire
|
||||
{
|
||||
Id = viewmodel.Id,
|
||||
|
|
@ -106,7 +102,6 @@ namespace Web.Areas.Admin.Controllers
|
|||
Description = viewmodel.Description,
|
||||
};
|
||||
|
||||
|
||||
var questions = viewmodel.Questions;
|
||||
|
||||
foreach (var questionViewModel in viewmodel.Questions)
|
||||
|
|
@ -121,30 +116,27 @@ namespace Web.Areas.Admin.Controllers
|
|||
|
||||
foreach (var answerViewModel in questionViewModel.Answers)
|
||||
{
|
||||
// Skip empty answers
|
||||
if (string.IsNullOrWhiteSpace(answerViewModel.Text))
|
||||
continue;
|
||||
|
||||
var answer = new Answer
|
||||
{
|
||||
Text = answerViewModel.Text,
|
||||
QuestionId = answerViewModel.QuestionId,
|
||||
|
||||
IsOtherOption = answerViewModel.IsOtherOption // NEW: Handle IsOtherOption property
|
||||
};
|
||||
|
||||
|
||||
question.Answers.Add(answer);
|
||||
}
|
||||
|
||||
|
||||
questionnaire.Questions.Add(question);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
_questionnaire.Add(questionnaire);
|
||||
await _questionnaire.commitAsync();
|
||||
TempData["Success"] = "Questionnaire created successfully";
|
||||
|
||||
|
||||
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
return View(viewmodel);
|
||||
|
|
@ -201,7 +193,6 @@ namespace Web.Areas.Admin.Controllers
|
|||
[HttpPost]
|
||||
public async Task<IActionResult> Edit(EditQuestionnaireViewModel viewModel)
|
||||
{
|
||||
|
||||
var questionTypes = Enum.GetValues(typeof(QuestionType))
|
||||
.Cast<QuestionType>()
|
||||
.Select(e => new SelectListItem { Value = e.ToString(), Text = e.ToString() });
|
||||
|
|
@ -214,7 +205,7 @@ namespace Web.Areas.Admin.Controllers
|
|||
|
||||
if (existingQuestionnaire == null)
|
||||
{
|
||||
return NotFound(); // Or handle not found case appropriately
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
// Update the existing questionnaire with the data from the view model
|
||||
|
|
@ -226,22 +217,13 @@ namespace Web.Areas.Admin.Controllers
|
|||
// Iterate through existing questions and remove those not found in the view model
|
||||
foreach (var existingQuestion in existingQuestionnaire.Questions.ToList())
|
||||
{
|
||||
// If the ID of the existing question is not found in the view model, remove it
|
||||
if (!viewModel.Questions.Any(q => q.Id == existingQuestion.Id))
|
||||
{
|
||||
existingQuestionnaire.Questions.Remove(existingQuestion);
|
||||
|
||||
}
|
||||
await _questionnaire.Update(existingQuestionnaire);
|
||||
}
|
||||
|
||||
// Update the questionnaire with the modified list of questions
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var newQuestions = new List<Question>();
|
||||
|
||||
// Update or add new questions
|
||||
|
|
@ -253,11 +235,9 @@ namespace Web.Areas.Admin.Controllers
|
|||
{
|
||||
if (existingQuestion != null)
|
||||
{
|
||||
var answersToRemove = new List<Answer>();
|
||||
existingQuestion.Text = questionViewModel.Text;
|
||||
existingQuestion.Type = questionViewModel.Type;
|
||||
|
||||
|
||||
foreach (var answerViewModel in questionViewModel.Answers)
|
||||
{
|
||||
// Check if the answer already exists
|
||||
|
|
@ -265,32 +245,27 @@ namespace Web.Areas.Admin.Controllers
|
|||
|
||||
if (answerViewModel.Id == 0)
|
||||
{
|
||||
|
||||
existingQuestion.Answers.Add(new Answer { Text = answerViewModel.Text });
|
||||
|
||||
|
||||
// NEW: Add IsOtherOption property when creating new answers
|
||||
existingQuestion.Answers.Add(new Answer
|
||||
{
|
||||
Text = answerViewModel.Text,
|
||||
IsOtherOption = answerViewModel.IsOtherOption
|
||||
});
|
||||
}
|
||||
else if (answerViewModel.Text == null)
|
||||
{
|
||||
existingQuestion.Answers.Remove(existingAnswer);
|
||||
await _questionnaire.Update(existingQuestionnaire);
|
||||
}
|
||||
|
||||
|
||||
else if (existingAnswer != null)
|
||||
{
|
||||
|
||||
existingAnswer.Text = answerViewModel.Text;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// NEW: Update IsOtherOption property for existing answers
|
||||
existingAnswer.IsOtherOption = answerViewModel.IsOtherOption;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
else
|
||||
{
|
||||
// Create a new question
|
||||
|
|
@ -305,52 +280,33 @@ namespace Web.Areas.Admin.Controllers
|
|||
{
|
||||
if (!string.IsNullOrEmpty(answerViewModel.Text))
|
||||
{
|
||||
// Add new answer if text is not null or empty
|
||||
newQuestion.Answers.Add(new Answer { Text = answerViewModel.Text });
|
||||
// NEW: Add IsOtherOption property when creating new answers
|
||||
newQuestion.Answers.Add(new Answer
|
||||
{
|
||||
Text = answerViewModel.Text,
|
||||
IsOtherOption = answerViewModel.IsOtherOption
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Add new question to the list of new questions
|
||||
newQuestions.Add(newQuestion);
|
||||
}
|
||||
|
||||
existingQuestionnaire.Questions.AddRange(newQuestions);
|
||||
//else
|
||||
//{
|
||||
// // Add new question
|
||||
// var newQuestion = new Question
|
||||
// {
|
||||
// Text = questionViewModel.Text, // Make sure question text is not null
|
||||
// Type = questionViewModel.Type, // Make sure question type is not null
|
||||
// Answers = new List<Answer>() // Initialize answers list
|
||||
// };
|
||||
|
||||
// foreach (var answerViewModel in questionViewModel.Answers)
|
||||
// {
|
||||
// // Add new answer
|
||||
// newQuestion.Answers.Add(new Answer { Text = answerViewModel.Text });
|
||||
// }
|
||||
|
||||
// // Add new question to questionnaire
|
||||
// existingQuestionnaire.Questions.Add(newQuestion);
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
|
||||
await _questionnaire.Update(existingQuestionnaire);
|
||||
|
||||
TempData["Success"] = "Questionnaire updated successfully";
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
|
||||
// If ModelState is not valid, re-display the form with validation errors
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Delete(int id)
|
||||
{
|
||||
|
||||
var questionTypes = Enum.GetValues(typeof(QuestionType)).Cast<QuestionType>();
|
||||
|
||||
ViewBag.QuestionTypes = new SelectList(questionTypes);
|
||||
|
|
@ -358,7 +314,7 @@ namespace Web.Areas.Admin.Controllers
|
|||
|
||||
if (questionnaire == null)
|
||||
{
|
||||
return NotFound(); // Or handle not found case appropriately
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var viewModel = new QuestionnaireViewModel
|
||||
|
|
@ -375,7 +331,8 @@ namespace Web.Areas.Admin.Controllers
|
|||
Answers = q.Answers.Select(a => new Answer
|
||||
{
|
||||
Id = a.Id,
|
||||
Text = a.Text
|
||||
Text = a.Text,
|
||||
IsOtherOption = a.IsOtherOption // NEW: Include IsOtherOption property
|
||||
}).ToList()
|
||||
}).ToList()
|
||||
};
|
||||
|
|
@ -422,7 +379,7 @@ namespace Web.Areas.Admin.Controllers
|
|||
|
||||
if (questionnaire == null)
|
||||
{
|
||||
return NotFound(); // Or handle not found case appropriately
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var viewModel = new QuestionnaireViewModel
|
||||
|
|
@ -439,7 +396,8 @@ namespace Web.Areas.Admin.Controllers
|
|||
Answers = q.Answers.Select(a => new Answer
|
||||
{
|
||||
Id = a.Id,
|
||||
Text = a.Text
|
||||
Text = a.Text,
|
||||
IsOtherOption = a.IsOtherOption // NEW: Include IsOtherOption property
|
||||
}).ToList()
|
||||
}).ToList()
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@ using OfficeOpenXml;
|
|||
using Services.Interaces;
|
||||
using Web.ViewModel.QuestionnaireVM;
|
||||
|
||||
|
||||
|
||||
namespace Web.Areas.Admin.Controllers
|
||||
{
|
||||
public class UserResponseStatusController : Controller
|
||||
|
|
@ -41,7 +39,6 @@ namespace Web.Areas.Admin.Controllers
|
|||
return View(usersWithQuestionnaires);
|
||||
}
|
||||
|
||||
|
||||
public async Task<IActionResult> UserResponsesStatus(string userEmail)
|
||||
{
|
||||
var responses = await _context.Responses
|
||||
|
|
@ -72,8 +69,6 @@ namespace Web.Areas.Admin.Controllers
|
|||
return View(viewModel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> DeleteSelected(string[] selectedEmails)
|
||||
{
|
||||
|
|
@ -95,8 +90,6 @@ namespace Web.Areas.Admin.Controllers
|
|||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async Task<IActionResult> GenerateReport(string userEmail, string format)
|
||||
{
|
||||
var responses = await _context.Responses
|
||||
|
|
@ -125,7 +118,6 @@ namespace Web.Areas.Admin.Controllers
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private IActionResult GeneratePdfReport(List<Response> responses)
|
||||
{
|
||||
var userName = responses.First().UserName;
|
||||
|
|
@ -197,6 +189,15 @@ namespace Web.Areas.Admin.Controllers
|
|||
{
|
||||
table.AddCell(new PdfPCell(new Phrase("Answers:", cellFont)) { Padding = 5 });
|
||||
var answers = string.Join(", ", detail.ResponseAnswers.Select(a => detail.Question.Answers.FirstOrDefault(ans => ans.Id == a.AnswerId)?.Text));
|
||||
|
||||
// NEW: Include "Other" text if available
|
||||
if (!string.IsNullOrEmpty(detail.OtherText))
|
||||
{
|
||||
answers += string.IsNullOrEmpty(answers)
|
||||
? $"Other: {detail.OtherText}"
|
||||
: $"; Other: {detail.OtherText}";
|
||||
}
|
||||
|
||||
table.AddCell(new PdfPCell(new Phrase(answers, cellFont)) { Padding = 5 });
|
||||
}
|
||||
}
|
||||
|
|
@ -211,8 +212,6 @@ namespace Web.Areas.Admin.Controllers
|
|||
return File(stream, "application/pdf", $"{userName}_report.pdf");
|
||||
}
|
||||
|
||||
|
||||
|
||||
private IActionResult GenerateExcelReport(List<Response> responses)
|
||||
{
|
||||
var userName = responses.First().UserName;
|
||||
|
|
@ -272,6 +271,15 @@ namespace Web.Areas.Admin.Controllers
|
|||
else
|
||||
{
|
||||
var answers = string.Join(", ", detail.ResponseAnswers.Select(a => detail.Question.Answers.FirstOrDefault(ans => ans.Id == a.AnswerId)?.Text));
|
||||
|
||||
// NEW: Include "Other" text if available
|
||||
if (!string.IsNullOrEmpty(detail.OtherText))
|
||||
{
|
||||
answers += string.IsNullOrEmpty(answers)
|
||||
? $"Other: {detail.OtherText}"
|
||||
: $"; Other: {detail.OtherText}";
|
||||
}
|
||||
|
||||
worksheet.Cells[row, 4].Value = answers;
|
||||
}
|
||||
row++;
|
||||
|
|
@ -289,11 +297,6 @@ namespace Web.Areas.Admin.Controllers
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public async Task<IActionResult> GenerateQuestionnairePdfReport(int questionnaireId)
|
||||
{
|
||||
var response = await _context.Responses
|
||||
|
|
@ -390,6 +393,15 @@ namespace Web.Areas.Admin.Controllers
|
|||
{
|
||||
table.AddCell(new PdfPCell(new Phrase("Answers:", cellFont)) { Padding = 5 });
|
||||
var answers = string.Join(", ", detail.ResponseAnswers.Select(a => detail.Question.Answers.FirstOrDefault(ans => ans.Id == a.AnswerId)?.Text));
|
||||
|
||||
// NEW: Include "Other" text if available
|
||||
if (!string.IsNullOrEmpty(detail.OtherText))
|
||||
{
|
||||
answers += string.IsNullOrEmpty(answers)
|
||||
? $"Other: {detail.OtherText}"
|
||||
: $"; Other: {detail.OtherText}";
|
||||
}
|
||||
|
||||
table.AddCell(new PdfPCell(new Phrase(answers, cellFont)) { Padding = 5 });
|
||||
}
|
||||
}
|
||||
|
|
@ -421,7 +433,6 @@ namespace Web.Areas.Admin.Controllers
|
|||
return GenerateExcelReportForQuestionnaire(response);
|
||||
}
|
||||
|
||||
|
||||
private IActionResult GenerateExcelReportForQuestionnaire(Response response)
|
||||
{
|
||||
var userName = response.UserName;
|
||||
|
|
@ -486,6 +497,15 @@ namespace Web.Areas.Admin.Controllers
|
|||
else
|
||||
{
|
||||
var answers = string.Join(", ", detail.ResponseAnswers.Select(a => detail.Question.Answers.FirstOrDefault(ans => ans.Id == a.AnswerId)?.Text));
|
||||
|
||||
// NEW: Include "Other" text if available
|
||||
if (!string.IsNullOrEmpty(detail.OtherText))
|
||||
{
|
||||
answers += string.IsNullOrEmpty(answers)
|
||||
? $"Other: {detail.OtherText}"
|
||||
: $"; Other: {detail.OtherText}";
|
||||
}
|
||||
|
||||
worksheet.Cells[row, 4].Value = answers;
|
||||
}
|
||||
row++;
|
||||
|
|
@ -500,81 +520,5 @@ namespace Web.Areas.Admin.Controllers
|
|||
return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $"{response.Questionnaire.Title}_{userEmail}.xlsx");
|
||||
}
|
||||
}
|
||||
|
||||
//private IActionResult GenerateExcelReportForQuestionnaire(Response response)
|
||||
//{
|
||||
// var userName = response.UserName;
|
||||
// var userEmail = response.UserEmail;
|
||||
|
||||
// using (var package = new ExcelPackage())
|
||||
// {
|
||||
// var worksheet = package.Workbook.Worksheets.Add("Report");
|
||||
|
||||
// // Add a logo
|
||||
// var logoPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images", "logo.png");
|
||||
// if (System.IO.File.Exists(logoPath))
|
||||
// {
|
||||
// var logo = new FileInfo(logoPath);
|
||||
// var picture = worksheet.Drawings.AddPicture("Logo", logo);
|
||||
// picture.SetPosition(0, 0, 0, 0);
|
||||
// picture.SetSize(300, 70); // Adjust the size as needed
|
||||
// }
|
||||
|
||||
// // Add a title
|
||||
// worksheet.Cells[6, 1].Value = $"Report for {response.Questionnaire.Title}";
|
||||
// worksheet.Cells[6, 1, 6, 4].Merge = true;
|
||||
// worksheet.Cells[6, 1, 6, 4].Style.Font.Size = 18;
|
||||
// worksheet.Cells[6, 1, 6, 4].Style.Font.Bold = true;
|
||||
// worksheet.Cells[6, 1, 6, 4].Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
|
||||
|
||||
// // Add headers
|
||||
// worksheet.Cells[7, 1].Value = "Survey";
|
||||
// worksheet.Cells[7, 2].Value = "Submitted on";
|
||||
// worksheet.Cells[7, 3].Value = "Question";
|
||||
// worksheet.Cells[7, 4].Value = "Response";
|
||||
|
||||
// using (var range = worksheet.Cells[7, 1, 7, 4])
|
||||
// {
|
||||
// range.Style.Font.Bold = true;
|
||||
// range.Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
|
||||
// range.Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.LightGray);
|
||||
// range.Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
|
||||
// }
|
||||
|
||||
// // Add data
|
||||
// var row = 8;
|
||||
// worksheet.Cells[row, 1].Value = response.Questionnaire.Title;
|
||||
// worksheet.Cells[row, 2].Value = response.SubmissionDate.ToString();
|
||||
// row++;
|
||||
|
||||
// foreach (var detail in response.ResponseDetails)
|
||||
// {
|
||||
// worksheet.Cells[row, 3].Value = detail.Question.Text;
|
||||
|
||||
// if (detail.QuestionType == QuestionType.Text || detail.QuestionType == QuestionType.Slider || detail.QuestionType == QuestionType.Open_ended)
|
||||
// {
|
||||
// worksheet.Cells[row, 4].Value = detail.TextResponse;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// var answers = string.Join(", ", detail.ResponseAnswers.Select(a => detail.Question.Answers.FirstOrDefault(ans => ans.Id == a.AnswerId)?.Text));
|
||||
// worksheet.Cells[row, 4].Value = answers;
|
||||
// }
|
||||
// row++;
|
||||
// }
|
||||
|
||||
// worksheet.Cells.AutoFitColumns();
|
||||
|
||||
// var stream = new MemoryStream();
|
||||
// package.SaveAs(stream);
|
||||
// stream.Position = 0;
|
||||
|
||||
// return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $"{response.Questionnaire.Title}_{userEmail}.xlsx");
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,559 @@
|
|||
|
||||
@model QuestionnaireViewModel
|
||||
@model QuestionnaireViewModel
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Create";
|
||||
}
|
||||
|
||||
<style>
|
||||
/* Modern Design Enhancements */
|
||||
@@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
|
||||
|
||||
:root {
|
||||
--primary-color: #6366f1;
|
||||
--primary-light: #8b5cf6;
|
||||
--primary-dark: #4338ca;
|
||||
--success-color: #10b981;
|
||||
--danger-color: #ef4444;
|
||||
--warning-color: #f59e0b;
|
||||
--info-color: #06b6d4;
|
||||
--gray-50: #f8fafc;
|
||||
--gray-100: #f1f5f9;
|
||||
--gray-200: #e2e8f0;
|
||||
--gray-300: #cbd5e1;
|
||||
--gray-400: #94a3b8;
|
||||
--gray-500: #64748b;
|
||||
--gray-600: #475569;
|
||||
--gray-700: #334155;
|
||||
--gray-800: #1e293b;
|
||||
--gray-900: #0f172a;
|
||||
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
||||
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
||||
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
||||
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
|
||||
--shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / 0.25);
|
||||
--border-radius-sm: 8px;
|
||||
--border-radius-md: 12px;
|
||||
--border-radius-lg: 16px;
|
||||
--border-radius-xl: 20px;
|
||||
}
|
||||
|
||||
* {
|
||||
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
}
|
||||
|
||||
/* Enhanced Card Design */
|
||||
.card {
|
||||
background: white;
|
||||
border-radius: var(--border-radius-xl);
|
||||
box-shadow: var(--shadow-2xl);
|
||||
border: 1px solid var(--gray-200);
|
||||
overflow: hidden;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
color: var(--gray-800);
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
position: relative;
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.card-title::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 60px;
|
||||
height: 4px;
|
||||
background: linear-gradient(135deg, var(--primary-color), var(--primary-light));
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 3rem;
|
||||
background: var(--gray-50);
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
background: white;
|
||||
padding: 2.5rem;
|
||||
border-top: 1px solid var(--gray-200);
|
||||
display: flex;
|
||||
gap: 1.5rem;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
/* Form Enhancements */
|
||||
.mb-3 {
|
||||
margin-bottom: 2rem !important;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
border: 2px solid var(--gray-200);
|
||||
border-radius: var(--border-radius-md);
|
||||
padding: 1rem 1.25rem;
|
||||
font-size: 0.95rem;
|
||||
font-weight: 500;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
background: white;
|
||||
box-shadow: var(--shadow-sm);
|
||||
width: 100%;
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
border-color: var(--primary-color);
|
||||
background: white;
|
||||
box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.1), var(--shadow-md);
|
||||
outline: none;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.control-label {
|
||||
font-weight: 600;
|
||||
color: var(--gray-700);
|
||||
margin-bottom: 0.75rem;
|
||||
font-size: 0.95rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* Enhanced Select Styling */
|
||||
select.form-control {
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
background-color: white;
|
||||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3e%3c/svg%3e");
|
||||
background-position: right 0.75rem center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 1.25em 1.25em;
|
||||
padding-right: 2.5rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
select.form-control:focus {
|
||||
background-color: white;
|
||||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236366f1' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3e%3c/svg%3e");
|
||||
background-position: right 0.75rem center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 1.25em 1.25em;
|
||||
}
|
||||
|
||||
select.form-control option {
|
||||
padding: 0.75rem;
|
||||
font-weight: 500;
|
||||
color: var(--gray-900);
|
||||
background: white;
|
||||
}
|
||||
|
||||
/* Textarea specific styling */
|
||||
textarea.form-control {
|
||||
min-height: 120px;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
/* Button Enhancements */
|
||||
.btn {
|
||||
border-radius: var(--border-radius-md);
|
||||
font-weight: 600;
|
||||
padding: 0.75rem 1.5rem;
|
||||
font-size: 0.875rem;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
border: none;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
box-shadow: var(--shadow-sm);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.btn::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
|
||||
transition: left 0.5s;
|
||||
}
|
||||
|
||||
.btn:hover::before {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-light) 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary-color) 100%);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: var(--shadow-lg);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-success {
|
||||
background: linear-gradient(135deg, var(--success-color) 0%, #059669 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-success:hover {
|
||||
background: linear-gradient(135deg, #059669 0%, #047857 100%);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: var(--shadow-lg);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
background: linear-gradient(135deg, var(--danger-color) 0%, #dc2626 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-danger:hover {
|
||||
background: linear-gradient(135deg, #dc2626 0%, #b91c1c 100%);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: var(--shadow-lg);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-info {
|
||||
background: linear-gradient(135deg, var(--info-color) 0%, #0891b2 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-info:hover {
|
||||
background: linear-gradient(135deg, #0891b2 0%, #0e7490 100%);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: var(--shadow-lg);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-warning {
|
||||
background: linear-gradient(135deg, var(--warning-color) 0%, #d97706 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-warning:hover {
|
||||
background: linear-gradient(135deg, #d97706 0%, #b45309 100%);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: var(--shadow-lg);
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Questions Container */
|
||||
#questions-container {
|
||||
background: white;
|
||||
border-radius: var(--border-radius-lg);
|
||||
padding: 3rem;
|
||||
margin: 2rem 0;
|
||||
box-shadow: var(--shadow-xl);
|
||||
border: 1px solid var(--gray-200);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#questions-container::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 4px;
|
||||
background: linear-gradient(90deg, var(--primary-color), var(--primary-light), var(--success-color));
|
||||
}
|
||||
|
||||
#questions-container h3 {
|
||||
font-size: 1.75rem;
|
||||
font-weight: 700;
|
||||
color: var(--gray-800);
|
||||
margin-bottom: 3rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Question Group Styling */
|
||||
.question-group {
|
||||
background: var(--gray-50);
|
||||
border-radius: var(--border-radius-lg);
|
||||
padding: 2.5rem;
|
||||
margin-bottom: 2.5rem;
|
||||
border: 2px solid var(--gray-200);
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.question-group::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 4px;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, var(--primary-color), var(--primary-light));
|
||||
transform: scaleY(0);
|
||||
transition: transform 0.3s ease;
|
||||
transform-origin: bottom;
|
||||
}
|
||||
|
||||
.question-group:hover {
|
||||
border-color: var(--primary-color);
|
||||
box-shadow: var(--shadow-xl);
|
||||
transform: translateY(-2px);
|
||||
background: white;
|
||||
}
|
||||
|
||||
.question-group:hover::before {
|
||||
transform: scaleY(1);
|
||||
}
|
||||
|
||||
.question-group.collapsed {
|
||||
background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);
|
||||
border-color: var(--success-color);
|
||||
}
|
||||
|
||||
.question-group label {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
color: var(--gray-800);
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
/* Answers Container */
|
||||
.answers-container {
|
||||
background: white;
|
||||
border-radius: var(--border-radius-md);
|
||||
padding: 2rem;
|
||||
margin: 1.5rem 0;
|
||||
border: 1px solid var(--gray-200);
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.answers-container label {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 700;
|
||||
color: var(--gray-800);
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
/* Answer Group Styling */
|
||||
.answer-group {
|
||||
background: var(--gray-50);
|
||||
border-radius: var(--border-radius-md);
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.25rem;
|
||||
border: 1px solid var(--gray-200);
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.answer-group:hover {
|
||||
border-color: var(--primary-color);
|
||||
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
|
||||
background: white;
|
||||
}
|
||||
|
||||
/* Other Option Styling */
|
||||
.other-option-group {
|
||||
background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
|
||||
border: 2px solid var(--warning-color);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.other-option-group::before {
|
||||
content: "OTHER OPTION";
|
||||
position: absolute;
|
||||
top: -12px;
|
||||
left: 20px;
|
||||
background: var(--warning-color);
|
||||
color: white;
|
||||
padding: 0.375rem 1rem;
|
||||
border-radius: var(--border-radius-sm);
|
||||
font-size: 0.7rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.5px;
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
/* Add Question Button */
|
||||
#add-question-btn {
|
||||
background: linear-gradient(135deg, var(--success-color) 0%, #059669 100%);
|
||||
color: white;
|
||||
padding: 1.25rem 2.5rem;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 700;
|
||||
border-radius: var(--border-radius-lg);
|
||||
margin: 2rem auto;
|
||||
box-shadow: var(--shadow-lg);
|
||||
border: none;
|
||||
display: block;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
#add-question-btn:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: var(--shadow-2xl);
|
||||
background: linear-gradient(135deg, #059669 0%, #047857 100%);
|
||||
}
|
||||
|
||||
/* Alert Enhancements */
|
||||
.alert {
|
||||
border-radius: var(--border-radius-md);
|
||||
padding: 1.25rem 1.5rem;
|
||||
margin: 1.5rem 0;
|
||||
border: none;
|
||||
font-weight: 500;
|
||||
box-shadow: var(--shadow-sm);
|
||||
animation: slideDown 0.3s ease;
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);
|
||||
color: #065f46;
|
||||
border-left: 4px solid var(--success-color);
|
||||
}
|
||||
|
||||
.alert-info {
|
||||
background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);
|
||||
color: #0c4a6e;
|
||||
border-left: 4px solid var(--info-color);
|
||||
}
|
||||
|
||||
.alert-danger {
|
||||
background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);
|
||||
color: #991b1b;
|
||||
border-left: 4px solid var(--danger-color);
|
||||
}
|
||||
|
||||
/* Horizontal Rules */
|
||||
hr {
|
||||
border: none;
|
||||
height: 2px;
|
||||
background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-light) 100%);
|
||||
margin: 2rem 0;
|
||||
border-radius: 1px;
|
||||
}
|
||||
|
||||
hr.border-4 {
|
||||
height: 4px;
|
||||
background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-light) 100%);
|
||||
margin: 3rem 0;
|
||||
}
|
||||
|
||||
/* Container Enhancements */
|
||||
.container-ms {
|
||||
background: white;
|
||||
border-radius: var(--border-radius-md);
|
||||
box-shadow: var(--shadow-md);
|
||||
border: 1px solid var(--gray-200);
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@@media (max-width: 768px) {
|
||||
.card-body
|
||||
|
||||
{
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
#questions-container {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.question-group {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Animations */
|
||||
@@keyframes slideDown {
|
||||
from
|
||||
|
||||
{
|
||||
opacity: 0;
|
||||
transform: translateY(-20px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.fade-in {
|
||||
animation: fadeIn 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
@@keyframes fadeIn {
|
||||
from
|
||||
|
||||
{
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Enhanced Focus States */
|
||||
.btn:focus,
|
||||
.form-control:focus {
|
||||
outline: 2px solid var(--primary-color);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Typography Enhancements */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.025em;
|
||||
}
|
||||
|
||||
/* Icon styling */
|
||||
.bi {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
/* Validation styling */
|
||||
.text-danger {
|
||||
color: var(--danger-color) !important;
|
||||
font-weight: 500;
|
||||
font-size: 0.875rem;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="container mt-4">
|
||||
<div class="card justify-content-center p-4 shadow rounded">
|
||||
<div class="card-body">
|
||||
|
|
@ -24,13 +573,13 @@
|
|||
<textarea asp-for="Description" class="form-control"></textarea>
|
||||
<span asp-validation-for="Description" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="container p-5 shadow bg-body-tertiary rounded">
|
||||
<div id="questions-container" class="mx-md-3 mx-lg-3 px-md-3 px-lg-3 mx-sm-0 px-sm-0">
|
||||
<div class="container p-5 shadow bg-body-tertiary rounded" id="questions-container">
|
||||
<div class="mx-md-3 mx-lg-3 px-md-3 px-lg-3 mx-sm-0 px-sm-0">
|
||||
<h3 class="text-primary font-weight-bold">Create Questions</h3>
|
||||
<div class="form-group">
|
||||
@for (int i = 0; i < Model.Questions?.Count; i++)
|
||||
{
|
||||
<div class="question-group" data-question-index="@i">
|
||||
<div class="question-group fade-in" data-question-index="@i">
|
||||
<label>Question @(i + 1)</label>
|
||||
<textarea name="Questions[@i].Text" class="form-control">@Model.Questions[i].Text</textarea>
|
||||
<select name="Questions[@i].Type" asp-items="ViewBag.QuestionTypes" class="form-control question-type">
|
||||
|
|
@ -44,10 +593,12 @@
|
|||
{
|
||||
<div class="answer-group">
|
||||
<input type="text" name="Questions[@i].Answers[@j].Text" class="form-control" value="@Model.Questions?[i]?.Answers?[j]?.Text" />
|
||||
<input type="hidden" name="Questions[@i].Answers[@j].IsOtherOption" value="@Model.Questions?[i]?.Answers?[j]?.IsOtherOption" />
|
||||
<button type="button" class="btn btn-sm btn-danger shadow remove-answer">Remove Answer</button>
|
||||
</div>
|
||||
}
|
||||
<button type="button" class="btn btn-sm btn-success shadow add-answer"><i class="bi bi-plus-square"></i> Create Answer</button>
|
||||
<button type="button" class="btn btn-sm btn-info shadow add-other-option"><i class="bi bi-pencil-square"></i> Add "Other" Option</button>
|
||||
<input type="hidden" name="Questions[@i].Answers" />
|
||||
</div>
|
||||
<button type="button" class="btn btn-sm p-3 btn-danger shadow remove-question">Remove Question <i class="bi bi-trash3-fill"></i></button> |
|
||||
|
|
@ -90,9 +641,10 @@
|
|||
<script>
|
||||
$(document).ready(function () {
|
||||
var questionIndex = @Model.Questions?.Count;
|
||||
|
||||
$("#add-question-btn").click(function () {
|
||||
var newQuestionHtml = `
|
||||
<div class="question-group" data-question-index="${questionIndex}">
|
||||
<div class="question-group fade-in" data-question-index="${questionIndex}">
|
||||
<label>Question ${questionIndex + 1}</label>
|
||||
<textarea name="Questions[${questionIndex}].Text" class="form-control" placeholder="new question"></textarea>
|
||||
<br>
|
||||
|
|
@ -108,14 +660,15 @@
|
|||
newQuestionHtml += `</select>`;
|
||||
|
||||
// Add answers input fields
|
||||
|
||||
newQuestionHtml += `<div class="container-ms mx-5 py-2 px-5 ">`;
|
||||
newQuestionHtml += `<div class="answers-container" data-question-index="${questionIndex}"><br>`;
|
||||
newQuestionHtml += `<label class="h3">Create Answers:</label>`;
|
||||
newQuestionHtml += `<div class="answer-group" data-answer-index="0"><hr class="border border-primary border-1 opacity-35">`;
|
||||
newQuestionHtml += `<label>Answer 1</label>`;
|
||||
newQuestionHtml += `<input type="text" name="Questions[${questionIndex}].Answers[0].Text" class="form-control" placeholder="new answer"/><br>`;
|
||||
newQuestionHtml += `<input type="hidden" name="Questions[${questionIndex}].Answers[0].IsOtherOption" value="false"/>`;
|
||||
newQuestionHtml += `<button type="button" class="btn btn-sm btn-success add-answer shadow mt-2"><i class="bi bi-plus-lg"></i> Add Answer</button>`;
|
||||
newQuestionHtml += `<button type="button" class="btn btn-sm btn-info add-other-option shadow mt-2 ml-2"><i class="bi bi-pencil-square"></i> Add "Other" Option</button>`;
|
||||
newQuestionHtml += `<hr class="border m-2">`
|
||||
newQuestionHtml += `</div> `;
|
||||
newQuestionHtml += `</div>`;
|
||||
|
|
@ -132,15 +685,17 @@
|
|||
questionIndex++;
|
||||
});
|
||||
|
||||
// Add regular answer
|
||||
$("#questions-container").on("click", ".add-answer", function () {
|
||||
var questionIndex = $(this).closest('.answers-container').data('question-index');
|
||||
var answerIndex = $(this).closest('.answers-container').find('.answer-group').length;
|
||||
|
||||
var answerGroupHtml = `
|
||||
<div class="answer-group">
|
||||
<div class="answer-group fade-in">
|
||||
<br>
|
||||
<label class="control-label">Answer ${answerIndex + 1}</label>
|
||||
<input type="text" class="form-control" name="Questions[${questionIndex}].Answers[${answerIndex}].Text" placeholder="new answer"/>
|
||||
<input type="hidden" name="Questions[${questionIndex}].Answers[${answerIndex}].IsOtherOption" value="false"/>
|
||||
<button type="button" class="btn btn-danger btn-sm mt-1 remove-answer"><i class="bi bi-trash3-fill"></i></button>
|
||||
<br>
|
||||
</div>`;
|
||||
|
|
@ -149,6 +704,34 @@
|
|||
$(this).prev('.answer-group').find('.remove-answer').show();
|
||||
});
|
||||
|
||||
// Add "Other" option
|
||||
$("#questions-container").on("click", ".add-other-option", function () {
|
||||
var questionIndex = $(this).closest('.answers-container').data('question-index');
|
||||
var answerIndex = $(this).closest('.answers-container').find('.answer-group').length;
|
||||
|
||||
// Check if "Other" option already exists
|
||||
var existingOther = $(this).closest('.answers-container').find('.other-option-group');
|
||||
if (existingOther.length > 0) {
|
||||
alert('An "Other" option already exists for this question.');
|
||||
return;
|
||||
}
|
||||
|
||||
var otherOptionHtml = `
|
||||
<div class="answer-group other-option-group fade-in">
|
||||
<br>
|
||||
<label class="control-label"><strong>Other Option ${answerIndex + 1}</strong></label>
|
||||
<div class="alert alert-info" role="alert">
|
||||
<small><i class="bi bi-info-circle"></i> This will allow users to write their own answer</small>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="Questions[${questionIndex}].Answers[${answerIndex}].Text" placeholder="Other (please specify)" value="Other (please specify)"/>
|
||||
<input type="hidden" name="Questions[${questionIndex}].Answers[${answerIndex}].IsOtherOption" value="true"/>
|
||||
<button type="button" class="btn btn-warning btn-sm mt-1 remove-answer"><i class="bi bi-trash3-fill"></i> Remove Other Option</button>
|
||||
<br>
|
||||
</div>`;
|
||||
|
||||
$(this).before(otherOptionHtml);
|
||||
});
|
||||
|
||||
// Remove answer dynamically
|
||||
$("#questions-container").on("click", ".remove-answer", function () {
|
||||
$(this).closest('.answer-group').remove();
|
||||
|
|
@ -160,14 +743,13 @@
|
|||
});
|
||||
|
||||
// Save question
|
||||
|
||||
$("#questions-container").on("click", ".save-question", function () {
|
||||
var questionGroup = $(this).closest('.question-group');
|
||||
questionGroup.find('.edit-question').show();
|
||||
questionGroup.find('.remove-question').hide();
|
||||
questionGroup.find('.save-question').hide();
|
||||
questionGroup.find('.form-control').attr('disabled', true); // Disable question text and answer input fields
|
||||
questionGroup.find('.question-type').attr('disabled', true); // Disable question type select field
|
||||
questionGroup.find('.form-control').attr('disabled', true);
|
||||
questionGroup.find('.question-type').attr('disabled', true);
|
||||
questionGroup.find('.answers-container').slideUp();
|
||||
questionGroup.addClass('collapsed');
|
||||
|
||||
|
|
@ -182,8 +764,8 @@
|
|||
questionGroup.find('.save-question').show();
|
||||
questionGroup.find('.remove-question').show();
|
||||
questionGroup.find('.edit-question').hide();
|
||||
questionGroup.find('.form-control').attr('disabled', false); // Enable question text and answer input fields
|
||||
questionGroup.find('.question-type').attr('disabled', false); // Enable question type select field
|
||||
questionGroup.find('.form-control').attr('disabled', false);
|
||||
questionGroup.find('.question-type').attr('disabled', false);
|
||||
questionGroup.find('.answers-container').slideDown();
|
||||
questionGroup.removeClass('collapsed');
|
||||
|
||||
|
|
@ -193,12 +775,10 @@
|
|||
|
||||
// Enable form fields before form submission
|
||||
$("form").submit(function () {
|
||||
$(this).find('.form-control').prop('disabled', false); // Enable all form fields before submission
|
||||
$(this).find('.form-control').prop('disabled', false);
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -98,6 +98,44 @@
|
|||
border-radius: 4px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
/* NEW: Styles for "Other" text responses */
|
||||
.other-text-response {
|
||||
background-color: #fff3cd;
|
||||
border: 1px solid #ffeaa7;
|
||||
border-radius: 6px;
|
||||
padding: 10px 12px;
|
||||
margin-top: 8px;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.other-text-label {
|
||||
font-weight: bold;
|
||||
color: #856404;
|
||||
margin-bottom: 5px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 0.85em;
|
||||
}
|
||||
|
||||
.other-text-content {
|
||||
color: #495057;
|
||||
font-style: italic;
|
||||
line-height: 1.3;
|
||||
background-color: #fff;
|
||||
padding: 6px 10px;
|
||||
border-radius: 4px;
|
||||
border-left: 3px solid #ffc107;
|
||||
}
|
||||
|
||||
.other-option-badge {
|
||||
background-color: #ffc107;
|
||||
color: #212529;
|
||||
font-size: 0.7em;
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="container-fluid mt-3">
|
||||
|
|
@ -244,9 +282,30 @@
|
|||
<div class="d-flex flex-wrap gap-1">
|
||||
@foreach (var answer in responseDetail.ResponseAnswers)
|
||||
{
|
||||
var answerText = question.Answers.FirstOrDefault(a => a.Id == answer.AnswerId)?.Text;
|
||||
<span class="badge bg-success">@answerText</span>
|
||||
var answerObj = question.Answers.FirstOrDefault(a => a.Id == answer.AnswerId);
|
||||
var answerText = answerObj?.Text;
|
||||
<span class="badge bg-success">
|
||||
@answerText
|
||||
@if (answerObj?.IsOtherOption == true)
|
||||
{
|
||||
<span class="other-option-badge">Other</span>
|
||||
}
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
@* NEW: Display "Other" text if available *@
|
||||
@if (!string.IsNullOrEmpty(responseDetail.OtherText))
|
||||
{
|
||||
<div class="other-text-response">
|
||||
<div class="other-text-label">
|
||||
<i class="bi bi-pencil-square me-1"></i>
|
||||
Custom "Other" Response:
|
||||
</div>
|
||||
<div class="other-text-content">
|
||||
@responseDetail.OtherText
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -179,7 +179,6 @@ namespace Web.Controllers
|
|||
}
|
||||
catch (System.Text.Json.JsonException ex)
|
||||
{
|
||||
// Log error if needed
|
||||
Console.WriteLine($"Error parsing tracking data: {ex.Message}");
|
||||
}
|
||||
|
||||
|
|
@ -209,7 +208,10 @@ namespace Web.Controllers
|
|||
: null,
|
||||
ResponseAnswers = answeredQuestion.SelectedAnswerIds
|
||||
.Select(aid => new ResponseAnswer { AnswerId = aid })
|
||||
.ToList()
|
||||
.ToList(),
|
||||
|
||||
// ✅ NEW: Handle Other Text
|
||||
OtherText = GetOtherTextForQuestion(answeredQuestion, dbQuestion)
|
||||
};
|
||||
}
|
||||
else if (skippedInfo != null)
|
||||
|
|
@ -252,6 +254,34 @@ namespace Web.Controllers
|
|||
return responseDetails;
|
||||
}
|
||||
|
||||
// ✅ NEW METHOD: Extract other text for a question
|
||||
private string GetOtherTextForQuestion(ResponseQuestionViewModel answeredQuestion, Question dbQuestion)
|
||||
{
|
||||
if (answeredQuestion.OtherTexts == null || !answeredQuestion.OtherTexts.Any())
|
||||
return null;
|
||||
|
||||
var otherTexts = new List<string>();
|
||||
|
||||
// Loop through selected answers and check if any are "other" options
|
||||
foreach (var selectedAnswerId in answeredQuestion.SelectedAnswerIds)
|
||||
{
|
||||
// Find the corresponding answer in the database
|
||||
var dbAnswer = dbQuestion.Answers.FirstOrDefault(a => a.Id == selectedAnswerId);
|
||||
|
||||
// If this answer is an "other" option and has custom text
|
||||
if (dbAnswer != null && dbAnswer.IsOtherOption && answeredQuestion.OtherTexts.ContainsKey(selectedAnswerId))
|
||||
{
|
||||
var customText = answeredQuestion.OtherTexts[selectedAnswerId];
|
||||
if (!string.IsNullOrWhiteSpace(customText))
|
||||
{
|
||||
otherTexts.Add($"{dbAnswer.Text}: {customText}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return otherTexts.Any() ? string.Join("; ", otherTexts) : null;
|
||||
}
|
||||
|
||||
private int GetQuestionNumber(int questionId, List<Question> allQuestions)
|
||||
{
|
||||
return allQuestions.FindIndex(q => q.Id == questionId) + 1;
|
||||
|
|
@ -265,7 +295,11 @@ namespace Web.Controllers
|
|||
bool hasAnswerResponse = question.SelectedAnswerIds != null &&
|
||||
question.SelectedAnswerIds.Any();
|
||||
|
||||
return hasTextResponse || hasAnswerResponse;
|
||||
// ✅ NEW: Check for other text responses
|
||||
bool hasOtherTextResponse = question.OtherTexts != null &&
|
||||
question.OtherTexts.Any(kv => !string.IsNullOrWhiteSpace(kv.Value));
|
||||
|
||||
return hasTextResponse || hasAnswerResponse || hasOtherTextResponse;
|
||||
}
|
||||
|
||||
// Add this class for JSON deserialization
|
||||
|
|
@ -438,7 +472,8 @@ namespace Web.Controllers
|
|||
{
|
||||
Id = a.Id,
|
||||
Text = a.Text,
|
||||
ConditionJson = a.ConditionJson // Add this line
|
||||
IsOtherOption = a.IsOtherOption, // ← ADD THIS LINE!
|
||||
ConditionJson = a.ConditionJson
|
||||
}).ToList()
|
||||
}).ToList()
|
||||
};
|
||||
|
|
|
|||
844
Web/Migrations/20250813151802_AddIsOtherOptionToAnswer.Designer.cs
generated
Normal file
844
Web/Migrations/20250813151802_AddIsOtherOptionToAnswer.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,844 @@
|
|||
// <auto-generated />
|
||||
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("20250813151802_AddIsOtherOptionToAnswer")]
|
||||
partial class AddIsOtherOptionToAnswer
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "8.0.4")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("nvarchar(256)");
|
||||
|
||||
b.Property<string>("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<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetRoleClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("ProviderKey")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("ProviderDisplayName")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetUserRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("AspNetUserTokens", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.Address", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("CVR")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("City")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Country")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Mobile")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("PostalCode")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("State")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Street")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Addresss");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.Answer", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ConditionJson")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("IsOtherOption")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<int>("QuestionId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Text")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("QuestionId");
|
||||
|
||||
b.ToTable("Answers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.ApplicationUser", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<int>("AccessFailedCount")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("nvarchar(256)");
|
||||
|
||||
b.Property<bool>("EmailConfirmed")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("FirstName")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("LockoutEnabled")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||
.HasColumnType("datetimeoffset");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("nvarchar(256)");
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("nvarchar(256)");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("SecurityStamp")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("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("Model.Banner", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Content")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("ImageUrl")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("LinkUrl")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Banners");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.Footer", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Content")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("CreatedBy")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("ImageUlr")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<DateTime>("LastUpdated")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Owner")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Sitecopyright")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("UpdatedBy")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Footers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.FooterSocialMedia", b =>
|
||||
{
|
||||
b.Property<int>("FooterId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("SocialId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("FooterId", "SocialId");
|
||||
|
||||
b.HasIndex("SocialId");
|
||||
|
||||
b.ToTable("FooterSocialMedias");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.Page", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("BannerId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<int>("FooterId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BannerId");
|
||||
|
||||
b.HasIndex("FooterId");
|
||||
|
||||
b.ToTable("Pages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.Question", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("QuestionnaireId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Text")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("QuestionnaireId");
|
||||
|
||||
b.ToTable("Questions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.Questionnaire", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Questionnaires");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.Response", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("QuestionnaireId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<DateTime>("SubmissionDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("UserEmail")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("QuestionnaireId");
|
||||
|
||||
b.ToTable("Responses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.ResponseAnswer", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("AnswerId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("ResponseDetailId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ResponseDetailId");
|
||||
|
||||
b.ToTable("ResponseAnswers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.ResponseDetail", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("QuestionId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("QuestionType")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("ResponseId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("SkipReason")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("TextResponse")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("QuestionId");
|
||||
|
||||
b.HasIndex("ResponseId");
|
||||
|
||||
b.ToTable("ResponseDetails");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.SentNewsletterEamil", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Body")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Geo")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("IpAddress")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("IsBlocked")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsBounced")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsClicked")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsDelivered")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsOpened")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsSent")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsSpam")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsUnsubscribed")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<DateTime>("ReceivedActivity")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("RecipientEmail")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<DateTime>("SentDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("Subject")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("SentNewsletterEamils");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.SocialMedia", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Url")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("SocialMedia");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.Subscription", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("IsSubscribed")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Subscriptions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Model.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("Model.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Model.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.HasOne("Model.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
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.HasOne("Model.Footer", "footer")
|
||||
.WithMany()
|
||||
.HasForeignKey("FooterId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("banner");
|
||||
|
||||
b.Navigation("footer");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.Question", b =>
|
||||
{
|
||||
b.HasOne("Model.Questionnaire", "Questionnaire")
|
||||
.WithMany("Questions")
|
||||
.HasForeignKey("QuestionnaireId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Questionnaire");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.Response", b =>
|
||||
{
|
||||
b.HasOne("Model.Questionnaire", "Questionnaire")
|
||||
.WithMany()
|
||||
.HasForeignKey("QuestionnaireId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Questionnaire");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.ResponseAnswer", b =>
|
||||
{
|
||||
b.HasOne("Model.ResponseDetail", "ResponseDetail")
|
||||
.WithMany("ResponseAnswers")
|
||||
.HasForeignKey("ResponseDetailId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("ResponseDetail");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.ResponseDetail", b =>
|
||||
{
|
||||
b.HasOne("Model.Question", "Question")
|
||||
.WithMany()
|
||||
.HasForeignKey("QuestionId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Model.Response", "Response")
|
||||
.WithMany("ResponseDetails")
|
||||
.HasForeignKey("ResponseId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Question");
|
||||
|
||||
b.Navigation("Response");
|
||||
});
|
||||
|
||||
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.Response", b =>
|
||||
{
|
||||
b.Navigation("ResponseDetails");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.ResponseDetail", b =>
|
||||
{
|
||||
b.Navigation("ResponseAnswers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.SocialMedia", b =>
|
||||
{
|
||||
b.Navigation("FooterSocialMedias");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
29
Web/Migrations/20250813151802_AddIsOtherOptionToAnswer.cs
Normal file
29
Web/Migrations/20250813151802_AddIsOtherOptionToAnswer.cs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Web.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddIsOtherOptionToAnswer : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "IsOtherOption",
|
||||
table: "Answers",
|
||||
type: "bit",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "IsOtherOption",
|
||||
table: "Answers");
|
||||
}
|
||||
}
|
||||
}
|
||||
847
Web/Migrations/20250813162055_AddOtherTextToResponseDetail.Designer.cs
generated
Normal file
847
Web/Migrations/20250813162055_AddOtherTextToResponseDetail.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,847 @@
|
|||
// <auto-generated />
|
||||
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("20250813162055_AddOtherTextToResponseDetail")]
|
||||
partial class AddOtherTextToResponseDetail
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "8.0.4")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("nvarchar(256)");
|
||||
|
||||
b.Property<string>("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<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetRoleClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("ProviderKey")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("ProviderDisplayName")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetUserRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("AspNetUserTokens", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.Address", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("CVR")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("City")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Country")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Mobile")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("PostalCode")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("State")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Street")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Addresss");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.Answer", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ConditionJson")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("IsOtherOption")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<int>("QuestionId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Text")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("QuestionId");
|
||||
|
||||
b.ToTable("Answers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.ApplicationUser", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<int>("AccessFailedCount")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("nvarchar(256)");
|
||||
|
||||
b.Property<bool>("EmailConfirmed")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("FirstName")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("LockoutEnabled")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||
.HasColumnType("datetimeoffset");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("nvarchar(256)");
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("nvarchar(256)");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("SecurityStamp")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("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("Model.Banner", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Content")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("ImageUrl")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("LinkUrl")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Banners");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.Footer", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Content")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("CreatedBy")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("ImageUlr")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<DateTime>("LastUpdated")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Owner")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Sitecopyright")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("UpdatedBy")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Footers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.FooterSocialMedia", b =>
|
||||
{
|
||||
b.Property<int>("FooterId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("SocialId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("FooterId", "SocialId");
|
||||
|
||||
b.HasIndex("SocialId");
|
||||
|
||||
b.ToTable("FooterSocialMedias");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.Page", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("BannerId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<int>("FooterId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BannerId");
|
||||
|
||||
b.HasIndex("FooterId");
|
||||
|
||||
b.ToTable("Pages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.Question", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("QuestionnaireId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Text")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("QuestionnaireId");
|
||||
|
||||
b.ToTable("Questions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.Questionnaire", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Questionnaires");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.Response", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("QuestionnaireId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<DateTime>("SubmissionDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("UserEmail")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("QuestionnaireId");
|
||||
|
||||
b.ToTable("Responses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.ResponseAnswer", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("AnswerId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("ResponseDetailId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ResponseDetailId");
|
||||
|
||||
b.ToTable("ResponseAnswers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.ResponseDetail", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("OtherText")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<int>("QuestionId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("QuestionType")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("ResponseId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("SkipReason")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("TextResponse")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("QuestionId");
|
||||
|
||||
b.HasIndex("ResponseId");
|
||||
|
||||
b.ToTable("ResponseDetails");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.SentNewsletterEamil", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Body")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Geo")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("IpAddress")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("IsBlocked")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsBounced")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsClicked")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsDelivered")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsOpened")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsSent")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsSpam")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsUnsubscribed")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<DateTime>("ReceivedActivity")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("RecipientEmail")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<DateTime>("SentDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("Subject")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("SentNewsletterEamils");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.SocialMedia", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Url")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("SocialMedia");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.Subscription", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("IsSubscribed")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Subscriptions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Model.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("Model.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Model.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.HasOne("Model.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
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.HasOne("Model.Footer", "footer")
|
||||
.WithMany()
|
||||
.HasForeignKey("FooterId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("banner");
|
||||
|
||||
b.Navigation("footer");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.Question", b =>
|
||||
{
|
||||
b.HasOne("Model.Questionnaire", "Questionnaire")
|
||||
.WithMany("Questions")
|
||||
.HasForeignKey("QuestionnaireId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Questionnaire");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.Response", b =>
|
||||
{
|
||||
b.HasOne("Model.Questionnaire", "Questionnaire")
|
||||
.WithMany()
|
||||
.HasForeignKey("QuestionnaireId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Questionnaire");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.ResponseAnswer", b =>
|
||||
{
|
||||
b.HasOne("Model.ResponseDetail", "ResponseDetail")
|
||||
.WithMany("ResponseAnswers")
|
||||
.HasForeignKey("ResponseDetailId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("ResponseDetail");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.ResponseDetail", b =>
|
||||
{
|
||||
b.HasOne("Model.Question", "Question")
|
||||
.WithMany()
|
||||
.HasForeignKey("QuestionId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Model.Response", "Response")
|
||||
.WithMany("ResponseDetails")
|
||||
.HasForeignKey("ResponseId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Question");
|
||||
|
||||
b.Navigation("Response");
|
||||
});
|
||||
|
||||
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.Response", b =>
|
||||
{
|
||||
b.Navigation("ResponseDetails");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.ResponseDetail", b =>
|
||||
{
|
||||
b.Navigation("ResponseAnswers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Model.SocialMedia", b =>
|
||||
{
|
||||
b.Navigation("FooterSocialMedias");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Web.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddOtherTextToResponseDetail : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "OtherText",
|
||||
table: "ResponseDetails",
|
||||
type: "nvarchar(max)",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "OtherText",
|
||||
table: "ResponseDetails");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -209,6 +209,9 @@ namespace Web.Migrations
|
|||
b.Property<string>("ConditionJson")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("IsOtherOption")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<int>("QuestionId")
|
||||
.HasColumnType("int");
|
||||
|
||||
|
|
@ -522,6 +525,9 @@ namespace Web.Migrations
|
|||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("OtherText")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<int>("QuestionId")
|
||||
.HasColumnType("int");
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
public string? Text { get; set; } // Answer text
|
||||
|
||||
public int? Count { get; set; }
|
||||
public bool IsOtherOption { get; set; } = false;
|
||||
public string? ConditionJson { get; set; } // Add this line for conditional logic
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,5 +16,7 @@ namespace Web.ViewModel.QuestionnaireVM
|
|||
public List<int> SelectedAnswerIds { get; set; } = new List<int>();
|
||||
|
||||
public List<string> SelectedText { get; set; } = new List<string>();
|
||||
|
||||
public Dictionary<int, string> OtherTexts { get; set; } = new Dictionary<int, string>();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -192,6 +192,59 @@
|
|||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* Other Option Styling */
|
||||
.other-option-container {
|
||||
position: relative;
|
||||
background: linear-gradient(135deg, rgba(245, 158, 11, 0.1) 0%, rgba(217, 119, 6, 0.05) 100%);
|
||||
border: 1px solid rgba(245, 158, 11, 0.2);
|
||||
border-radius: 16px;
|
||||
padding: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.other-option-badge {
|
||||
background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
|
||||
color: white;
|
||||
padding: 4px 8px;
|
||||
border-radius: 8px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
margin-left: 8px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.other-text-container {
|
||||
margin-top: 12px;
|
||||
padding: 12px;
|
||||
background: var(--surface-secondary);
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--border-accent);
|
||||
animation: morphIn 0.3s ease;
|
||||
display: none !important; /* Initially hidden */
|
||||
}
|
||||
|
||||
.other-text-container.show {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.other-text-input {
|
||||
background: var(--surface-glass);
|
||||
border: 1px solid var(--border-subtle);
|
||||
color: var(--text-primary);
|
||||
border-radius: 12px;
|
||||
padding: 12px 16px;
|
||||
font-size: 14px;
|
||||
resize: vertical;
|
||||
min-height: 80px;
|
||||
}
|
||||
|
||||
.other-text-input:focus {
|
||||
border-color: var(--accent-primary);
|
||||
box-shadow: 0 0 0 3px rgba(74, 144, 164, 0.15);
|
||||
background: rgba(26, 42, 64, 0.8);
|
||||
}
|
||||
|
||||
/* Next-Gen Buttons */
|
||||
.btn {
|
||||
border-radius: 16px;
|
||||
|
|
@ -1011,9 +1064,34 @@
|
|||
<div class="form-group">
|
||||
@foreach (var answer in question.Answers)
|
||||
{
|
||||
<div class="form-check mb-2">
|
||||
<input class="form-check-input" id="question@(i)_answer@(answer.Id)" type="checkbox" name="Questions[@i].SelectedAnswerIds" value="@answer.Id" data-condition="@answer.ConditionJson">
|
||||
<label class="form-check-label" for="question@(i)_answer@(answer.Id)">@answer.Text</label>
|
||||
<div class="form-check mb-2 @(answer.IsOtherOption ? "other-option-container" : "")">
|
||||
<input class="form-check-input @(answer.IsOtherOption ? "other-option-input" : "")"
|
||||
id="question@(i)_answer@(answer.Id)"
|
||||
type="checkbox"
|
||||
name="Questions[@i].SelectedAnswerIds"
|
||||
value="@answer.Id"
|
||||
data-condition="@answer.ConditionJson"
|
||||
data-question-index="@i"
|
||||
data-answer-id="@answer.Id"
|
||||
data-is-other="@answer.IsOtherOption.ToString().ToLower()">
|
||||
<label class="form-check-label" for="question@(i)_answer@(answer.Id)">
|
||||
@answer.Text
|
||||
@if (answer.IsOtherOption)
|
||||
{
|
||||
<span class="other-option-badge">Other Option</span>
|
||||
}
|
||||
</label>
|
||||
|
||||
@if (answer.IsOtherOption)
|
||||
{
|
||||
<div class="other-text-container" id="otherText_@(i)_@(answer.Id)" style="display: none;">
|
||||
<textarea class="form-control other-text-input"
|
||||
name="Questions[@i].OtherTexts[@answer.Id]"
|
||||
id="otherTextArea_@(i)_@(answer.Id)"
|
||||
rows="3"
|
||||
placeholder="Please specify..."></textarea>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
|
@ -1023,9 +1101,34 @@
|
|||
<div class="form-check">
|
||||
@foreach (var answer in question.Answers)
|
||||
{
|
||||
<div class="form-check mb-2">
|
||||
<input class="form-check-input answer-input" type="radio" id="question@(i)_answer@(answer.Id)" name="Questions[@i].SelectedAnswerIds" value="@answer.Id" data-condition="@answer.ConditionJson">
|
||||
<label class="form-check-label" for="question@(i)_answer@(answer.Id)">@answer.Text</label>
|
||||
<div class="form-check mb-2 @(answer.IsOtherOption ? "other-option-container" : "")">
|
||||
<input class="form-check-input answer-input @(answer.IsOtherOption ? "other-option-input" : "")"
|
||||
type="radio"
|
||||
id="question@(i)_answer@(answer.Id)"
|
||||
name="Questions[@i].SelectedAnswerIds"
|
||||
value="@answer.Id"
|
||||
data-condition="@answer.ConditionJson"
|
||||
data-question-index="@i"
|
||||
data-answer-id="@answer.Id"
|
||||
data-is-other="@answer.IsOtherOption.ToString().ToLower()">
|
||||
<label class="form-check-label" for="question@(i)_answer@(answer.Id)">
|
||||
@answer.Text
|
||||
@if (answer.IsOtherOption)
|
||||
{
|
||||
<span class="other-option-badge">Other Option</span>
|
||||
}
|
||||
</label>
|
||||
|
||||
@if (answer.IsOtherOption)
|
||||
{
|
||||
<div class="other-text-container" id="otherText_@(i)_@(answer.Id)" style="display: none;">
|
||||
<textarea class="form-control other-text-input"
|
||||
name="Questions[@i].OtherTexts[@answer.Id]"
|
||||
id="otherTextArea_@(i)_@(answer.Id)"
|
||||
rows="3"
|
||||
placeholder="Please specify..."></textarea>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
|
@ -1232,6 +1335,81 @@
|
|||
const form = document.getElementById('questionnaireForm');
|
||||
if (!form) { console.error('Form not found!'); return; }
|
||||
|
||||
// ===== OTHER OPTION FUNCTIONALITY =====
|
||||
// Handle showing/hiding text areas for "Other" options
|
||||
function initializeOtherOptions() {
|
||||
console.log('Initializing other options...');
|
||||
|
||||
// Handle checkbox other options
|
||||
$(document).on('change', 'input[type="checkbox"]', function() {
|
||||
console.log('Checkbox changed:', this);
|
||||
const $checkbox = $(this);
|
||||
const isOther = $checkbox.attr('data-is-other') === 'true';
|
||||
|
||||
if (isOther) {
|
||||
console.log('Other checkbox detected');
|
||||
const questionIndex = $checkbox.attr('data-question-index');
|
||||
const answerId = $checkbox.attr('data-answer-id');
|
||||
const $textContainer = $(`#otherText_${questionIndex}_${answerId}`);
|
||||
const $textArea = $(`#otherTextArea_${questionIndex}_${answerId}`);
|
||||
|
||||
console.log('Looking for container:', `#otherText_${questionIndex}_${answerId}`);
|
||||
console.log('Container found:', $textContainer.length);
|
||||
|
||||
if ($checkbox.is(':checked')) {
|
||||
console.log('Showing text container');
|
||||
$textContainer.addClass('show').slideDown(300);
|
||||
$textArea.focus();
|
||||
$textArea.prop('required', true);
|
||||
} else {
|
||||
console.log('Hiding text container');
|
||||
$textContainer.removeClass('show').slideUp(300);
|
||||
$textArea.val('');
|
||||
$textArea.prop('required', false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Handle radio button other options
|
||||
$(document).on('change', 'input[type="radio"]', function() {
|
||||
console.log('Radio button changed:', this);
|
||||
const $radio = $(this);
|
||||
const questionIndex = $radio.attr('data-question-index');
|
||||
const isOther = $radio.attr('data-is-other') === 'true';
|
||||
|
||||
// First, hide all other text containers for this question
|
||||
if (questionIndex) {
|
||||
console.log('Hiding all other containers for question:', questionIndex);
|
||||
$(`.other-text-container[id^="otherText_${questionIndex}_"]`).removeClass('show').slideUp(300);
|
||||
$(`.other-text-input[id^="otherTextArea_${questionIndex}_"]`).prop('required', false).val('');
|
||||
}
|
||||
|
||||
// If this is an other option and it's selected, show its text container
|
||||
if (isOther && $radio.is(':checked')) {
|
||||
console.log('Other radio selected');
|
||||
const answerId = $radio.attr('data-answer-id');
|
||||
const $textContainer = $(`#otherText_${questionIndex}_${answerId}`);
|
||||
const $textArea = $(`#otherTextArea_${questionIndex}_${answerId}`);
|
||||
|
||||
console.log('Showing text container for radio');
|
||||
$textContainer.addClass('show').slideDown(300);
|
||||
$textArea.focus();
|
||||
$textArea.prop('required', true);
|
||||
}
|
||||
});
|
||||
|
||||
// Debug: List all other option inputs
|
||||
console.log('Other option inputs found:', $('input[data-is-other="true"]').length);
|
||||
$('input[data-is-other="true"]').each(function() {
|
||||
console.log('Other input:', this, 'Question:', $(this).attr('data-question-index'), 'Answer:', $(this).attr('data-answer-id'));
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize other options functionality when DOM is ready
|
||||
$(document).ready(function() {
|
||||
initializeOtherOptions();
|
||||
});
|
||||
|
||||
// Tracking
|
||||
let questionsShownArray = [1];
|
||||
let questionsSkippedArray = [];
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue