Real-time email event with charts completed
This commit is contained in:
parent
4fb4e979e6
commit
8994421caf
8 changed files with 1152 additions and 201 deletions
|
|
@ -13,6 +13,7 @@ namespace Model
|
|||
public string? Subject { get; set; }
|
||||
public string? Body { get; set; }
|
||||
public DateTime SentDate { get; set; }
|
||||
public DateTime ReceivedActivity { get; set; }
|
||||
public bool IsDelivered { get; set; }
|
||||
public bool IsOpened { get; set; }
|
||||
public bool IsClicked { get; set; }
|
||||
|
|
|
|||
|
|
@ -204,47 +204,54 @@ namespace Web.Areas.Admin.Controllers
|
|||
string eventType = e.Value<string>("event");
|
||||
Console.WriteLine($"Processing {eventType} for {email}");
|
||||
|
||||
var newsletterEmail = await _context.SentNewsletterEamils
|
||||
.FirstOrDefaultAsync(n => n.RecipientEmail == email);
|
||||
// Retrieve all matching newsletter email records
|
||||
var newsletterEmails = await _context.SentNewsletterEamils
|
||||
.Where(n => n.RecipientEmail == email)
|
||||
.ToListAsync();
|
||||
|
||||
if (newsletterEmail == null)
|
||||
if (newsletterEmails == null || !newsletterEmails.Any())
|
||||
{
|
||||
Console.WriteLine("No newsletter email record found for email: " + email);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (eventType)
|
||||
foreach (var newsletterEmail in newsletterEmails)
|
||||
{
|
||||
case "sent":
|
||||
newsletterEmail.IsDelivered = true;
|
||||
break;
|
||||
// Update the ReceivedActivity property to the current UTC time
|
||||
newsletterEmail.ReceivedActivity = DateTime.UtcNow.ToLocalTime();
|
||||
|
||||
case "open":
|
||||
newsletterEmail.IsOpened = true;
|
||||
break;
|
||||
case "click":
|
||||
newsletterEmail.IsClicked = true;
|
||||
break;
|
||||
case "bounce":
|
||||
newsletterEmail.IsBounced = true;
|
||||
break;
|
||||
case "spam":
|
||||
newsletterEmail.IsSpam = true;
|
||||
break;
|
||||
case "unsub":
|
||||
newsletterEmail.IsUnsubscribed = true;
|
||||
break;
|
||||
case "blocked":
|
||||
newsletterEmail.IsBlocked = true;
|
||||
break;
|
||||
default:
|
||||
Console.WriteLine($"Unhandled event type: {eventType}");
|
||||
break;
|
||||
switch (eventType)
|
||||
{
|
||||
case "sent":
|
||||
newsletterEmail.IsDelivered = true;
|
||||
break;
|
||||
case "open":
|
||||
newsletterEmail.IsOpened = true;
|
||||
break;
|
||||
case "click":
|
||||
newsletterEmail.IsClicked = true;
|
||||
break;
|
||||
case "bounce":
|
||||
newsletterEmail.IsBounced = true;
|
||||
break;
|
||||
case "spam":
|
||||
newsletterEmail.IsSpam = true;
|
||||
break;
|
||||
case "unsub":
|
||||
newsletterEmail.IsUnsubscribed = true;
|
||||
break;
|
||||
case "blocked":
|
||||
newsletterEmail.IsBlocked = true;
|
||||
break;
|
||||
default:
|
||||
Console.WriteLine($"Unhandled event type: {eventType}");
|
||||
break;
|
||||
}
|
||||
|
||||
_context.Entry(newsletterEmail).State = EntityState.Modified;
|
||||
}
|
||||
|
||||
_context.Entry(newsletterEmail).State = EntityState.Modified;
|
||||
}
|
||||
Console.WriteLine("Email got updated ");
|
||||
Console.WriteLine("Emails got updated ");
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
|
@ -256,155 +263,198 @@ namespace Web.Areas.Admin.Controllers
|
|||
}
|
||||
|
||||
return Ok();
|
||||
|
||||
//using (var reader = new StreamReader(Request.Body))
|
||||
//{
|
||||
// var requestBody = await reader.ReadToEndAsync();
|
||||
// Console.WriteLine("Received payload: " + requestBody);
|
||||
// Request.Body.Position = 0;
|
||||
|
||||
// try
|
||||
// {
|
||||
// var events = JArray.Parse(requestBody);
|
||||
// if (events == null)
|
||||
// {
|
||||
// return BadRequest("Parsed data is null");
|
||||
// }
|
||||
|
||||
// foreach (JObject e in events)
|
||||
// {
|
||||
// string email = e.Value<string>("email");
|
||||
// string eventType = e.Value<string>("event");
|
||||
// Console.WriteLine($"Processing {eventType} for {email}");
|
||||
|
||||
// var newsletterEmail = await _context.SentNewsletterEamils
|
||||
// .FirstOrDefaultAsync(n => n.RecipientEmail == email);
|
||||
|
||||
// if (newsletterEmail == null)
|
||||
// {
|
||||
// Console.WriteLine("No newsletter email record found for email: " + email);
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// // Update the ReceivedActivity property to the current UTC time
|
||||
// newsletterEmail.ReceivedActivity = DateTime.UtcNow.ToLocalTime();
|
||||
|
||||
// switch (eventType)
|
||||
// {
|
||||
// case "sent":
|
||||
// newsletterEmail.IsDelivered = true;
|
||||
// break;
|
||||
// case "open":
|
||||
// newsletterEmail.IsOpened = true;
|
||||
// break;
|
||||
// case "click":
|
||||
// newsletterEmail.IsClicked = true;
|
||||
// break;
|
||||
// case "bounce":
|
||||
// newsletterEmail.IsBounced = true;
|
||||
// break;
|
||||
// case "spam":
|
||||
// newsletterEmail.IsSpam = true;
|
||||
// break;
|
||||
// case "unsub":
|
||||
// newsletterEmail.IsUnsubscribed = true;
|
||||
// break;
|
||||
// case "blocked":
|
||||
// newsletterEmail.IsBlocked = true;
|
||||
// break;
|
||||
// default:
|
||||
// Console.WriteLine($"Unhandled event type: {eventType}");
|
||||
// break;
|
||||
// }
|
||||
|
||||
// _context.Entry(newsletterEmail).State = EntityState.Modified;
|
||||
// }
|
||||
// Console.WriteLine("Email got updated ");
|
||||
|
||||
// await _context.SaveChangesAsync();
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// Console.WriteLine("Exception parsing JSON: " + ex.Message);
|
||||
// return BadRequest("Error parsing JSON: " + ex.Message);
|
||||
// }
|
||||
//}
|
||||
|
||||
//return Ok();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//public async Task<IActionResult> MailjetWebhook()
|
||||
//{
|
||||
// using (var reader = new StreamReader(Request.Body))
|
||||
// {
|
||||
// var requestBody = await reader.ReadToEndAsync();
|
||||
// Console.WriteLine("Received payload: " + requestBody);
|
||||
// Request.Body.Position = 0;
|
||||
|
||||
// try
|
||||
// {
|
||||
// var events = JArray.Parse(requestBody);
|
||||
// if (events == null)
|
||||
// {
|
||||
// return BadRequest("Parsed data is null");
|
||||
// }
|
||||
|
||||
// foreach (JObject e in events)
|
||||
// {
|
||||
// string email = e.Value<string>("email");
|
||||
// string eventType = e.Value<string>("event");
|
||||
// Console.WriteLine($"Processing {eventType} for {email}");
|
||||
|
||||
// var newsletterEmail = await _context.SentNewsletterEamils
|
||||
// .FirstOrDefaultAsync(n => n.RecipientEmail == email);
|
||||
|
||||
// if (newsletterEmail == null)
|
||||
// {
|
||||
// Console.WriteLine("No newsletter email record found for email: " + email);
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// switch (eventType)
|
||||
// {
|
||||
// case "sent":
|
||||
// newsletterEmail.IsDelivered = true;
|
||||
// break;
|
||||
|
||||
// case "open":
|
||||
// newsletterEmail.IsOpened = true;
|
||||
// break;
|
||||
// case "click":
|
||||
// newsletterEmail.IsClicked = true;
|
||||
// break;
|
||||
// case "bounce":
|
||||
// newsletterEmail.IsBounced = true;
|
||||
// break;
|
||||
// case "spam":
|
||||
// newsletterEmail.IsSpam = true;
|
||||
// break;
|
||||
// case "unsub":
|
||||
// newsletterEmail.IsUnsubscribed = true;
|
||||
// break;
|
||||
// case "blocked":
|
||||
// newsletterEmail.IsBlocked = true;
|
||||
// break;
|
||||
// default:
|
||||
// Console.WriteLine($"Unhandled event type: {eventType}");
|
||||
// break;
|
||||
// }
|
||||
|
||||
// _context.Entry(newsletterEmail).State = EntityState.Modified;
|
||||
// }
|
||||
// Console.WriteLine("Email got updated ");
|
||||
|
||||
// await _context.SaveChangesAsync();
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// Console.WriteLine("Exception parsing JSON: " + ex.Message);
|
||||
// return BadRequest("Error parsing JSON: " + ex.Message);
|
||||
// }
|
||||
// }
|
||||
|
||||
// return Ok();
|
||||
//}
|
||||
|
||||
|
||||
|
||||
public async Task<IActionResult> EmailStats()
|
||||
{
|
||||
var emails = await _context.SentNewsletterEamils.ToListAsync();
|
||||
return View(emails);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async Task<IActionResult> GetEmailStatsData()
|
||||
{
|
||||
var model = await _context.SentNewsletterEamils.ToListAsync();
|
||||
return Json(model); // Returns the list of emails as JSON.
|
||||
}
|
||||
|
||||
public async Task<JsonResult> GetChartData()
|
||||
{
|
||||
var emails = await _context.SentNewsletterEamils.ToListAsync();
|
||||
//public async Task<JsonResult> GetChartData()
|
||||
|
||||
var data = new
|
||||
{
|
||||
Sent = emails.Count(e => e.IsSent),
|
||||
Delivered = emails.Count(e => e.IsDelivered),
|
||||
Opened = emails.Count(e => e.IsOpened),
|
||||
Clicked = emails.Count(e => e.IsClicked),
|
||||
Bounced = emails.Count(e => e.IsBounced),
|
||||
Spam = emails.Count(e => e.IsSpam),
|
||||
Blocked = emails.Count(e => e.IsBlocked),
|
||||
Unsubscribed = emails.Count(e => e.IsUnsubscribed)
|
||||
};
|
||||
// var emails = await _context.SentNewsletterEamils.ToListAsync();
|
||||
|
||||
return Json(data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//[HttpPost]
|
||||
//public async Task<IActionResult> Create(SendNewsLetterViewModel viewModel)
|
||||
//{
|
||||
// if(ModelState.IsValid)
|
||||
// var data = new
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// // Retrieve all subscribed users
|
||||
// var subscribedUsers = await _context.Subscriptions.Where(s => s.IsSubscribed).ToListAsync();
|
||||
|
||||
|
||||
// string confirmationPath = _configuration["Email:unsubscribePath"];
|
||||
// // Send the newsletter email to each subscribed user
|
||||
// foreach (var user in subscribedUsers)
|
||||
// {
|
||||
// string confirmationUrl = $"{Request.Scheme}://{Request.Host}/{confirmationPath}?email={user.Email}";
|
||||
|
||||
// string emailBody = $@"<head>
|
||||
// <meta charset=""UTF-8"">
|
||||
// <meta name=""viewport"" content=""width=device-width, initial-scale=1.0"">
|
||||
// <title>Email Confirmation</title>
|
||||
// <style>
|
||||
// body {{
|
||||
// font-family: Arial, sans-serif;
|
||||
// line-height: 1.6;
|
||||
// margin: 0;
|
||||
// padding: 0;
|
||||
// background-color: #f9f9f9;
|
||||
// }}
|
||||
// .container {{
|
||||
// max-width: 800px;
|
||||
// margin: 0 auto;
|
||||
// padding: 20px;
|
||||
// border: 0.5px solid #ccc;
|
||||
// border-radius: 5px;
|
||||
// background-color: #f9f9f9;
|
||||
// }}
|
||||
// h4, h5, h6 {{
|
||||
// margin: 0;
|
||||
// }}
|
||||
// hr {{
|
||||
// border: none;
|
||||
// border-top: 1px solid #ccc;
|
||||
// margin: 10px 0;
|
||||
// }}
|
||||
// a.button {{
|
||||
// display: inline-block;
|
||||
// padding: 5px 10px;
|
||||
// background-color: #6c757d;
|
||||
// color: #fff;
|
||||
// text-decoration: none;
|
||||
// border-radius: 4px;
|
||||
// }}
|
||||
// a.button:hover {{
|
||||
// background-color: #5a6268;
|
||||
// }}
|
||||
// a {{
|
||||
// color: #007bff;
|
||||
// text-decoration: none;
|
||||
// }}
|
||||
// a:hover {{
|
||||
// text-decoration: underline;
|
||||
// }}
|
||||
// </style>
|
||||
// </head>
|
||||
// <body>
|
||||
// <div class=""container"">
|
||||
// <h4>Hey {user.Name},</h4>
|
||||
// <p>{viewModel.Body}</p><br>
|
||||
|
||||
// <h5>Søren Eggert Lundsteen Olsen</h5>
|
||||
// <h5><a href=""https://www.seosoft.dk/"" target=""_blank"">SeoSoft ApS</a></h5>
|
||||
// <hr>
|
||||
// <h6>Hovedgaden 3<br>Jordrup<br>Kolding 6064<br>Denmark</h6>
|
||||
// <div style=""text-align: center;"">
|
||||
// <a href=""{confirmationUrl}"" class=""button"">Unsubscribe</a>
|
||||
// </div>
|
||||
// </div>
|
||||
// </body>";
|
||||
// var email = new EmailToSend(user.Email, viewModel.Subject, emailBody);
|
||||
// var isSent = await _emailServices.SendConfirmationEmailAsync(email);
|
||||
|
||||
// // Handle failure to send email if needed
|
||||
|
||||
// }
|
||||
|
||||
// TempData["success"] = "Nesletter sent successfully.";
|
||||
// return RedirectToAction(nameof(Index));
|
||||
|
||||
|
||||
|
||||
// }
|
||||
// catch (Exception)
|
||||
// {
|
||||
// // Log or handle the exception as needed
|
||||
// TempData["success"] = "something went wrong.";
|
||||
// return RedirectToAction(nameof(Index));
|
||||
// }
|
||||
// }
|
||||
// return View(viewModel);
|
||||
|
||||
// Sent = emails.Count(e => e.IsSent),
|
||||
// Delivered = emails.Count(e => e.IsDelivered),
|
||||
// Opened = emails.Count(e => e.IsOpened),
|
||||
// Clicked = emails.Count(e => e.IsClicked),
|
||||
// Bounced = emails.Count(e => e.IsBounced),
|
||||
// Spam = emails.Count(e => e.IsSpam),
|
||||
// Blocked = emails.Count(e => e.IsBlocked),
|
||||
// Unsubscribed = emails.Count(e => e.IsUnsubscribed)
|
||||
// };
|
||||
|
||||
// return Json(data);
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Delete(int id)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -124,13 +124,13 @@
|
|||
<p>
|
||||
<a asp-action="Index" class="btn btn-primary btn-sm">Back to list</a>
|
||||
</p>
|
||||
<h1>EmailStats</h1>
|
||||
<h3 class="text-primary p-3">Real-Time Email Event</h3>
|
||||
|
||||
<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 shadow-lg rounded-2">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Recipient</th>
|
||||
<th>Sent Date</th>
|
||||
<th>Activity Date</th>
|
||||
<th>Subject</th>
|
||||
<th>Sent</th>
|
||||
<th>Delivered</th>
|
||||
|
|
@ -147,7 +147,7 @@
|
|||
{
|
||||
<tr>
|
||||
<td>@item.RecipientEmail</td>
|
||||
<td>@item.SentDate</td>
|
||||
<td>@item.ReceivedActivity</td>
|
||||
<td>@item.Subject</td>
|
||||
<td>
|
||||
@if (item.IsSent)
|
||||
|
|
@ -236,49 +236,80 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="card shadow-lg rounded-2 p-3">
|
||||
<div class="row p-3">
|
||||
|
||||
<div class="col-5 m-2">
|
||||
<div id="chart_div_percentage" style="width: 500px; height: 300px;"></div>
|
||||
</div>
|
||||
<div class="col-5 m-2">
|
||||
<div id="chart_div_labels" style="width: 500px; height: 300px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Email Statistics</h2>
|
||||
<div id="piechart" style="width: 900px; height: 500px;"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
google.charts.load('current', { 'packages': ['corechart'] });
|
||||
google.charts.setOnLoadCallback(drawChart);
|
||||
google.charts.setOnLoadCallback(drawCharts);
|
||||
|
||||
function drawChart() {
|
||||
fetch('@Url.Action("GetChartData", "Newsletters")')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
var dataTable = new google.visualization.DataTable();
|
||||
dataTable.addColumn('string', 'Type');
|
||||
dataTable.addColumn('number', 'Count');
|
||||
dataTable.addRows([
|
||||
['Sent', data.Sent],
|
||||
['Delivered', data.Delivered],
|
||||
['Opened', data.Opened],
|
||||
['Clicked', data.Clicked],
|
||||
['Bounced', data.Bounced],
|
||||
['Spam', data.Spam],
|
||||
['Blocked', data.Blocked],
|
||||
['Unsubscribed', data.Unsubscribed]
|
||||
]);
|
||||
function drawCharts() {
|
||||
var data = new google.visualization.DataTable();
|
||||
data.addColumn('string', 'Status');
|
||||
data.addColumn('number', 'Count');
|
||||
data.addRows([
|
||||
['Sent', @Model.Count(e => e.IsSent)],
|
||||
['Delivered', @Model.Count(e => e.IsDelivered)],
|
||||
['Opened', @Model.Count(e => e.IsOpened)],
|
||||
['Clicked', @Model.Count(e => e.IsClicked)],
|
||||
['Bounced', @Model.Count(e => e.IsBounced)],
|
||||
['Spam', @Model.Count(e => e.IsSpam)],
|
||||
['Blocked', @Model.Count(e => e.IsBlocked)],
|
||||
['Unsubscribed', @Model.Count(e => e.IsUnsubscribed)]
|
||||
]);
|
||||
|
||||
var options = {
|
||||
title: 'Email Interaction Overview',
|
||||
width: 900,
|
||||
height: 500
|
||||
};
|
||||
// Chart options for showing percentages
|
||||
var optionsPercentage = {
|
||||
title: 'Email Interactions (Percentage)',
|
||||
width: 500,
|
||||
height: 300,
|
||||
is3D: true,
|
||||
pieSliceText: 'percentage',
|
||||
titleTextStyle: { color: '#3b76cb', fontSize: 12, bold: true }
|
||||
};
|
||||
|
||||
var chart = new google.visualization.PieChart(document.getElementById('piechart'));
|
||||
chart.draw(dataTable, options);
|
||||
})
|
||||
.catch(error => console.error('Failed to fetch email stats:', error));
|
||||
// Chart options for showing labels
|
||||
var optionsLabels = {
|
||||
title: 'Email Interactions (Labels)',
|
||||
width: 500,
|
||||
height: 300,
|
||||
is3D: true,
|
||||
pieSliceText: 'label',
|
||||
titleTextStyle: { color: '#3b76cb', fontSize: 12, bold: true }
|
||||
};
|
||||
|
||||
// Draw the first chart
|
||||
var chartPercentage = new google.visualization.PieChart(document.getElementById('chart_div_percentage'));
|
||||
chartPercentage.draw(data, optionsPercentage);
|
||||
|
||||
// Draw the second chart
|
||||
var chartLabels = new google.visualization.PieChart(document.getElementById('chart_div_labels'));
|
||||
chartLabels.draw(data, optionsLabels);
|
||||
}
|
||||
</script>
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -117,11 +117,11 @@
|
|||
background-color: #cb4a49;
|
||||
}
|
||||
</style>
|
||||
<div class="container mt-5">
|
||||
<div class="container mt-5 mb-3">
|
||||
|
||||
<partial name="_Notification" />
|
||||
|
||||
<div class="card bg-default mb-3 ">
|
||||
<div class="card bg-default mb-3 rounded-2 shadow-lg">
|
||||
<div class="card-header">Subscribers</div>
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Subscribers list</h4>
|
||||
|
|
@ -181,19 +181,19 @@
|
|||
|
||||
|
||||
|
||||
<div class="container">
|
||||
<div class="container mb-5 mt-4">
|
||||
|
||||
<h4>
|
||||
<i class="bi bi-broadcast p-1 border-1 shadow-sm"></i> Real-Time Email Event Tracking
|
||||
<i class="bi bi-broadcast"></i> Real-Time Email Event Tracking
|
||||
</h4>
|
||||
<p>
|
||||
<a asp-action="EmailStats" class="btn btn-primary btn-sm">View email tracking with chart</a>
|
||||
</p>
|
||||
<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 rounded-2 shadow-lg">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Recipient</th>
|
||||
<th>Sent Date</th>
|
||||
<th>Activity Date</th>
|
||||
<th>Subject</th>
|
||||
<th>Sent</th>
|
||||
<th>Delivered</th>
|
||||
|
|
@ -232,7 +232,7 @@
|
|||
const row = `
|
||||
<tr>
|
||||
<td>${item.recipientEmail}</td>
|
||||
<td>${item.sentDate}</td>
|
||||
<td>${item.receivedActivity}</td>
|
||||
<td>${item.subject}</td>
|
||||
<td>${item.isSent ? '<span class="badge-Sent">Sent</span>' : '<span class="badge badge-secondary">Pending</span>'}</td>
|
||||
<td>${item.isDelivered ? '<span class="badge-Deliverd">Delivered</span>' : '<span class="badge badge-secondary">Pending</span>'}</td>
|
||||
|
|
|
|||
826
Web/Migrations/20240509135537_ReceviedDateTimeAddedtoSentNewsLetterModel.Designer.cs
generated
Normal file
826
Web/Migrations/20240509135537_ReceviedDateTimeAddedtoSentNewsLetterModel.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,826 @@
|
|||
// <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("20240509135537_ReceviedDateTimeAddedtoSentNewsLetterModel")]
|
||||
partial class ReceviedDateTimeAddedtoSentNewsLetterModel
|
||||
{
|
||||
/// <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<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>("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<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,30 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Web.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ReceviedDateTimeAddedtoSentNewsLetterModel : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "ReceivedActivity",
|
||||
table: "SentNewsletterEamils",
|
||||
type: "datetime2",
|
||||
nullable: false,
|
||||
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ReceivedActivity",
|
||||
table: "SentNewsletterEamils");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -575,6 +575,9 @@ namespace Web.Migrations
|
|||
b.Property<bool>("IsUnsubscribed")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<DateTime>("ReceivedActivity")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<string>("RecipientEmail")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
|
|
|
|||
10
Web/ViewModel/NewsLetterVM/EmailStatsViewModel.cs
Normal file
10
Web/ViewModel/NewsLetterVM/EmailStatsViewModel.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using Model;
|
||||
|
||||
namespace Web.ViewModel.NewsLetterVM
|
||||
{
|
||||
public class EmailStatsViewModel
|
||||
{
|
||||
public IEnumerable<SentNewsletterEamil>? Emails { get; set; }
|
||||
public IEnumerable<dynamic>? DailyActivities { get; set; }
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue