generate report for pdf and excel completed
This commit is contained in:
parent
9c560a798c
commit
aacc23d5ef
5 changed files with 305 additions and 143 deletions
|
|
@ -1,10 +1,15 @@
|
||||||
using Data;
|
using Data;
|
||||||
|
using iTextSharp.text;
|
||||||
|
using iTextSharp.text.pdf;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Model;
|
using Model;
|
||||||
|
using OfficeOpenXml;
|
||||||
using Services.Interaces;
|
using Services.Interaces;
|
||||||
using Web.ViewModel.QuestionnaireVM;
|
using Web.ViewModel.QuestionnaireVM;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace Web.Areas.Admin.Controllers
|
namespace Web.Areas.Admin.Controllers
|
||||||
{
|
{
|
||||||
public class UserResponseStatusController : Controller
|
public class UserResponseStatusController : Controller
|
||||||
|
|
@ -67,34 +72,269 @@ namespace Web.Areas.Admin.Controllers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//public async Task<IActionResult> UserResponsesStatus(string userEmail)
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> DeleteSelected(string[] selectedEmails)
|
||||||
|
{
|
||||||
|
if (selectedEmails == null || selectedEmails.Length == 0)
|
||||||
|
{
|
||||||
|
return RedirectToAction(nameof(Index));
|
||||||
|
}
|
||||||
|
|
||||||
|
var responsesToDelete = await _context.Responses
|
||||||
|
.Where(r => selectedEmails.Contains(r.UserEmail))
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
if (responsesToDelete.Any())
|
||||||
|
{
|
||||||
|
_context.Responses.RemoveRange(responsesToDelete);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
return RedirectToAction(nameof(Index));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<IActionResult> GenerateReport(string userEmail, string format)
|
||||||
|
{
|
||||||
|
var responses = await _context.Responses
|
||||||
|
.Include(r => r.Questionnaire)
|
||||||
|
.Include(r => r.ResponseDetails)
|
||||||
|
.ThenInclude(rd => rd.Question)
|
||||||
|
.ThenInclude(q => q.Answers)
|
||||||
|
.Include(r => r.ResponseDetails)
|
||||||
|
.ThenInclude(rd => rd.ResponseAnswers)
|
||||||
|
.Where(r => r.UserEmail == userEmail)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
if (responses == null || !responses.Any())
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (format.ToLower())
|
||||||
|
{
|
||||||
|
case "pdf":
|
||||||
|
return GeneratePdfReport(responses);
|
||||||
|
case "excel":
|
||||||
|
return GenerateExcelReport(responses);
|
||||||
|
default:
|
||||||
|
return BadRequest("Unsupported report format.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private IActionResult GeneratePdfReport(List<Response> responses)
|
||||||
|
{
|
||||||
|
var userName = responses.First().UserName;
|
||||||
|
var userEmail = responses.First().UserEmail;
|
||||||
|
|
||||||
|
var stream = new MemoryStream();
|
||||||
|
var document = new Document(PageSize.A4, 50, 50, 25, 25);
|
||||||
|
var writer = PdfWriter.GetInstance(document, stream);
|
||||||
|
writer.CloseStream = false; // Prevent the stream from being closed when the document is closed
|
||||||
|
|
||||||
|
document.Open();
|
||||||
|
|
||||||
|
// Add a title
|
||||||
|
var titleFont = FontFactory.GetFont(FontFactory.HELVETICA_BOLD, 18, BaseColor.BLACK);
|
||||||
|
var title = new Paragraph($"Report for {userName} ({userEmail})", titleFont)
|
||||||
|
{
|
||||||
|
Alignment = Element.ALIGN_CENTER,
|
||||||
|
SpacingAfter = 20
|
||||||
|
};
|
||||||
|
document.Add(title);
|
||||||
|
|
||||||
|
// Add a logo
|
||||||
|
var logoPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images", "logo.png");
|
||||||
|
if (System.IO.File.Exists(logoPath))
|
||||||
|
{
|
||||||
|
var logo = Image.GetInstance(logoPath);
|
||||||
|
logo.ScaleToFit(100f, 100f);
|
||||||
|
logo.Alignment = Image.ALIGN_CENTER;
|
||||||
|
document.Add(logo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a table for each response
|
||||||
|
var headerFont = FontFactory.GetFont(FontFactory.HELVETICA_BOLD, 14, BaseColor.WHITE);
|
||||||
|
var cellFont = FontFactory.GetFont(FontFactory.HELVETICA, 12, BaseColor.BLACK);
|
||||||
|
|
||||||
|
foreach (var response in responses)
|
||||||
|
{
|
||||||
|
var table = new PdfPTable(2)
|
||||||
|
{
|
||||||
|
WidthPercentage = 100,
|
||||||
|
SpacingBefore = 20,
|
||||||
|
SpacingAfter = 20
|
||||||
|
};
|
||||||
|
table.SetWidths(new float[] { 1, 3 });
|
||||||
|
|
||||||
|
var cell = new PdfPCell(new Phrase($"Survey: {response.Questionnaire.Title}", headerFont))
|
||||||
|
{
|
||||||
|
Colspan = 2,
|
||||||
|
BackgroundColor = new BaseColor(0, 150, 0),
|
||||||
|
HorizontalAlignment = Element.ALIGN_CENTER,
|
||||||
|
Padding = 10
|
||||||
|
};
|
||||||
|
table.AddCell(cell);
|
||||||
|
|
||||||
|
table.AddCell(new PdfPCell(new Phrase("Submitted on:", cellFont)) { Padding = 5 });
|
||||||
|
table.AddCell(new PdfPCell(new Phrase(response.SubmissionDate.ToString(), cellFont)) { Padding = 5 });
|
||||||
|
|
||||||
|
foreach (var detail in response.ResponseDetails)
|
||||||
|
{
|
||||||
|
table.AddCell(new PdfPCell(new Phrase("Question:", cellFont)) { Padding = 5 });
|
||||||
|
table.AddCell(new PdfPCell(new Phrase(detail.Question.Text, cellFont)) { Padding = 5 });
|
||||||
|
|
||||||
|
if (detail.QuestionType == QuestionType.Text || detail.QuestionType == QuestionType.Slider || detail.QuestionType == QuestionType.Open_ended)
|
||||||
|
{
|
||||||
|
table.AddCell(new PdfPCell(new Phrase("Answer:", cellFont)) { Padding = 5 });
|
||||||
|
table.AddCell(new PdfPCell(new Phrase(detail.TextResponse, cellFont)) { Padding = 5 });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
table.AddCell(new PdfPCell(new Phrase(answers, cellFont)) { Padding = 5 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.Add(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.Close();
|
||||||
|
writer.Close();
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
return File(stream, "application/pdf", $"{userName}_report.pdf");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private IActionResult GenerateExcelReport(List<Response> responses)
|
||||||
|
{
|
||||||
|
var userName = responses.First().UserName;
|
||||||
|
var userEmail = responses.First().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 {userName} ({userEmail})";
|
||||||
|
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;
|
||||||
|
foreach (var response in responses)
|
||||||
|
{
|
||||||
|
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++;
|
||||||
|
}
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
|
||||||
|
worksheet.Cells.AutoFitColumns();
|
||||||
|
|
||||||
|
var stream = new MemoryStream();
|
||||||
|
package.SaveAs(stream);
|
||||||
|
stream.Position = 0;
|
||||||
|
|
||||||
|
return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $"{userName}_report.xlsx");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//private IActionResult GenerateExcelReport(List<Response> responses)
|
||||||
//{
|
//{
|
||||||
// var responses = await _context.Responses
|
|
||||||
// .Include(r => r.Questionnaire)
|
|
||||||
// .Include(r => r.ResponseDetails)
|
|
||||||
// .ThenInclude(rd => rd.Question)
|
|
||||||
// .Include(r => r.ResponseDetails)
|
|
||||||
|
|
||||||
// .ThenInclude(rd => rd.ResponseAnswers)
|
|
||||||
// .Where(r => r.UserEmail == userEmail)
|
|
||||||
// .ToListAsync();
|
|
||||||
|
|
||||||
// if (responses == null || !responses.Any())
|
|
||||||
// {
|
|
||||||
// return NotFound();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var userName = responses.First().UserName;
|
// var userName = responses.First().UserName;
|
||||||
|
// var userEmail = responses.First().UserEmail;
|
||||||
|
|
||||||
// var viewModel = new UserResponsesViewModel
|
// using (var package = new ExcelPackage())
|
||||||
// {
|
// {
|
||||||
// UserName = userName,
|
// var worksheet = package.Workbook.Worksheets.Add("Report");
|
||||||
// UserEmail = userEmail,
|
|
||||||
// Responses = responses
|
|
||||||
// };
|
|
||||||
|
|
||||||
// return View(viewModel);
|
// worksheet.Cells[1, 1].Value = $"Report for {userName} ({userEmail})";
|
||||||
|
// worksheet.Cells[2, 1].Value = "Survey";
|
||||||
|
// worksheet.Cells[2, 2].Value = "Submitted on";
|
||||||
|
// worksheet.Cells[2, 3].Value = "Question";
|
||||||
|
// worksheet.Cells[2, 4].Value = "Response";
|
||||||
|
|
||||||
|
// var row = 3;
|
||||||
|
// foreach (var response in responses)
|
||||||
|
// {
|
||||||
|
// 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++;
|
||||||
|
// }
|
||||||
|
// row++;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// var stream = new MemoryStream();
|
||||||
|
// package.SaveAs(stream);
|
||||||
|
// stream.Position = 0;
|
||||||
|
|
||||||
|
// return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $"{userName}_report.xlsx");
|
||||||
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,36 @@
|
||||||
@model IEnumerable<UserResponsesViewModel>
|
@model IEnumerable<UserResponsesViewModel>
|
||||||
|
|
||||||
@{
|
@{
|
||||||
ViewData["Title"] = "User Responses status";
|
ViewData["Title"] = "User Responses Status";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="container-fluid mt-4 mb-5">
|
<div class="container-fluid mt-4 mb-5">
|
||||||
<div class="col-10 offset-1 ">
|
<div class="col-10 offset-1">
|
||||||
|
|
||||||
|
<div class="card p-4 shadow-lg rounded-2">
|
||||||
|
|
||||||
<div class="card p-4 shadow-lg rounded-2">
|
|
||||||
|
|
||||||
<h3 class="text-primary">Response status</h3>
|
<h3 class="text-primary">Response status</h3>
|
||||||
|
|
||||||
<form asp-action="DeleteSelected" method="post">
|
<form asp-action="DeleteSelected" method="post">
|
||||||
<table class="table table-responsive w-100 d-block d-md-table table-bordered table-hover">
|
<table class="table table-responsive w-100 d-block d-md-table table-bordered table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
<th>
|
||||||
|
<input type="checkbox" id="selectAll" />
|
||||||
|
</th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Email</th>
|
<th>Email</th>
|
||||||
<th>Survey</th>
|
<th>Survey</th>
|
||||||
|
|
||||||
<th>Action</th>
|
<th>Action</th>
|
||||||
|
|
||||||
<!-- Additional headers omitted for brevity -->
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach (var item in Model)
|
@foreach (var item in Model)
|
||||||
{
|
{
|
||||||
<tr>
|
<tr>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" name="selectedEmails" value="@item.UserEmail" class="selectCheckbox" />
|
||||||
|
</td>
|
||||||
<td>@item.UserName</td>
|
<td>@item.UserName</td>
|
||||||
<td>@item.UserEmail</td>
|
<td>@item.UserEmail</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
@ -44,12 +44,11 @@
|
||||||
<td class="text-end">
|
<td class="text-end">
|
||||||
<a asp-controller="UserResponseStatus" asp-action="UserResponsesStatus" asp-route-UserEmail="@item.UserEmail" class="btn btn-info btn-sm"><i class="bi bi-eye"></i> View Responses status</a>
|
<a asp-controller="UserResponseStatus" asp-action="UserResponsesStatus" asp-route-UserEmail="@item.UserEmail" class="btn btn-info btn-sm"><i class="bi bi-eye"></i> View Responses status</a>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<button type="submit" class="btn btn-danger mt-2">Delete Selected</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -57,6 +56,13 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<script>
|
||||||
|
document.getElementById('selectAll').addEventListener('click', function (event) {
|
||||||
|
var checkboxes = document.querySelectorAll('.selectCheckbox');
|
||||||
|
checkboxes.forEach(function (checkbox) {
|
||||||
|
checkbox.checked = event.target.checked;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
background-color: #007bff;
|
background-color: #aed5ff;
|
||||||
color: white;
|
color: white;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
|
@ -56,6 +56,8 @@
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="container-fluid mt-3">
|
<div class="container-fluid mt-3">
|
||||||
<p>
|
<p>
|
||||||
<a asp-action="Index" class="btn btn-primary btn-sm">Back to list</a>
|
<a asp-action="Index" class="btn btn-primary btn-sm">Back to list</a>
|
||||||
|
|
@ -63,24 +65,34 @@
|
||||||
|
|
||||||
<div class="card p-5 m-3 shadow">
|
<div class="card p-5 m-3 shadow">
|
||||||
<div class="bd-callout bd-callout-primary">
|
<div class="bd-callout bd-callout-primary">
|
||||||
<h4 class="text-primary">User Responses</h4>
|
|
||||||
<text>@Model.UserName (@Model.UserEmail)</text>
|
<h6 class="text-primary font-weight-bold"><i class="bi bi-person"></i> @Model.UserName (@Model.UserEmail)</h6>
|
||||||
</div>
|
<p class="text-info"><i class="bi bi-calculator"></i> Total responses: @Model.Responses.Count()</p>
|
||||||
|
|
||||||
|
|
||||||
|
<a asp-action="GenerateReport" asp-route-userEmail="@Model.UserEmail" asp-route-format="pdf" class="btn btn-info btn-sm">
|
||||||
|
<i class="bi bi-filetype-pdf"></i> Generate PDF Report
|
||||||
|
</a>
|
||||||
|
<a asp-action="GenerateReport" asp-route-userEmail="@Model.UserEmail" asp-route-format="excel" class="btn btn-info btn-sm">
|
||||||
|
<i class="bi bi-file-excel"></i> Generate Excel Report
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Stepper -->
|
<!-- Stepper -->
|
||||||
<div class="stepper-wrapper">
|
<div class="stepper-wrapper">
|
||||||
@foreach (var response in Model.Responses)
|
@foreach (var response in Model.Responses)
|
||||||
{
|
{
|
||||||
<div class="stepper-item">
|
<div class="stepper-item">
|
||||||
<div class="step-counter">
|
<div class="step-counter">
|
||||||
<span class="badge bg-primary p-3 shadow">@response.Questionnaire.Title</span>
|
<span class="badge bg-primary p-2 shadow">@response.Questionnaire.Title <i class="bi bi-arrow-right-circle-fill"></i></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="step-content">
|
<div class="step-content">
|
||||||
|
|
||||||
<div class="card p-4">
|
<div class="card p-4">
|
||||||
<div class="step-header">
|
<div class="step-header">
|
||||||
<h6>Survey: @response.Questionnaire.Title</h6>
|
<h6 class="text-primary font-weight-bold"><i class="bi bi-ui-checks"></i> @response.Questionnaire.Title</h6>
|
||||||
<p>Submitted on: @response.SubmissionDate</p>
|
<h6 class="text-success"><i class="bi bi-calendar2-week"></i> Submitted on: @response.SubmissionDate</h6>
|
||||||
|
<p class="text-info"><i class="bi bi-question-square"></i> Total questions: @response.Questionnaire.Questions.Count()</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Collapsible button -->
|
<!-- Collapsible button -->
|
||||||
|
|
@ -154,104 +166,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@* <div class="container-fluid mt-3">
|
|
||||||
<p>
|
|
||||||
<a asp-action="Index" class="btn btn-primary btn-sm">Back to list</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="card p-5 m-3 shadow">
|
|
||||||
<div class="bd-callout bd-callout-primary">
|
|
||||||
<h4 class="text-primary">User Responses</h4>
|
|
||||||
<text>@Model.UserName (@Model.UserEmail)</text>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
@foreach (var response in Model.Responses)
|
|
||||||
{
|
|
||||||
<div class="container card mt-4 p-3">
|
|
||||||
<div>
|
|
||||||
<h6>Survey: @response.Questionnaire.Title</h6>
|
|
||||||
<p>Submitted on: @response.SubmissionDate</p>
|
|
||||||
|
|
||||||
<!-- Collapsible button -->
|
|
||||||
<button class="btn btn-primary btn-sm" type="button" data-bs-toggle="collapse" data-bs-target="#collapseResponse-@response.Id" aria-expanded="false" aria-controls="collapseResponse-@response.Id">
|
|
||||||
View Responses
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<!-- Collapsible content -->
|
|
||||||
<div class="collapse mt-3" id="collapseResponse-@response.Id">
|
|
||||||
<table class="table table-responsive w-100 d-block d-md-table table-hover">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Question</th>
|
|
||||||
<th>Response</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@foreach (var detail in response.ResponseDetails)
|
|
||||||
{
|
|
||||||
<tr>
|
|
||||||
<td>@detail.Question.Text</td>
|
|
||||||
<td>
|
|
||||||
@if (detail.QuestionType == QuestionType.Text || detail.QuestionType == QuestionType.Slider || detail.QuestionType == QuestionType.Open_ended)
|
|
||||||
{
|
|
||||||
<ul class="list-group">
|
|
||||||
<li class="list-group-item d-flex justify-content-between align-items-center border-1">
|
|
||||||
Question type
|
|
||||||
<span class="badge text-bg-primary rounded-pill p-1s">@detail.QuestionType</span>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<ul class="list-group">
|
|
||||||
<li class="list-group-item d-flex justify-content-between align-items-center border-1">
|
|
||||||
|
|
||||||
Answer
|
|
||||||
<span class="badge text-bg-primary rounded-pill p-1">@detail.TextResponse</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
<ul class="list-group">
|
|
||||||
<li class="list-group-item d-flex justify-content-between align-items-center border-1">
|
|
||||||
Question type
|
|
||||||
<span class="badge text-bg-primary rounded-pill p-1">@detail.QuestionType</span>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<ul class="list-group">
|
|
||||||
|
|
||||||
@foreach (var answer in detail.ResponseAnswers)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
|
||||||
Answer
|
|
||||||
<span class="badge text-bg-primary rounded-pill p-1">@detail.Question.Answers.FirstOrDefault(a => a.Id == answer.AnswerId)?.Text</span>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div> *@
|
|
||||||
|
|
||||||
@section Scripts {
|
@section Scripts {
|
||||||
<!-- Include Bootstrap 5 JS for collapse functionality -->
|
<!-- Include Bootstrap 5 JS for collapse functionality -->
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,9 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="EPPlus" Version="7.1.3" />
|
||||||
<PackageReference Include="itext7" Version="8.0.4" />
|
<PackageReference Include="itext7" Version="8.0.4" />
|
||||||
|
<PackageReference Include="iTextSharp" Version="5.5.13.3" />
|
||||||
<PackageReference Include="MailJet.Api" Version="3.0.0" />
|
<PackageReference Include="MailJet.Api" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.QuickGrid.EntityFrameworkAdapter" Version="8.0.2" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.QuickGrid.EntityFrameworkAdapter" Version="8.0.2" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="8.0.3" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="8.0.3" />
|
||||||
|
|
@ -33,7 +35,6 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="NewFolder\" />
|
<Folder Include="NewFolder\" />
|
||||||
<Folder Include="wwwroot\Images\" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
BIN
Web/wwwroot/Images/logo.png
Normal file
BIN
Web/wwwroot/Images/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.7 KiB |
Loading…
Add table
Reference in a new issue