add database backup

This commit is contained in:
Qais Yousuf 2025-07-30 14:41:43 +02:00
parent 196c6887a8
commit d06e0c5ba9
21 changed files with 250 additions and 103 deletions

View file

@ -4,6 +4,7 @@
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

BIN
DbBackup/asurvey.bak Normal file

Binary file not shown.

View file

@ -7,6 +7,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Model namespace Model
{ {
public class Answer public class Answer

View file

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -12,6 +13,8 @@ namespace Model
public int Id { get; set; } public int Id { get; set; }
[Required] [Required]
public string? Title { get; set; } public string? Title { get; set; }
[Required] [Required]
public string? Description { get; set; } public string? Description { get; set; }

View file

@ -14,25 +14,43 @@ EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0A90A5D7-CBD6-4956-B8EC-4E368736113F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0A90A5D7-CBD6-4956-B8EC-4E368736113F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0A90A5D7-CBD6-4956-B8EC-4E368736113F}.Debug|Any CPU.Build.0 = Debug|Any CPU {0A90A5D7-CBD6-4956-B8EC-4E368736113F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0A90A5D7-CBD6-4956-B8EC-4E368736113F}.Debug|x64.ActiveCfg = Debug|Any CPU
{0A90A5D7-CBD6-4956-B8EC-4E368736113F}.Debug|x64.Build.0 = Debug|Any CPU
{0A90A5D7-CBD6-4956-B8EC-4E368736113F}.Release|Any CPU.ActiveCfg = Release|Any CPU {0A90A5D7-CBD6-4956-B8EC-4E368736113F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0A90A5D7-CBD6-4956-B8EC-4E368736113F}.Release|Any CPU.Build.0 = Release|Any CPU {0A90A5D7-CBD6-4956-B8EC-4E368736113F}.Release|Any CPU.Build.0 = Release|Any CPU
{0A90A5D7-CBD6-4956-B8EC-4E368736113F}.Release|x64.ActiveCfg = Release|Any CPU
{0A90A5D7-CBD6-4956-B8EC-4E368736113F}.Release|x64.Build.0 = Release|Any CPU
{6EE5F607-221D-4DFF-B027-06D190BCD536}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6EE5F607-221D-4DFF-B027-06D190BCD536}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6EE5F607-221D-4DFF-B027-06D190BCD536}.Debug|Any CPU.Build.0 = Debug|Any CPU {6EE5F607-221D-4DFF-B027-06D190BCD536}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6EE5F607-221D-4DFF-B027-06D190BCD536}.Debug|x64.ActiveCfg = Debug|Any CPU
{6EE5F607-221D-4DFF-B027-06D190BCD536}.Debug|x64.Build.0 = Debug|Any CPU
{6EE5F607-221D-4DFF-B027-06D190BCD536}.Release|Any CPU.ActiveCfg = Release|Any CPU {6EE5F607-221D-4DFF-B027-06D190BCD536}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6EE5F607-221D-4DFF-B027-06D190BCD536}.Release|Any CPU.Build.0 = Release|Any CPU {6EE5F607-221D-4DFF-B027-06D190BCD536}.Release|Any CPU.Build.0 = Release|Any CPU
{6EE5F607-221D-4DFF-B027-06D190BCD536}.Release|x64.ActiveCfg = Release|Any CPU
{6EE5F607-221D-4DFF-B027-06D190BCD536}.Release|x64.Build.0 = Release|Any CPU
{D03B56FD-361D-49C5-B0D3-B48DDE90A217}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D03B56FD-361D-49C5-B0D3-B48DDE90A217}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D03B56FD-361D-49C5-B0D3-B48DDE90A217}.Debug|Any CPU.Build.0 = Debug|Any CPU {D03B56FD-361D-49C5-B0D3-B48DDE90A217}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D03B56FD-361D-49C5-B0D3-B48DDE90A217}.Debug|x64.ActiveCfg = Debug|x64
{D03B56FD-361D-49C5-B0D3-B48DDE90A217}.Debug|x64.Build.0 = Debug|x64
{D03B56FD-361D-49C5-B0D3-B48DDE90A217}.Release|Any CPU.ActiveCfg = Release|Any CPU {D03B56FD-361D-49C5-B0D3-B48DDE90A217}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D03B56FD-361D-49C5-B0D3-B48DDE90A217}.Release|Any CPU.Build.0 = Release|Any CPU {D03B56FD-361D-49C5-B0D3-B48DDE90A217}.Release|Any CPU.Build.0 = Release|Any CPU
{D03B56FD-361D-49C5-B0D3-B48DDE90A217}.Release|x64.ActiveCfg = Release|x64
{D03B56FD-361D-49C5-B0D3-B48DDE90A217}.Release|x64.Build.0 = Release|x64
{61EE2AF3-6434-4DE4-BD66-222DC6E9AC4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {61EE2AF3-6434-4DE4-BD66-222DC6E9AC4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{61EE2AF3-6434-4DE4-BD66-222DC6E9AC4B}.Debug|Any CPU.Build.0 = Debug|Any CPU {61EE2AF3-6434-4DE4-BD66-222DC6E9AC4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{61EE2AF3-6434-4DE4-BD66-222DC6E9AC4B}.Debug|x64.ActiveCfg = Debug|Any CPU
{61EE2AF3-6434-4DE4-BD66-222DC6E9AC4B}.Debug|x64.Build.0 = Debug|Any CPU
{61EE2AF3-6434-4DE4-BD66-222DC6E9AC4B}.Release|Any CPU.ActiveCfg = Release|Any CPU {61EE2AF3-6434-4DE4-BD66-222DC6E9AC4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{61EE2AF3-6434-4DE4-BD66-222DC6E9AC4B}.Release|Any CPU.Build.0 = Release|Any CPU {61EE2AF3-6434-4DE4-BD66-222DC6E9AC4B}.Release|Any CPU.Build.0 = Release|Any CPU
{61EE2AF3-6434-4DE4-BD66-222DC6E9AC4B}.Release|x64.ActiveCfg = Release|Any CPU
{61EE2AF3-6434-4DE4-BD66-222DC6E9AC4B}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View file

@ -0,0 +1,5 @@
{
"version": 1,
"isRoot": true,
"tools": {}
}

View file

@ -403,7 +403,7 @@ namespace Web.Areas.Admin.Controllers
// If deletion is successful, you can redirect to a success page or return a success message // If deletion is successful, you can redirect to a success page or return a success message
return Json(new { success = true, message = "Item deleted successfully" }); return Json(new { success = true, message = "Item deleted successfully" });
} }
catch (Exception ex) catch (Exception)
{ {
// Log the exception or handle it appropriately // Log the exception or handle it appropriately
return StatusCode(500, "An error occurred while processing your request."); return StatusCode(500, "An error occurred while processing your request.");

View file

@ -6,7 +6,7 @@
<div class="container-fluid p-4"> <div class="container p-4">
<div> <div>
<a class="btn btn-primary" asp-action="Index">Back to List</a> <a class="btn btn-primary" asp-action="Index">Back to List</a>
@ -37,7 +37,7 @@
</div> </div>
</div> </div>
<table class="table table-responsive w-100 d-block d-md-table table-bordered table-hover "> <table class="table table-responsive table-bordered table-hover ">
<thead> <thead>
<tr > <tr >
<th scope="col" class="text-warning h5">ID</th> <th scope="col" class="text-warning h5">ID</th>

View file

@ -5,30 +5,30 @@
} }
<div class="container-fluid d-flex justify-content-center"> <div class="container-fluid mt-3">
<partial name="_Notification" /> <partial name="_Notification" />
<div class="card bg-default mb-3 p-4 shadow "> <div class="card bg-default shadow ">
<div class="card-header">Questionnaire</div> <div class="card-header">Questionnaire</div>
<div class="card-body"> <div class="card-body">
<h4 class="card-title">Questionnaire list</h4> <h4 class="card-title">Questionnaire list</h4>
<p> <p>
<a asp-action="Create" class="btn btn-primary"><span><i class="bi bi-plus-square-fill"></i></span> Create New</a> <a asp-action="Create" class="btn btn-primary"><span><i class="bi bi-plus-square-fill"></i></span> Create New</a>
</p> </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-hover">
<thead class="w-auto"> <thead >
<tr> <tr>
<th scope="col">Id</th> <th>Id</th>
<th scope="col">Title</th> <th>Title</th>
<th scope="col">Total Questions</th> <th>Total Questions</th>
<th scope="col"> <span class="badge badge-primary">Questions</span> | <span class="badge badge-info">Type</span> | <span class="badge badge-success">Answers </span></th> <th> <span class="badge badge-primary">Questions</span> | <span class="badge badge-info">Type</span> | <span class="badge badge-success">Answers </span></th>
<th scope="col">Action</th> <th>Action</th>
</tr> </tr>
</thead> </thead>
<tbody class="w-auto"> <tbody class="w-100">
@foreach (var item in Model) @foreach (var item in Model)
{ {
<tr class="table-secondary"> <tr class="table-secondary">
@ -41,9 +41,7 @@
<td> <td>
@* <button type="button" class="btn btn-primary btn-sm">
</button> *@
<span class="badge shadow rounded text-bg-primary p-2"> <span class="badge shadow rounded text-bg-primary p-2">
Questions <span class="badge text-bg-secondary shadow rounded p-1">@item.Questions?.Count()</span> Questions <span class="badge text-bg-secondary shadow rounded p-1">@item.Questions?.Count()</span>
</span> </span>
@ -67,11 +65,11 @@
</td> </td>
<td class="d-flex justify-content-end"> <td>
<a asp-action="Delete" asp-route-id="@item.Id" class="btn btn-danger btn-sm"><i class="bi bi-trash"></i> Delete</a> | <a asp-action="Delete" asp-route-id="@item.Id" class="btn btn-danger btn-sm m-1"><i class="bi bi-trash"></i> Delete</a>
<a asp-action="Edit" asp-route-id="@item.Id" class="btn btn-primary btn-sm"><i class="bi bi-pencil-square"></i> Edit</a>| <a asp-action="Edit" asp-route-id="@item.Id" class="btn btn-primary btn-sm m-1"><i class="bi bi-pencil-square"></i> Edit</a>
<a asp-action="Details" asp-route-id="@item.Id" class="btn btn-info btn-sm"><i class="bi bi-pencil-square"></i> Details</a> | <a asp-action="Details" asp-route-id="@item.Id" class="btn btn-info btn-sm m-1"><i class="bi bi-pencil-square"></i> Details</a>
<a asp-action="SendQuestionnaire" asp-route-id="@item.Id" class="btn btn-success btn-sm"><i class="bi bi-pencil-square"></i> Send</a> <a asp-action="SendQuestionnaire" asp-route-id="@item.Id" class="btn btn-success btn-sm m-1"><i class="bi bi-pencil-square"></i> Send</a>
</td> </td>
</tr> </tr>
@ -84,31 +82,3 @@
</div> </div>
</div> </div>
@section Scripts{
<script>
$(document).ready(function () {
$('.read-more-title-btn').click(function () {
var $titleText = $(this).closest('.title-container').find('.title-text');
var $moreTitle = $titleText.find('.more-title');
var $toggleMore = $titleText.find('.toggle-more');
if ($moreTitle.is(':visible')) {
$moreTitle.slideUp();
$toggleMore.fadeIn();
} else {
$moreTitle.slideDown();
$toggleMore.fadeOut();
}
$(this).text(function (i, text) {
return text === "Read More" ? "Read Less" : "Read More";
});
});
});
</script>
}

View file

@ -77,27 +77,25 @@
<div class="collapse navbar-collapse" id="navbarSupportedContent"> <div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="nav navbar-nav ml-auto"> <ul class="nav navbar-nav ml-auto">
<span class="dropdown mr-2"> <span class="dropdown m-2">
<button class="btn btn-info btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false"> <button class="bg-transparent text-white btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <span class="badge badge-danger" id="notificationCount">0</span>
Notifications <span class="badge badge-danger" id="notificationCount">0</span>
</a>
</button> </button>
<ul class="dropdown-menu"> <ul class="dropdown-menu" id="notificationDropdown">
<li> <li>
<a class="dropdown-item" href="#"> <a class="dropdown-item" href="#">
<h6 class="dropdown-header">New Notifications</h6>
<div id="notifications"> <div id="notifications">
</div> </div>
</a> </a>
</li> </li>
</ul> </ul>
</span> </span>
<span class="dropdown mr-2">
<span class="dropdown m-2">
<button class="btn btn-primary btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false"> <button class="btn btn-primary btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
Account Account
</button> </button>
@ -106,7 +104,7 @@
<li><a class="dropdown-item" asp-controller="Users" asp-action="index">Users</a></li> <li><a class="dropdown-item" asp-controller="Users" asp-action="index">Users</a></li>
</ul> </ul>
</span> </span>
<li class="nav-item"> <li class="nav-item m-2">
<form asp-area="Admin" asp-controller="Admin" asp-action="Logout" method="post"> <form asp-area="Admin" asp-controller="Admin" asp-action="Logout" method="post">
<button type="submit" class="btn btn-danger btn-sm"><span class="bi bi-box-arrow-left"></span> Logout</button> <button type="submit" class="btn btn-danger btn-sm"><span class="bi bi-box-arrow-left"></span> Logout</button>
</form> </form>
@ -138,17 +136,77 @@
.withUrl("/notificationHub") .withUrl("/notificationHub")
.build(); .build();
// Function to load notifications from local storage
function loadNotifications() {
const notificationsList = document.getElementById("notifications");
const notificationCount = document.getElementById("notificationCount");
// Retrieve notifications from local storage
const storedNotifications = JSON.parse(localStorage.getItem("notifications")) || [];
// Update the notification count
notificationCount.textContent = storedNotifications.length;
// Add each stored notification to the list
storedNotifications.forEach(notification => {
const div = document.createElement("div");
div.className = "list-group-item";
const link = document.createElement("a");
link.href = `/admin/UserResponseStatus/UserResponsesStatus?UserEmail=${notification.email}`;
link.textContent = notification.text;
link.addEventListener("click", () => {
removeNotification(div, notification.id);
});
div.appendChild(link);
notificationsList.appendChild(div);
});
}
// Function to add a notification to the list // Function to add a notification to the list
function addNotification(userName, email) { function addNotification(userName, email) {
const notificationsList = document.getElementById("notifications"); const notificationsList = document.getElementById("notifications");
const li = document.createElement("li"); const notificationCount = document.getElementById("notificationCount");
li.className = "list-group-item";
li.textContent = `New submission from ${userName}`; // Create a unique ID for the notification
notificationsList.appendChild(li); const notificationId = Date.now();
// Create notification item
const div = document.createElement("div");
div.className = "list-group-item";
const link = document.createElement("a");
link.href = `/admin/UserResponseStatus/UserResponsesStatus?UserEmail=${email}`;
link.textContent = ` ${userName}`;
link.addEventListener("click", () => {
removeNotification(div, notificationId);
});
div.appendChild(link);
notificationsList.appendChild(div);
// Update the notification count
notificationCount.textContent = parseInt(notificationCount.textContent) + 1;
// Store the notification in local storage
const storedNotifications = JSON.parse(localStorage.getItem("notifications")) || [];
storedNotifications.push({ id: notificationId, text: link.textContent, email: email });
localStorage.setItem("notifications", JSON.stringify(storedNotifications));
}
// Function to remove a notification
function removeNotification(div, id) {
div.remove();
// Update the notification count // Update the notification count
const notificationCount = document.getElementById("notificationCount"); const notificationCount = document.getElementById("notificationCount");
notificationCount.textContent = parseInt(notificationCount.textContent) + 1; notificationCount.textContent = parseInt(notificationCount.textContent) - 1;
// Remove the notification from local storage
let storedNotifications = JSON.parse(localStorage.getItem("notifications")) || [];
storedNotifications = storedNotifications.filter(notification => notification.id !== id);
localStorage.setItem("notifications", JSON.stringify(storedNotifications));
} }
// Receive notification from the server // Receive notification from the server
@ -157,11 +215,101 @@
}); });
// Start the connection // Start the connection
connection.start().catch(function (err) { connection.start().then(loadNotifications).catch(function (err) {
return console.error(err.toString()); return console.error(err.toString());
}); });
</script> </script>
@* <script type="text/javascript">
// Establish a connection to the SignalR hub
const connection = new signalR.HubConnectionBuilder()
.withUrl("/notificationHub")
.build();
// Function to load notifications from local storage
function loadNotifications() {
const notificationsList = document.getElementById("notifications");
const notificationCount = document.getElementById("notificationCount");
// Retrieve notifications from local storage
const storedNotifications = JSON.parse(localStorage.getItem("notifications")) || [];
// Update the notification count
notificationCount.textContent = storedNotifications.length;
// Add each stored notification to the list
storedNotifications.forEach(notification => {
const div = document.createElement("div");
div.className = "list-group-item";
div.textContent = notification.text;
// Add click event to remove notification
div.addEventListener("click", () => {
removeNotification(div, notification.id);
});
notificationsList.appendChild(div);
});
}
// Function to add a notification to the list
function addNotification(userName, email) {
const notificationsList = document.getElementById("notifications");
const notificationCount = document.getElementById("notificationCount");
// Create a unique ID for the notification
const notificationId = Date.now();
// Create notification item
const div = document.createElement("div");
div.className = "list-group-item";
div.textContent = `New submission from ${userName}`;
// Add click event to remove notification
div.addEventListener("click", () => {
removeNotification(div, notificationId);
});
// Append the new notification
notificationsList.appendChild(div);
// Update the notification count
notificationCount.textContent = parseInt(notificationCount.textContent) + 1;
// Store the notification in local storage
const storedNotifications = JSON.parse(localStorage.getItem("notifications")) || [];
storedNotifications.push({ id: notificationId, text: div.textContent });
localStorage.setItem("notifications", JSON.stringify(storedNotifications));
}
// Function to remove a notification
function removeNotification(div, id) {
div.remove();
// Update the notification count
const notificationCount = document.getElementById("notificationCount");
notificationCount.textContent = parseInt(notificationCount.textContent) - 1;
// Remove the notification from local storage
let storedNotifications = JSON.parse(localStorage.getItem("notifications")) || [];
storedNotifications = storedNotifications.filter(notification => notification.id !== id);
localStorage.setItem("notifications", JSON.stringify(storedNotifications));
}
// Receive notification from the server
connection.on("ReceiveNotification", function (userName, email) {
addNotification(userName, email);
});
// Start the connection
connection.start().then(loadNotifications).catch(function (err) {
return console.error(err.toString());
});
</script> *@
@await RenderSectionAsync("Scripts", required: false) @await RenderSectionAsync("Scripts", required: false)

View file

@ -3,7 +3,7 @@
@{ @{
ViewData["Title"] = "Survey Analysis"; ViewData["Title"] = "Survey Analysis";
} }
<div class="container mt-5"> <div class="container-fluid mt-5">
<partial name="_Notification" /> <partial name="_Notification" />

View file

@ -5,7 +5,7 @@
} }
<div class="container-fluid mt-4 mb-5"> <div class="container-fluid mt-4 mb-5">
<div class="col-10 offset-1"> <div class="">
<div class="card p-4 shadow-lg rounded-2"> <div class="card p-4 shadow-lg rounded-2">

View file

@ -92,7 +92,7 @@
</div> </div>
<div class="col-md-9"> <div class="col-md-9">
<div id="user_survey_summary_chart_div" style=" width: 100%; height: 200px;"></div> <div id="user_survey_summary_chart_div" style=" width: auto; height: 200px;"></div>
</div> </div>
</div> </div>

View file

@ -120,8 +120,8 @@
background-color: #cb4a49; background-color: #cb4a49;
} }
</style> </style>
<div class="container-fluid mt-4 mb-5"> <div class="container mt-4 mb-5">
<div class="col-10 offset-1 "> <div>
<div class="card p-4 shadow-lg rounded-2"> <div class="card p-4 shadow-lg rounded-2">
<p> <p>
@ -130,7 +130,7 @@
<h3 class="text-primary">Real-Time Email tracking</h3> <h3 class="text-primary">Real-Time Email tracking</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">
<thead> <thead>
<tr> <tr>
<th><input type="checkbox" id="selectAll" /></th> <th><input type="checkbox" id="selectAll" /></th>
@ -256,16 +256,16 @@
<div class="container mb-4"> <div class="container mb-4">
<div class="card shadow-lg rounded-2 p-3"> <div class="card shadow-lg rounded-2 p-3">
<div class="row p-3"> <div class="row">
<div class="col-5 m-2"> <div class="col-6">
<div id="chart_div_percentage" style="width: 500px; height: 300px;"></div> <div id="chart_div_percentage" style="width: 500px; height: 300px;"></div>
</div> </div>
<div class="col-5 m-2"> <div class="col-6 ">
<div id="chart_div_labels" style="width: 500px; height: 300px;"></div> <div id="chart_div_labels" style="width: 500px; height: 300px;"></div>
</div> </div>
<div class="col-8 m-2"> <div class="col-10 offset-1 m-2">
<div id="geo_chart_div" style="width: 500px; height: 300px;"></div> <div id="geo_chart_div" style="width: 700px; height: 300px;"></div>
</div> </div>
</div> </div>

View file

@ -195,8 +195,8 @@
</div> </div>
</div> </div>
<div class="container-fluid mb-5 mt-4"> <div class="container mb-5 mt-4">
<div class="col-md-10 col-lg-10 col-sm-12 offset-1">
<div class="card rounded-2 shadow-lg p-3 mt-3"> <div class="card rounded-2 shadow-lg p-3 mt-3">
<h4 class="text-primary"> <h4 class="text-primary">
<i class="bi bi-broadcast"></i> Real-Time Email Tracking <i class="bi bi-broadcast"></i> Real-Time Email Tracking
@ -204,7 +204,7 @@
<p> <p>
<a asp-action="EmailStats" class="btn btn-primary btn-sm">View email tracking with chart</a> <a asp-action="EmailStats" class="btn btn-primary btn-sm">View email tracking with chart</a>
</p> </p>
<table class="table table-responsive d-block d-md-table table-bordered table-hover mt-3"> <table class=" table table-responsive">
<thead> <thead>
<tr> <tr>
<th>Recipient</th> <th>Recipient</th>
@ -222,12 +222,12 @@
<th>Unsubscribed</th> <th>Unsubscribed</th>
</tr> </tr>
</thead> </thead>
<tbody id="emailStatsTableBody"> <tbody class="" id="emailStatsTableBody">
<!-- Rows will be dynamically inserted here --> <!-- Rows will be dynamically inserted here -->
</tbody> </tbody>
</table> </table>
</div> </div>
</div>
</div> </div>
@section Scripts{ @section Scripts{

View file

@ -153,7 +153,7 @@ namespace Web.Controllers
TempData["success"] = "Subscription successful. Please confirm your email."; TempData["success"] = "Subscription successful. Please confirm your email.";
return RedirectToAction("", "home"); return RedirectToAction("", "home");
} }
catch (Exception ex) catch (Exception)
{ {
TempData["error"] = "Failed to subscribe."; TempData["error"] = "Failed to subscribe.";
return RedirectToAction("", "home"); return RedirectToAction("", "home");

View file

@ -1,14 +1,20 @@
using Data; using Data;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Model; using Model;
using OpenAI_API; using OpenAI_API;
using Services.Implemnetation; using Services.Implemnetation;
using Services.Interaces; using Services.Interaces;
using System.Net;
using Web.AIConfiguration; using Web.AIConfiguration;
namespace Web.Extesions namespace Web.Extesions
{ {
public static class ServicesExtesions public static class ServicesExtesions
{ {
public static void ConfigureSQLConnection(this IServiceCollection services, IConfiguration configuration) public static void ConfigureSQLConnection(this IServiceCollection services, IConfiguration configuration)

View file

@ -1,9 +1,5 @@
using Data; using Data;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Services.Implemnetation; using Services.Implemnetation;
using Services.Interaces;
using Web.Extesions; using Web.Extesions;
using Web.ViewComponents; using Web.ViewComponents;

View file

@ -6,8 +6,6 @@
<!-- FOR DEMO PURPOSE --> <!-- FOR DEMO PURPOSE -->
<section id="MainContent" class="text-white"> <section id="MainContent" class="text-white">
<div class="container py-1"> <div class="container py-1">

View file

@ -10,22 +10,23 @@
"ConnectionStrings": { "ConnectionStrings": {
"SurveyVista": "data source=SEO-PC; initial catalog=SurveyVista;integrated security=True; TrustServerCertificate=True;" "SurveyVista": "data source=SEO-PC; initial catalog=SurveyVista;integrated security=True; TrustServerCertificate=True;"
}, },
//"ConnectionStrings": {
// "SurveyVista": "data source=mssql11.curanet.dk; initial catalog=yacht_view_com;User Id=yacht_view; Password=P-S@bH49As; TrustServerCertificate=True;"
//},
//"ConnectionStrings": {
// "SurveyVista": "data source=SQL1003.site4now.net; Initial Catalog=db_ab8a17_vistasurvey;User Id=db_ab8a17_vistasurvey_admin,Password=1!QaisYousuf;integrated security=True; TrustServerCertificate=True;"
//},
"Email": { "Email": {
"From": "mr.qais.yousuf@gmail.com", "From": "mr.qais.yousuf@gmail.com",
"ApplicationName": "Online Survey", "ApplicationName": "Online Survey",
"ConfirmEmailPath": "Subscription/Confirmation", "ConfirmEmailPath": "Subscription/Confirmation",
"unsubscribePath": "Subscription/UnsubscribeConfirmation", "unsubscribePath": "Subscription/UnsubscribeConfirmation",
"Questionnaire": "QuestionnaireResponse/DisplayQuestionnaire", "Questionnaire": "QuestionnaireResponse/DisplayQuestionnaire"
}, },
"MailJet": { "MailJet": {
"ApiKey": "f545eee3a4743464b9d25fb9c5ab3f6c", "ApiKey": "f545eee3a4743464b9d25fb9c5ab3f6c",
"SecretKey": "8df3cf0337a090b1d6301f312ca51413" "SecretKey": "8df3cf0337a090b1d6301f312ca51413"
},
"OpenAI": {
"ApiKey": "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"
} }
} }