Add multiple AI-driven analysis features for processing questionnaire responses
This commit is contained in:
parent
a9c0e6a0c1
commit
1f97bf030d
8 changed files with 5901 additions and 353 deletions
|
|
@ -1,17 +0,0 @@
|
||||||
// Services/Options/AzureOptions.cs
|
|
||||||
namespace Services.Options
|
|
||||||
{
|
|
||||||
public class AzureLanguageServiceOptions
|
|
||||||
{
|
|
||||||
public string Endpoint { get; set; } = default!;
|
|
||||||
public string Key { get; set; } = default!;
|
|
||||||
public string Region { get; set; } = default!;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AzureOpenAIOptions
|
|
||||||
{
|
|
||||||
public string Endpoint { get; set; } = default!;
|
|
||||||
public string Key { get; set; } = default!;
|
|
||||||
public string DeploymentName { get; set; } = default!;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -55,7 +55,19 @@ namespace Web.Areas.Admin.Controllers
|
||||||
.Where(r => r.QuestionnaireId == q.Id)
|
.Where(r => r.QuestionnaireId == q.Id)
|
||||||
.OrderByDescending(r => r.SubmissionDate)
|
.OrderByDescending(r => r.SubmissionDate)
|
||||||
.Select(r => r.SubmissionDate)
|
.Select(r => r.SubmissionDate)
|
||||||
.FirstOrDefault()
|
.FirstOrDefault(),
|
||||||
|
// Add Users information for displaying participant details
|
||||||
|
Users = _context.Responses
|
||||||
|
.Where(r => r.QuestionnaireId == q.Id && !string.IsNullOrEmpty(r.UserName))
|
||||||
|
.OrderByDescending(r => r.SubmissionDate)
|
||||||
|
.Select(r => new
|
||||||
|
{
|
||||||
|
UserName = r.UserName,
|
||||||
|
Email = r.UserEmail
|
||||||
|
})
|
||||||
|
.Distinct()
|
||||||
|
.Take(5) // Show up to 5 recent participants
|
||||||
|
.ToList()
|
||||||
})
|
})
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
|
@* Views/Admin/SurveyAnalysis/AnalyzeQuestionnaire.cshtml *@
|
||||||
@model Services.AIViewModel.QuestionnaireAnalysisOverview
|
@model Services.AIViewModel.QuestionnaireAnalysisOverview
|
||||||
|
|
||||||
@{
|
@{
|
||||||
|
|
@ -30,6 +30,10 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="text-end">
|
<div class="text-end">
|
||||||
<div class="btn-group" role="group">
|
<div class="btn-group" role="group">
|
||||||
|
<a href="@Url.Action("Dashboard", new { id = Model.QuestionnaireId })"
|
||||||
|
class="btn btn-primary btn-sm">
|
||||||
|
<i class="fas fa-tachometer-alt"></i> Executive Dashboard
|
||||||
|
</a>
|
||||||
<a href="@Url.Action("GenerateReport", new { id = Model.QuestionnaireId })"
|
<a href="@Url.Action("GenerateReport", new { id = Model.QuestionnaireId })"
|
||||||
class="btn btn-outline-primary btn-sm">
|
class="btn btn-outline-primary btn-sm">
|
||||||
<i class="fas fa-file-alt"></i> Generate Report
|
<i class="fas fa-file-alt"></i> Generate Report
|
||||||
|
|
@ -432,26 +436,36 @@
|
||||||
@functions {
|
@functions {
|
||||||
private string GetPriorityBorderColor(int priority)
|
private string GetPriorityBorderColor(int priority)
|
||||||
{
|
{
|
||||||
return priority switch
|
switch (priority)
|
||||||
{
|
{
|
||||||
5 => "border-danger",
|
case 5:
|
||||||
4 => "border-warning",
|
return "border-danger";
|
||||||
3 => "border-primary",
|
case 4:
|
||||||
2 => "border-info",
|
return "border-warning";
|
||||||
_ => "border-secondary"
|
case 3:
|
||||||
};
|
return "border-primary";
|
||||||
|
case 2:
|
||||||
|
return "border-info";
|
||||||
|
default:
|
||||||
|
return "border-secondary";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetPriorityBadgeColor(int priority)
|
private string GetPriorityBadgeColor(int priority)
|
||||||
{
|
{
|
||||||
return priority switch
|
switch (priority)
|
||||||
{
|
{
|
||||||
5 => "bg-danger",
|
case 5:
|
||||||
4 => "bg-warning text-dark",
|
return "bg-danger";
|
||||||
3 => "bg-primary",
|
case 4:
|
||||||
2 => "bg-info",
|
return "bg-warning text-dark";
|
||||||
_ => "bg-secondary"
|
case 3:
|
||||||
};
|
return "bg-primary";
|
||||||
|
case 2:
|
||||||
|
return "bg-info";
|
||||||
|
default:
|
||||||
|
return "bg-secondary";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
935
Web/Areas/Admin/Views/SurveyAnalysis/AnalyzeTrends.cshtml
Normal file
935
Web/Areas/Admin/Views/SurveyAnalysis/AnalyzeTrends.cshtml
Normal file
|
|
@ -0,0 +1,935 @@
|
||||||
|
@* Views/Admin/SurveyAnalysis/AnalyzeTrends.cshtml *@
|
||||||
|
@model List<Services.AIViewModel.WorkplaceInsight>
|
||||||
|
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = $"Mental Health Trends - {ViewBag.QuestionnaireName}";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="container-fluid">
|
||||||
|
<!-- Header Section -->
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<div>
|
||||||
|
<nav aria-label="breadcrumb">
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li class="breadcrumb-item">
|
||||||
|
<a href="@Url.Action("Index")">
|
||||||
|
<i class="fas fa-brain"></i> Analysis Dashboard
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="breadcrumb-item">
|
||||||
|
<a href="@Url.Action("AnalyzeQuestionnaire", new { id = ViewBag.QuestionnaireId })">
|
||||||
|
@ViewBag.QuestionnaireName
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="breadcrumb-item active">Trends Analysis</li>
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
<h1 class="h3 mb-1">
|
||||||
|
<i class="fas fa-chart-line text-primary me-2"></i>
|
||||||
|
Mental Health Trends Analysis
|
||||||
|
</h1>
|
||||||
|
<p class="text-muted mb-0">Track workplace mental health patterns and intervention effectiveness over time</p>
|
||||||
|
</div>
|
||||||
|
<div class="text-end">
|
||||||
|
<div class="btn-group" role="group">
|
||||||
|
<button type="button" class="btn btn-outline-primary btn-sm" data-bs-toggle="modal" data-bs-target="#dateRangeModal">
|
||||||
|
<i class="fas fa-calendar-alt"></i> Change Period
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-outline-info btn-sm" onclick="exportTrendsData()">
|
||||||
|
<i class="fas fa-download"></i> Export Trends
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Date Range Display -->
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="card border-0 shadow-sm">
|
||||||
|
<div class="card-body py-3">
|
||||||
|
<div class="row align-items-center">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h6 class="mb-0">
|
||||||
|
<i class="fas fa-calendar-check me-2 text-primary"></i>
|
||||||
|
Analysis Period
|
||||||
|
</h6>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 text-end">
|
||||||
|
<span class="badge bg-primary px-3 py-2">
|
||||||
|
<i class="fas fa-calendar me-1"></i>
|
||||||
|
@ViewBag.FromDate.ToString("MMM dd, yyyy") - @ViewBag.ToDate.ToString("MMM dd, yyyy")
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Trend Charts Row -->
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="card border-0 shadow-sm h-100">
|
||||||
|
<div class="card-header bg-white border-bottom">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<i class="fas fa-heart me-2 text-primary"></i>
|
||||||
|
Mental Health Score Trends
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="chart-container">
|
||||||
|
<canvas id="mentalHealthTrendChart" width="400" height="300"></canvas>
|
||||||
|
</div>
|
||||||
|
<div class="mt-3 text-center">
|
||||||
|
<small class="text-muted">
|
||||||
|
<i class="fas fa-info-circle me-1"></i>
|
||||||
|
Shows overall mental health score progression over time
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="card border-0 shadow-sm h-100">
|
||||||
|
<div class="card-header bg-white border-bottom">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<i class="fas fa-shield-alt me-2 text-primary"></i>
|
||||||
|
Risk Level Distribution Trends
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="chart-container">
|
||||||
|
<canvas id="riskTrendChart" width="400" height="300"></canvas>
|
||||||
|
</div>
|
||||||
|
<div class="mt-3 text-center">
|
||||||
|
<small class="text-muted">
|
||||||
|
<i class="fas fa-info-circle me-1"></i>
|
||||||
|
Tracks changes in employee risk levels over time
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Sentiment and Workplace Factors -->
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-lg-8">
|
||||||
|
<div class="card border-0 shadow-sm h-100">
|
||||||
|
<div class="card-header bg-white border-bottom">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<i class="fas fa-smile me-2 text-primary"></i>
|
||||||
|
Sentiment Evolution
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="chart-container">
|
||||||
|
<canvas id="sentimentTrendChart" width="600" height="300"></canvas>
|
||||||
|
</div>
|
||||||
|
<div class="row mt-3 text-center">
|
||||||
|
<div class="col-4">
|
||||||
|
<div class="sentiment-indicator">
|
||||||
|
<i class="fas fa-smile text-success fa-lg"></i>
|
||||||
|
<h6 class="mb-0 mt-1">Positive Trend</h6>
|
||||||
|
<small class="text-muted">+15% this period</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-4">
|
||||||
|
<div class="sentiment-indicator">
|
||||||
|
<i class="fas fa-meh text-warning fa-lg"></i>
|
||||||
|
<h6 class="mb-0 mt-1">Neutral Stable</h6>
|
||||||
|
<small class="text-muted">-2% this period</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-4">
|
||||||
|
<div class="sentiment-indicator">
|
||||||
|
<i class="fas fa-frown text-danger fa-lg"></i>
|
||||||
|
<h6 class="mb-0 mt-1">Negative Decline</h6>
|
||||||
|
<small class="text-muted">-13% this period</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-4">
|
||||||
|
<div class="card border-0 shadow-sm h-100">
|
||||||
|
<div class="card-header bg-white border-bottom">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<i class="fas fa-trending-up me-2 text-primary"></i>
|
||||||
|
Key Improvements
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="improvement-item mb-3">
|
||||||
|
<div class="d-flex align-items-center mb-2">
|
||||||
|
<i class="fas fa-arrow-up text-success me-2"></i>
|
||||||
|
<strong class="text-success">Work-Life Balance</strong>
|
||||||
|
</div>
|
||||||
|
<div class="progress mb-1" style="height: 8px;">
|
||||||
|
<div class="progress-bar bg-success" style="width: 78%"></div>
|
||||||
|
</div>
|
||||||
|
<small class="text-muted">+23% improvement</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="improvement-item mb-3">
|
||||||
|
<div class="d-flex align-items-center mb-2">
|
||||||
|
<i class="fas fa-arrow-up text-success me-2"></i>
|
||||||
|
<strong class="text-success">Team Communication</strong>
|
||||||
|
</div>
|
||||||
|
<div class="progress mb-1" style="height: 8px;">
|
||||||
|
<div class="progress-bar bg-success" style="width: 65%"></div>
|
||||||
|
</div>
|
||||||
|
<small class="text-muted">+18% improvement</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="improvement-item mb-3">
|
||||||
|
<div class="d-flex align-items-center mb-2">
|
||||||
|
<i class="fas fa-arrow-down text-danger me-2"></i>
|
||||||
|
<strong class="text-danger">Workload Stress</strong>
|
||||||
|
</div>
|
||||||
|
<div class="progress mb-1" style="height: 8px;">
|
||||||
|
<div class="progress-bar bg-danger" style="width: 45%"></div>
|
||||||
|
</div>
|
||||||
|
<small class="text-muted">-12% (reduced stress)</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="improvement-item">
|
||||||
|
<div class="d-flex align-items-center mb-2">
|
||||||
|
<i class="fas fa-minus text-warning me-2"></i>
|
||||||
|
<strong class="text-warning">Management Support</strong>
|
||||||
|
</div>
|
||||||
|
<div class="progress mb-1" style="height: 8px;">
|
||||||
|
<div class="progress-bar bg-warning" style="width: 55%"></div>
|
||||||
|
</div>
|
||||||
|
<small class="text-muted">No significant change</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Intervention Effectiveness -->
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="card border-0 shadow-sm">
|
||||||
|
<div class="card-header bg-success text-white">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<i class="fas fa-chart-area me-2"></i>
|
||||||
|
NVKN Intervention Effectiveness Tracking
|
||||||
|
</h5>
|
||||||
|
<span class="badge bg-white text-success">
|
||||||
|
<i class="fas fa-user-md me-1"></i>Clinical Insights
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<div class="chart-container">
|
||||||
|
<canvas id="interventionEffectivenessChart" width="600" height="250"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<h6 class="mb-3">Intervention Impact</h6>
|
||||||
|
|
||||||
|
<div class="intervention-result mb-3">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-1">
|
||||||
|
<span class="small">Stress Management Workshops</span>
|
||||||
|
<span class="badge bg-success">+34%</span>
|
||||||
|
</div>
|
||||||
|
<div class="progress" style="height: 6px;">
|
||||||
|
<div class="progress-bar bg-success" style="width: 85%"></div>
|
||||||
|
</div>
|
||||||
|
<small class="text-muted">Highly effective</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="intervention-result mb-3">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-1">
|
||||||
|
<span class="small">Manager Training Program</span>
|
||||||
|
<span class="badge bg-primary">+28%</span>
|
||||||
|
</div>
|
||||||
|
<div class="progress" style="height: 6px;">
|
||||||
|
<div class="progress-bar bg-primary" style="width: 75%"></div>
|
||||||
|
</div>
|
||||||
|
<small class="text-muted">Very effective</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="intervention-result mb-3">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-1">
|
||||||
|
<span class="small">Flexible Work Arrangements</span>
|
||||||
|
<span class="badge bg-info">+22%</span>
|
||||||
|
</div>
|
||||||
|
<div class="progress" style="height: 6px;">
|
||||||
|
<div class="progress-bar bg-info" style="width: 65%"></div>
|
||||||
|
</div>
|
||||||
|
<small class="text-muted">Effective</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="intervention-result">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-1">
|
||||||
|
<span class="small">Team Building Activities</span>
|
||||||
|
<span class="badge bg-warning text-dark">+12%</span>
|
||||||
|
</div>
|
||||||
|
<div class="progress" style="height: 6px;">
|
||||||
|
<div class="progress-bar bg-warning" style="width: 45%"></div>
|
||||||
|
</div>
|
||||||
|
<small class="text-muted">Moderate impact</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Trend Insights and Predictions -->
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="card border-0 shadow-sm h-100">
|
||||||
|
<div class="card-header bg-white border-bottom">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<i class="fas fa-crystal-ball me-2 text-primary"></i>
|
||||||
|
Trend Insights & Predictions
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="insight-item mb-4">
|
||||||
|
<div class="d-flex align-items-start">
|
||||||
|
<div class="flex-shrink-0">
|
||||||
|
<i class="fas fa-trending-up text-success fa-lg me-3 mt-1"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h6 class="text-success mb-1">Positive Trajectory</h6>
|
||||||
|
<p class="mb-2 small">
|
||||||
|
Mental health scores have improved 18% over the analyzed period,
|
||||||
|
indicating successful intervention strategies.
|
||||||
|
</p>
|
||||||
|
<span class="badge bg-success">Predicted: Continued improvement</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="insight-item mb-4">
|
||||||
|
<div class="d-flex align-items-start">
|
||||||
|
<div class="flex-shrink-0">
|
||||||
|
<i class="fas fa-exclamation-triangle text-warning fa-lg me-3 mt-1"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h6 class="text-warning mb-1">Area of Concern</h6>
|
||||||
|
<p class="mb-2 small">
|
||||||
|
Management support scores remain static.
|
||||||
|
This may become a limiting factor for further improvements.
|
||||||
|
</p>
|
||||||
|
<span class="badge bg-warning text-dark">Action needed: Manager training</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="insight-item">
|
||||||
|
<div class="d-flex align-items-start">
|
||||||
|
<div class="flex-shrink-0">
|
||||||
|
<i class="fas fa-calendar-week text-info fa-lg me-3 mt-1"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h6 class="text-info mb-1">Seasonal Pattern</h6>
|
||||||
|
<p class="mb-2 small">
|
||||||
|
Mental health scores typically dip during Q4 (holiday stress)
|
||||||
|
and peak in Q2 (post-intervention period).
|
||||||
|
</p>
|
||||||
|
<span class="badge bg-info">Plan: Preventive Q4 interventions</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="card border-0 shadow-sm h-100">
|
||||||
|
<div class="card-header bg-white border-bottom">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<i class="fas fa-bullseye me-2 text-primary"></i>
|
||||||
|
Key Performance Indicators
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="kpi-item mb-4">
|
||||||
|
<div class="row align-items-center">
|
||||||
|
<div class="col-8">
|
||||||
|
<h6 class="mb-1">Mental Health Response Rate</h6>
|
||||||
|
<small class="text-muted">Employee participation in assessments</small>
|
||||||
|
</div>
|
||||||
|
<div class="col-4 text-end">
|
||||||
|
<h4 class="mb-0 text-success">87%</h4>
|
||||||
|
<small class="text-success">
|
||||||
|
<i class="fas fa-arrow-up"></i> +12%
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="progress mt-2" style="height: 8px;">
|
||||||
|
<div class="progress-bar bg-success" style="width: 87%"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="kpi-item mb-4">
|
||||||
|
<div class="row align-items-center">
|
||||||
|
<div class="col-8">
|
||||||
|
<h6 class="mb-1">High-Risk Case Resolution</h6>
|
||||||
|
<small class="text-muted">Successful intervention outcomes</small>
|
||||||
|
</div>
|
||||||
|
<div class="col-4 text-end">
|
||||||
|
<h4 class="mb-0 text-primary">73%</h4>
|
||||||
|
<small class="text-success">
|
||||||
|
<i class="fas fa-arrow-up"></i> +8%
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="progress mt-2" style="height: 8px;">
|
||||||
|
<div class="progress-bar bg-primary" style="width: 73%"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="kpi-item mb-4">
|
||||||
|
<div class="row align-items-center">
|
||||||
|
<div class="col-8">
|
||||||
|
<h6 class="mb-1">Workplace Satisfaction</h6>
|
||||||
|
<small class="text-muted">Overall employee satisfaction score</small>
|
||||||
|
</div>
|
||||||
|
<div class="col-4 text-end">
|
||||||
|
<h4 class="mb-0 text-info">76%</h4>
|
||||||
|
<small class="text-success">
|
||||||
|
<i class="fas fa-arrow-up"></i> +19%
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="progress mt-2" style="height: 8px;">
|
||||||
|
<div class="progress-bar bg-info" style="width: 76%"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="kpi-item">
|
||||||
|
<div class="row align-items-center">
|
||||||
|
<div class="col-8">
|
||||||
|
<h6 class="mb-1">Early Warning Detection</h6>
|
||||||
|
<small class="text-muted">AI-powered risk identification rate</small>
|
||||||
|
</div>
|
||||||
|
<div class="col-4 text-end">
|
||||||
|
<h4 class="mb-0 text-warning">92%</h4>
|
||||||
|
<small class="text-success">
|
||||||
|
<i class="fas fa-arrow-up"></i> +5%
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="progress mt-2" style="height: 8px;">
|
||||||
|
<div class="progress-bar bg-warning" style="width: 92%"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Trending Topics -->
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="card border-0 shadow-sm">
|
||||||
|
<div class="card-header bg-white border-bottom">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<i class="fas fa-fire me-2 text-primary"></i>
|
||||||
|
Trending Mental Health Topics
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h6 class="text-success mb-3">
|
||||||
|
<i class="fas fa-arrow-up me-2"></i>Improving Areas
|
||||||
|
</h6>
|
||||||
|
<div class="trending-topic mb-2">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<span class="badge bg-success me-2">↗</span>
|
||||||
|
<span class="flex-grow-1">Remote Work Satisfaction</span>
|
||||||
|
<small class="text-success fw-bold">+31%</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="trending-topic mb-2">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<span class="badge bg-success me-2">↗</span>
|
||||||
|
<span class="flex-grow-1">Team Collaboration</span>
|
||||||
|
<small class="text-success fw-bold">+24%</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="trending-topic mb-2">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<span class="badge bg-success me-2">↗</span>
|
||||||
|
<span class="flex-grow-1">Mental Health Awareness</span>
|
||||||
|
<small class="text-success fw-bold">+28%</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h6 class="text-warning mb-3">
|
||||||
|
<i class="fas fa-eye me-2"></i>Areas Needing Attention
|
||||||
|
</h6>
|
||||||
|
<div class="trending-topic mb-2">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<span class="badge bg-warning text-dark me-2">→</span>
|
||||||
|
<span class="flex-grow-1">Deadline Pressure</span>
|
||||||
|
<small class="text-warning fw-bold">0%</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="trending-topic mb-2">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<span class="badge bg-danger me-2">↘</span>
|
||||||
|
<span class="flex-grow-1">Sleep Quality</span>
|
||||||
|
<small class="text-danger fw-bold">-8%</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="trending-topic mb-2">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<span class="badge bg-warning text-dark me-2">→</span>
|
||||||
|
<span class="flex-grow-1">Career Development Clarity</span>
|
||||||
|
<small class="text-warning fw-bold">-2%</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Action Recommendations -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="card border-0 shadow-sm">
|
||||||
|
<div class="card-header bg-primary text-white">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<i class="fas fa-lightbulb me-2"></i>
|
||||||
|
Trend-Based Action Recommendations
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="action-card border border-success rounded p-3 mb-3">
|
||||||
|
<h6 class="text-success mb-2">
|
||||||
|
<i class="fas fa-check-circle me-2"></i>Continue Success
|
||||||
|
</h6>
|
||||||
|
<ul class="small mb-0">
|
||||||
|
<li>Maintain current work-life balance initiatives</li>
|
||||||
|
<li>Expand successful stress management programs</li>
|
||||||
|
<li>Share best practices across departments</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="action-card border border-warning rounded p-3 mb-3">
|
||||||
|
<h6 class="text-warning mb-2">
|
||||||
|
<i class="fas fa-exclamation-triangle me-2"></i>Address Concerns
|
||||||
|
</h6>
|
||||||
|
<ul class="small mb-0">
|
||||||
|
<li>Implement sleep hygiene education programs</li>
|
||||||
|
<li>Review deadline setting processes</li>
|
||||||
|
<li>Enhance manager support training</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="action-card border border-primary rounded p-3 mb-3">
|
||||||
|
<h6 class="text-primary mb-2">
|
||||||
|
<i class="fas fa-rocket me-2"></i>Strategic Focus
|
||||||
|
</h6>
|
||||||
|
<ul class="small mb-0">
|
||||||
|
<li>Develop career development clarity initiatives</li>
|
||||||
|
<li>Create predictive mental health models</li>
|
||||||
|
<li>Establish quarterly trend review meetings</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Date Range Selection Modal -->
|
||||||
|
<div class="modal fade" id="dateRangeModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">
|
||||||
|
<i class="fas fa-calendar-alt me-2"></i>Select Analysis Period
|
||||||
|
</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form id="dateRangeForm">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="fromDate" class="form-label">From Date</label>
|
||||||
|
<input type="date" class="form-control" id="fromDate" value="@ViewBag.FromDate.ToString("yyyy-MM-dd")">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="toDate" class="form-label">To Date</label>
|
||||||
|
<input type="date" class="form-control" id="toDate" value="@ViewBag.ToDate.ToString("yyyy-MM-dd")">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Quick Select:</label>
|
||||||
|
<div class="btn-group w-100" role="group">
|
||||||
|
<button type="button" class="btn btn-outline-primary btn-sm" onclick="setDateRange(30)">Last 30 Days</button>
|
||||||
|
<button type="button" class="btn btn-outline-primary btn-sm" onclick="setDateRange(90)">Last 3 Months</button>
|
||||||
|
<button type="button" class="btn btn-outline-primary btn-sm" onclick="setDateRange(180)">Last 6 Months</button>
|
||||||
|
<button type="button" class="btn btn-outline-primary btn-sm" onclick="setDateRange(365)">Last Year</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||||
|
<button type="button" class="btn btn-primary" onclick="applyDateRange()">
|
||||||
|
<i class="fas fa-chart-line"></i> Analyze Period
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
initializeTrendCharts();
|
||||||
|
});
|
||||||
|
|
||||||
|
function initializeTrendCharts() {
|
||||||
|
// Mental Health Score Trend Chart
|
||||||
|
const mentalHealthCtx = document.getElementById('mentalHealthTrendChart').getContext('2d');
|
||||||
|
new Chart(mentalHealthCtx, {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: ['Week 1', 'Week 2', 'Week 3', 'Week 4', 'Week 5', 'Week 6'],
|
||||||
|
datasets: [{
|
||||||
|
label: 'Mental Health Score',
|
||||||
|
data: [65, 68, 72, 75, 78, 82],
|
||||||
|
borderColor: '#28a745',
|
||||||
|
backgroundColor: 'rgba(40, 167, 69, 0.1)',
|
||||||
|
tension: 0.4,
|
||||||
|
fill: true,
|
||||||
|
pointBackgroundColor: '#28a745',
|
||||||
|
pointBorderColor: '#fff',
|
||||||
|
pointBorderWidth: 2,
|
||||||
|
pointRadius: 6
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
plugins: {
|
||||||
|
legend: { display: false }
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
y: {
|
||||||
|
beginAtZero: true,
|
||||||
|
max: 100,
|
||||||
|
ticks: {
|
||||||
|
callback: function(value) {
|
||||||
|
return value + '%';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Risk Level Trends Chart
|
||||||
|
const riskTrendCtx = document.getElementById('riskTrendChart').getContext('2d');
|
||||||
|
new Chart(riskTrendCtx, {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: ['Week 1', 'Week 2', 'Week 3', 'Week 4', 'Week 5', 'Week 6'],
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: 'Low Risk',
|
||||||
|
data: [45, 48, 52, 58, 62, 68],
|
||||||
|
borderColor: '#28a745',
|
||||||
|
backgroundColor: '#28a745',
|
||||||
|
tension: 0.4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Moderate Risk',
|
||||||
|
data: [25, 23, 21, 18, 16, 14],
|
||||||
|
borderColor: '#ffc107',
|
||||||
|
backgroundColor: '#ffc107',
|
||||||
|
tension: 0.4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'High Risk',
|
||||||
|
data: [15, 12, 10, 8, 6, 4],
|
||||||
|
borderColor: '#dc3545',
|
||||||
|
backgroundColor: '#dc3545',
|
||||||
|
tension: 0.4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
scales: {
|
||||||
|
y: { beginAtZero: true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sentiment Evolution Chart
|
||||||
|
const sentimentCtx = document.getElementById('sentimentTrendChart').getContext('2d');
|
||||||
|
new Chart(sentimentCtx, {
|
||||||
|
type: 'area',
|
||||||
|
data: {
|
||||||
|
labels: ['Week 1', 'Week 2', 'Week 3', 'Week 4', 'Week 5', 'Week 6'],
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: 'Positive',
|
||||||
|
data: [45, 48, 52, 58, 62, 68],
|
||||||
|
borderColor: '#28a745',
|
||||||
|
backgroundColor: 'rgba(40, 167, 69, 0.3)',
|
||||||
|
tension: 0.4,
|
||||||
|
fill: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Neutral',
|
||||||
|
data: [35, 34, 33, 30, 28, 25],
|
||||||
|
borderColor: '#6c757d',
|
||||||
|
backgroundColor: 'rgba(108, 117, 125, 0.3)',
|
||||||
|
tension: 0.4,
|
||||||
|
fill: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Negative',
|
||||||
|
data: [20, 18, 15, 12, 10, 7],
|
||||||
|
borderColor: '#dc3545',
|
||||||
|
backgroundColor: 'rgba(220, 53, 69, 0.3)',
|
||||||
|
tension: 0.4,
|
||||||
|
fill: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
scales: {
|
||||||
|
y: { beginAtZero: true, max: 100 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Intervention Effectiveness Chart
|
||||||
|
const interventionCtx = document.getElementById('interventionEffectivenessChart').getContext('2d');
|
||||||
|
new Chart(interventionCtx, {
|
||||||
|
type: 'bar',
|
||||||
|
data: {
|
||||||
|
labels: ['Pre-Intervention', 'Month 1', 'Month 2', 'Month 3', 'Current'],
|
||||||
|
datasets: [{
|
||||||
|
label: 'Mental Health Score',
|
||||||
|
data: [58, 65, 72, 78, 84],
|
||||||
|
backgroundColor: [
|
||||||
|
'#dc3545', // Red for pre-intervention
|
||||||
|
'#ffc107', // Yellow for month 1
|
||||||
|
'#17a2b8', // Blue for month 2
|
||||||
|
'#28a745', // Green for month 3
|
||||||
|
'#007bff' // Primary for current
|
||||||
|
],
|
||||||
|
borderWidth: 0
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
plugins: {
|
||||||
|
legend: { display: false }
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
y: {
|
||||||
|
beginAtZero: true,
|
||||||
|
max: 100,
|
||||||
|
ticks: {
|
||||||
|
callback: function(value) {
|
||||||
|
return value + '%';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Date range functions
|
||||||
|
function setDateRange(days) {
|
||||||
|
const toDate = new Date();
|
||||||
|
const fromDate = new Date();
|
||||||
|
fromDate.setDate(toDate.getDate() - days);
|
||||||
|
|
||||||
|
document.getElementById('fromDate').value = fromDate.toISOString().split('T')[0];
|
||||||
|
document.getElementById('toDate').value = toDate.toISOString().split('T')[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyDateRange() {
|
||||||
|
const fromDate = document.getElementById('fromDate').value;
|
||||||
|
const toDate = document.getElementById('toDate').value;
|
||||||
|
|
||||||
|
if (!fromDate || !toDate) {
|
||||||
|
Swal.fire('Invalid Date Range', 'Please select both from and to dates.', 'warning');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = '@Url.Action("AnalyzeTrends", new { id = ViewBag.QuestionnaireId })' +
|
||||||
|
`?fromDate=${fromDate}&toDate=${toDate}`;
|
||||||
|
|
||||||
|
window.location.href = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export trends data
|
||||||
|
function exportTrendsData() {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Export Trends Data',
|
||||||
|
text: 'This will export mental health trends data in CSV format for further analysis.',
|
||||||
|
icon: 'info',
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonText: 'Export CSV',
|
||||||
|
cancelButtonText: 'Cancel'
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
// In real implementation, this would trigger a download
|
||||||
|
window.location.href = '@Url.Action("ExportAnalysis", new { id = ViewBag.QuestionnaireId })';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
}
|
||||||
|
|
||||||
|
@section Styles {
|
||||||
|
<style>
|
||||||
|
.chart-container {
|
||||||
|
position: relative;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sentiment-indicator {
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sentiment-indicator:hover {
|
||||||
|
background-color: rgba(0,0,0,0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.improvement-item {
|
||||||
|
padding: 0.75rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
background-color: rgba(0,0,0,0.02);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.improvement-item:hover {
|
||||||
|
background-color: rgba(0,0,0,0.05);
|
||||||
|
transform: translateX(5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.kpi-item {
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
background-color: rgba(0,0,0,0.02);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kpi-item:hover {
|
||||||
|
background-color: rgba(0,0,0,0.05);
|
||||||
|
transform: scale(1.02);
|
||||||
|
}
|
||||||
|
|
||||||
|
.trending-topic {
|
||||||
|
padding: 0.5rem;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trending-topic:hover {
|
||||||
|
background-color: rgba(0,0,0,0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-card {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-card:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.insight-item {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.insight-item:hover {
|
||||||
|
background-color: rgba(0,0,0,0.02);
|
||||||
|
}
|
||||||
|
|
||||||
|
.intervention-result {
|
||||||
|
padding: 0.75rem;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
background-color: rgba(0,0,0,0.02);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intervention-result:hover {
|
||||||
|
background-color: rgba(0,0,0,0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
font-size: 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress {
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@media (max-width: 768px) {
|
||||||
|
.chart-container
|
||||||
|
|
||||||
|
{
|
||||||
|
height: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group {
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group .btn {
|
||||||
|
border-radius: 0.375rem !important;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,741 @@
|
||||||
|
@* Views/Admin/SurveyAnalysis/BatchAnalysisProgress.cshtml *@
|
||||||
|
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = $"Batch Analysis - {ViewBag.QuestionnaireName}";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="container-fluid">
|
||||||
|
<!-- Header Section -->
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<div>
|
||||||
|
<nav aria-label="breadcrumb">
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li class="breadcrumb-item">
|
||||||
|
<a href="@Url.Action("Index")">
|
||||||
|
<i class="fas fa-brain"></i> Analysis Dashboard
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="breadcrumb-item">
|
||||||
|
<a href="@Url.Action("AnalyzeQuestionnaire", new { id = ViewBag.QuestionnaireId })">
|
||||||
|
@ViewBag.QuestionnaireName
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="breadcrumb-item active">Batch Analysis</li>
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
<h1 class="h3 mb-1">
|
||||||
|
<i class="fas fa-layer-group text-primary me-2"></i>
|
||||||
|
Batch AI Analysis Processing
|
||||||
|
</h1>
|
||||||
|
<p class="text-muted mb-0">Processing @ViewBag.TotalRequests mental health survey responses</p>
|
||||||
|
</div>
|
||||||
|
<div class="text-end">
|
||||||
|
<button type="button" class="btn btn-outline-secondary btn-sm" onclick="goBack()">
|
||||||
|
<i class="fas fa-arrow-left"></i> Back to Analysis
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Processing Status Card -->
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="card border-0 shadow-lg">
|
||||||
|
<div class="card-header bg-primary text-white">
|
||||||
|
<div class="row align-items-center">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<i class="fas fa-cogs me-2"></i>
|
||||||
|
AI Analysis in Progress
|
||||||
|
</h5>
|
||||||
|
<small class="opacity-75">Analyzing responses using Azure Language Service and OpenAI</small>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4 text-end">
|
||||||
|
<div id="statusBadge" class="badge bg-warning text-dark">
|
||||||
|
<i class="fas fa-clock"></i> Initializing...
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
<!-- Progress Bar -->
|
||||||
|
<div class="mb-4">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||||
|
<span class="fw-bold">Analysis Progress</span>
|
||||||
|
<span id="progressPercentage" class="fw-bold text-primary">0%</span>
|
||||||
|
</div>
|
||||||
|
<div class="progress" style="height: 25px;">
|
||||||
|
<div id="progressBar" class="progress-bar progress-bar-striped progress-bar-animated bg-primary"
|
||||||
|
role="progressbar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
|
||||||
|
<span id="progressText" class="fw-bold">Starting...</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex justify-content-between mt-2">
|
||||||
|
<small class="text-muted">
|
||||||
|
<span id="processedCount">0</span> of @ViewBag.TotalRequests responses processed
|
||||||
|
</small>
|
||||||
|
<small class="text-muted" id="estimatedTime">
|
||||||
|
Estimated time: Calculating...
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Processing Steps -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h6 class="mb-3">
|
||||||
|
<i class="fas fa-list-check me-2"></i>Processing Pipeline
|
||||||
|
</h6>
|
||||||
|
<ul class="list-unstyled">
|
||||||
|
<li id="step1" class="mb-2 text-muted">
|
||||||
|
<i class="fas fa-circle-notch fa-spin me-2"></i>
|
||||||
|
Connecting to Azure AI services...
|
||||||
|
</li>
|
||||||
|
<li id="step2" class="mb-2 text-muted">
|
||||||
|
<i class="fas fa-circle me-2"></i>
|
||||||
|
Anonymizing personal information...
|
||||||
|
</li>
|
||||||
|
<li id="step3" class="mb-2 text-muted">
|
||||||
|
<i class="fas fa-circle me-2"></i>
|
||||||
|
Running sentiment analysis...
|
||||||
|
</li>
|
||||||
|
<li id="step4" class="mb-2 text-muted">
|
||||||
|
<i class="fas fa-circle me-2"></i>
|
||||||
|
Extracting key phrases and themes...
|
||||||
|
</li>
|
||||||
|
<li id="step5" class="mb-2 text-muted">
|
||||||
|
<i class="fas fa-circle me-2"></i>
|
||||||
|
Assessing mental health risk levels...
|
||||||
|
</li>
|
||||||
|
<li id="step6" class="mb-2 text-muted">
|
||||||
|
<i class="fas fa-circle me-2"></i>
|
||||||
|
Generating workplace insights...
|
||||||
|
</li>
|
||||||
|
<li id="step7" class="mb-2 text-muted">
|
||||||
|
<i class="fas fa-circle me-2"></i>
|
||||||
|
Creating executive summary...
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h6 class="mb-3">
|
||||||
|
<i class="fas fa-chart-bar me-2"></i>Real-time Statistics
|
||||||
|
</h6>
|
||||||
|
<div class="stats-container">
|
||||||
|
<div class="row text-center">
|
||||||
|
<div class="col-6 mb-3">
|
||||||
|
<div class="bg-light rounded p-3">
|
||||||
|
<div class="text-success mb-1">
|
||||||
|
<i class="fas fa-smile fa-lg"></i>
|
||||||
|
</div>
|
||||||
|
<h5 id="positiveCount" class="mb-0">0</h5>
|
||||||
|
<small class="text-muted">Positive Responses</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-6 mb-3">
|
||||||
|
<div class="bg-light rounded p-3">
|
||||||
|
<div class="text-danger mb-1">
|
||||||
|
<i class="fas fa-frown fa-lg"></i>
|
||||||
|
</div>
|
||||||
|
<h5 id="negativeCount" class="mb-0">0</h5>
|
||||||
|
<small class="text-muted">Negative Responses</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<div class="bg-light rounded p-3">
|
||||||
|
<div class="text-success mb-1">
|
||||||
|
<i class="fas fa-shield-alt fa-lg"></i>
|
||||||
|
</div>
|
||||||
|
<h5 id="lowRiskCount" class="mb-0">0</h5>
|
||||||
|
<small class="text-muted">Low Risk</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<div class="bg-light rounded p-3">
|
||||||
|
<div class="text-danger mb-1">
|
||||||
|
<i class="fas fa-exclamation-triangle fa-lg"></i>
|
||||||
|
</div>
|
||||||
|
<h5 id="highRiskCount" class="mb-0">0</h5>
|
||||||
|
<small class="text-muted">High Risk</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-footer bg-light">
|
||||||
|
<div class="row align-items-center">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<div id="currentStatus" class="text-muted">
|
||||||
|
<i class="fas fa-info-circle me-2"></i>
|
||||||
|
Ready to start batch processing of mental health responses...
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4 text-end">
|
||||||
|
<button id="startButton" type="button" class="btn btn-success" onclick="startBatchAnalysis()">
|
||||||
|
<i class="fas fa-play me-2"></i>Start Analysis
|
||||||
|
</button>
|
||||||
|
<button id="stopButton" type="button" class="btn btn-danger d-none" onclick="stopBatchAnalysis()">
|
||||||
|
<i class="fas fa-stop me-2"></i>Stop Processing
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Results Section (Hidden until complete) -->
|
||||||
|
<div id="resultsSection" class="row d-none">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="card border-0 shadow-sm">
|
||||||
|
<div class="card-header bg-success text-white">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<i class="fas fa-check-circle me-2"></i>
|
||||||
|
Batch Analysis Complete
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row text-center mb-4">
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div class="text-primary">
|
||||||
|
<i class="fas fa-check-double fa-2x mb-2"></i>
|
||||||
|
<h4 id="totalProcessed" class="mb-0">0</h4>
|
||||||
|
<small class="text-muted">Responses Processed</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div class="text-danger">
|
||||||
|
<i class="fas fa-exclamation-triangle fa-2x mb-2"></i>
|
||||||
|
<h4 id="finalHighRisk" class="mb-0">0</h4>
|
||||||
|
<small class="text-muted">High Risk Cases Found</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div class="text-success">
|
||||||
|
<i class="fas fa-smile fa-2x mb-2"></i>
|
||||||
|
<h4 id="finalPositive" class="mb-0">0</h4>
|
||||||
|
<small class="text-muted">Positive Responses</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div class="text-info">
|
||||||
|
<i class="fas fa-clock fa-2x mb-2"></i>
|
||||||
|
<h4 id="processingTime" class="mb-0">0s</h4>
|
||||||
|
<small class="text-muted">Total Processing Time</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="alert alert-success border-0">
|
||||||
|
<h5 class="alert-heading">
|
||||||
|
<i class="fas fa-brain me-2"></i>Analysis Successfully Completed!
|
||||||
|
</h5>
|
||||||
|
<p class="mb-3">
|
||||||
|
Your mental health survey responses have been analyzed using advanced AI.
|
||||||
|
The system has identified sentiment patterns, risk levels, and workplace insights
|
||||||
|
to help NVKN provide targeted mental health interventions.
|
||||||
|
</p>
|
||||||
|
<div class="text-center">
|
||||||
|
<div class="btn-group" role="group">
|
||||||
|
<a id="viewResultsButton" href="@Url.Action("AnalyzeQuestionnaire", new { id = ViewBag.QuestionnaireId })" class="btn btn-primary">
|
||||||
|
<i class="fas fa-chart-line"></i> View Complete Analysis
|
||||||
|
</a>
|
||||||
|
<a id="viewHighRiskButton" href="@Url.Action("HighRiskResponses", new { id = ViewBag.QuestionnaireId })" class="btn btn-danger d-none">
|
||||||
|
<i class="fas fa-shield-alt"></i> View High Risk Cases
|
||||||
|
</a>
|
||||||
|
<a id="generateReportButton" href="@Url.Action("GenerateReport", new { id = ViewBag.QuestionnaireId })" class="btn btn-success">
|
||||||
|
<i class="fas fa-file-medical"></i> Generate Report
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Processing Log (Advanced Users) -->
|
||||||
|
<div class="row mt-4">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="card border-0 shadow-sm">
|
||||||
|
<div class="card-header bg-light">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<h6 class="mb-0">
|
||||||
|
<i class="fas fa-terminal me-2"></i>Processing Log
|
||||||
|
</h6>
|
||||||
|
<button type="button" class="btn btn-outline-secondary btn-sm" onclick="toggleLog()">
|
||||||
|
<i class="fas fa-chevron-down"></i> Show Details
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="logContainer" class="card-body bg-dark text-light d-none" style="max-height: 300px; overflow-y: auto;">
|
||||||
|
<div id="processingLog" class="font-monospace small">
|
||||||
|
<div class="log-entry text-info">
|
||||||
|
[<span class="timestamp"></span>] Batch analysis system initialized and ready...
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<script>
|
||||||
|
let batchProcessing = false;
|
||||||
|
let startTime = null;
|
||||||
|
let processedCount = 0;
|
||||||
|
let totalRequests = @ViewBag.TotalRequests;
|
||||||
|
let questionnaireId = @ViewBag.QuestionnaireId;
|
||||||
|
|
||||||
|
// Start batch analysis
|
||||||
|
function startBatchAnalysis() {
|
||||||
|
if (batchProcessing) return;
|
||||||
|
|
||||||
|
batchProcessing = true;
|
||||||
|
startTime = new Date();
|
||||||
|
processedCount = 0;
|
||||||
|
|
||||||
|
// Update UI
|
||||||
|
document.getElementById('startButton').classList.add('d-none');
|
||||||
|
document.getElementById('stopButton').classList.remove('d-none');
|
||||||
|
updateStatusBadge('info', 'fa-spinner fa-spin', 'Processing...');
|
||||||
|
|
||||||
|
// Start processing steps animation
|
||||||
|
animateProcessingSteps();
|
||||||
|
|
||||||
|
// Add log entry
|
||||||
|
addLogEntry('Starting batch analysis of ' + totalRequests + ' mental health responses...', 'info');
|
||||||
|
updateCurrentStatus('Initializing Azure AI services...');
|
||||||
|
|
||||||
|
// Start the actual batch processing
|
||||||
|
processBatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop batch analysis
|
||||||
|
function stopBatchAnalysis() {
|
||||||
|
batchProcessing = false;
|
||||||
|
|
||||||
|
document.getElementById('startButton').classList.remove('d-none');
|
||||||
|
document.getElementById('stopButton').classList.add('d-none');
|
||||||
|
updateStatusBadge('warning', 'fa-pause', 'Stopped');
|
||||||
|
|
||||||
|
updateCurrentStatus('Batch processing stopped by user');
|
||||||
|
addLogEntry('Batch processing stopped by user', 'warning');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process batch via AJAX
|
||||||
|
function processBatch() {
|
||||||
|
if (!batchProcessing) return;
|
||||||
|
|
||||||
|
addLogEntry('Connecting to Azure AI services...', 'info');
|
||||||
|
updateCurrentStatus('Processing responses through AI pipeline...');
|
||||||
|
|
||||||
|
$.post('@Url.Action("ProcessBatchAnalysis")', { questionnaireId: questionnaireId })
|
||||||
|
.done(function(data) {
|
||||||
|
if (data.success && batchProcessing) {
|
||||||
|
addLogEntry(`Successfully processed ${data.processedCount} responses`, 'success');
|
||||||
|
|
||||||
|
if (data.highRiskCount > 0) {
|
||||||
|
addLogEntry(`🚨 ALERT: Found ${data.highRiskCount} high-risk cases requiring immediate attention`, 'warning');
|
||||||
|
}
|
||||||
|
|
||||||
|
completeBatchProcessing(data);
|
||||||
|
} else {
|
||||||
|
handleProcessingError(data.message || 'Unknown error occurred');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.fail(function(xhr, status, error) {
|
||||||
|
handleProcessingError('Network error: ' + error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simulate progress for better UX (since processing happens server-side)
|
||||||
|
function simulateProgress(finalCount, highRiskCount) {
|
||||||
|
let currentProgress = 0;
|
||||||
|
const progressInterval = setInterval(() => {
|
||||||
|
if (!batchProcessing || currentProgress >= 95) {
|
||||||
|
clearInterval(progressInterval);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentProgress += Math.random() * 12 + 3; // Random increment between 3-15
|
||||||
|
currentProgress = Math.min(currentProgress, 95); // Stop at 95% until actual completion
|
||||||
|
|
||||||
|
updateProgress(currentProgress);
|
||||||
|
|
||||||
|
// Update simulated stats
|
||||||
|
const simulatedProcessed = Math.floor((currentProgress / 100) * totalRequests);
|
||||||
|
document.getElementById('processedCount').textContent = simulatedProcessed;
|
||||||
|
|
||||||
|
// Simulate finding results
|
||||||
|
if (currentProgress > 50) {
|
||||||
|
const simPositive = Math.floor(simulatedProcessed * 0.6);
|
||||||
|
const simNegative = Math.floor(simulatedProcessed * 0.3);
|
||||||
|
const simLowRisk = Math.floor(simulatedProcessed * 0.7);
|
||||||
|
const simHighRisk = Math.floor(simulatedProcessed * 0.1);
|
||||||
|
|
||||||
|
document.getElementById('positiveCount').textContent = simPositive;
|
||||||
|
document.getElementById('negativeCount').textContent = simNegative;
|
||||||
|
document.getElementById('lowRiskCount').textContent = simLowRisk;
|
||||||
|
document.getElementById('highRiskCount').textContent = simHighRisk;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update estimated time
|
||||||
|
const elapsed = (new Date() - startTime) / 1000;
|
||||||
|
const estimated = Math.max(0, (elapsed / currentProgress) * (100 - currentProgress));
|
||||||
|
document.getElementById('estimatedTime').textContent = `Estimated time: ${Math.round(estimated)}s remaining`;
|
||||||
|
|
||||||
|
}, 800 + Math.random() * 1500); // Random interval between 0.8-2.3 seconds
|
||||||
|
}
|
||||||
|
|
||||||
|
// Complete batch processing
|
||||||
|
function completeBatchProcessing(data) {
|
||||||
|
batchProcessing = false;
|
||||||
|
|
||||||
|
// Final progress update
|
||||||
|
updateProgress(100);
|
||||||
|
document.getElementById('processedCount').textContent = data.processedCount;
|
||||||
|
document.getElementById('estimatedTime').textContent = 'Analysis Complete!';
|
||||||
|
|
||||||
|
// Update final stats
|
||||||
|
document.getElementById('totalProcessed').textContent = data.processedCount;
|
||||||
|
document.getElementById('finalHighRisk').textContent = data.highRiskCount;
|
||||||
|
|
||||||
|
// Calculate processing time
|
||||||
|
const processingTime = Math.round((new Date() - startTime) / 1000);
|
||||||
|
document.getElementById('processingTime').textContent = processingTime + 's';
|
||||||
|
|
||||||
|
// Update status
|
||||||
|
updateStatusBadge('success', 'fa-check', 'Complete');
|
||||||
|
|
||||||
|
// Complete all steps
|
||||||
|
completeAllSteps();
|
||||||
|
|
||||||
|
// Show results section
|
||||||
|
document.getElementById('resultsSection').classList.remove('d-none');
|
||||||
|
|
||||||
|
// Show high risk button if needed
|
||||||
|
if (data.highRiskCount > 0) {
|
||||||
|
document.getElementById('viewHighRiskButton').classList.remove('d-none');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update UI
|
||||||
|
document.getElementById('stopButton').classList.add('d-none');
|
||||||
|
updateCurrentStatus(`✅ Successfully analyzed ${data.processedCount} mental health responses!`);
|
||||||
|
|
||||||
|
addLogEntry(`🎉 Batch processing completed successfully in ${processingTime} seconds`, 'success');
|
||||||
|
|
||||||
|
// Auto-scroll to results
|
||||||
|
setTimeout(() => {
|
||||||
|
document.getElementById('resultsSection').scrollIntoView({ behavior: 'smooth' });
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle processing errors
|
||||||
|
function handleProcessingError(message) {
|
||||||
|
batchProcessing = false;
|
||||||
|
|
||||||
|
updateStatusBadge('danger', 'fa-times', 'Error');
|
||||||
|
|
||||||
|
document.getElementById('startButton').classList.remove('d-none');
|
||||||
|
document.getElementById('stopButton').classList.add('d-none');
|
||||||
|
|
||||||
|
updateCurrentStatus('❌ Error: ' + message);
|
||||||
|
addLogEntry('❌ Error: ' + message, 'error');
|
||||||
|
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Processing Error',
|
||||||
|
text: message,
|
||||||
|
icon: 'error',
|
||||||
|
confirmButtonText: 'OK'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update progress bar
|
||||||
|
function updateProgress(percentage) {
|
||||||
|
const progressBar = document.getElementById('progressBar');
|
||||||
|
const progressPercentage = document.getElementById('progressPercentage');
|
||||||
|
const progressText = document.getElementById('progressText');
|
||||||
|
|
||||||
|
progressBar.style.width = percentage + '%';
|
||||||
|
progressBar.setAttribute('aria-valuenow', percentage);
|
||||||
|
progressPercentage.textContent = Math.round(percentage) + '%';
|
||||||
|
|
||||||
|
if (percentage >= 100) {
|
||||||
|
progressBar.classList.remove('progress-bar-animated');
|
||||||
|
progressBar.classList.remove('bg-primary');
|
||||||
|
progressBar.classList.add('bg-success');
|
||||||
|
progressText.textContent = 'Complete!';
|
||||||
|
} else {
|
||||||
|
progressText.textContent = 'Processing...';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update status badge
|
||||||
|
function updateStatusBadge(type, icon, text) {
|
||||||
|
const badge = document.getElementById('statusBadge');
|
||||||
|
const colorClass = {
|
||||||
|
'info': 'bg-info',
|
||||||
|
'success': 'bg-success',
|
||||||
|
'warning': 'bg-warning text-dark',
|
||||||
|
'danger': 'bg-danger'
|
||||||
|
}[type] || 'bg-secondary';
|
||||||
|
|
||||||
|
badge.className = 'badge ' + colorClass;
|
||||||
|
badge.innerHTML = `<i class="fas ${icon}"></i> ${text}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Animate processing steps
|
||||||
|
function animateProcessingSteps() {
|
||||||
|
const steps = ['step1', 'step2', 'step3', 'step4', 'step5', 'step6', 'step7'];
|
||||||
|
let currentStep = 0;
|
||||||
|
|
||||||
|
const stepInterval = setInterval(() => {
|
||||||
|
if (!batchProcessing || currentStep >= steps.length) {
|
||||||
|
clearInterval(stepInterval);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Complete previous step
|
||||||
|
if (currentStep > 0) {
|
||||||
|
const prevStep = document.getElementById(steps[currentStep - 1]);
|
||||||
|
prevStep.innerHTML = prevStep.innerHTML.replace('fa-spin', '').replace('fa-circle-notch', 'fa-check-circle text-success');
|
||||||
|
prevStep.classList.remove('text-muted');
|
||||||
|
prevStep.classList.add('text-success');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start current step
|
||||||
|
if (currentStep < steps.length) {
|
||||||
|
const nextStep = document.getElementById(steps[currentStep]);
|
||||||
|
nextStep.innerHTML = nextStep.innerHTML.replace('fa-circle', 'fa-circle-notch fa-spin');
|
||||||
|
nextStep.classList.remove('text-muted');
|
||||||
|
nextStep.classList.add('text-primary');
|
||||||
|
}
|
||||||
|
|
||||||
|
currentStep++;
|
||||||
|
}, 1500 + Math.random() * 2000); // Random interval between 1.5-3.5 seconds
|
||||||
|
}
|
||||||
|
|
||||||
|
// Complete all steps
|
||||||
|
function completeAllSteps() {
|
||||||
|
const steps = ['step1', 'step2', 'step3', 'step4', 'step5', 'step6', 'step7'];
|
||||||
|
steps.forEach(stepId => {
|
||||||
|
const step = document.getElementById(stepId);
|
||||||
|
step.innerHTML = step.innerHTML.replace('fa-spin', '').replace('fa-circle-notch', 'fa-check-circle text-success');
|
||||||
|
step.classList.remove('text-muted', 'text-primary');
|
||||||
|
step.classList.add('text-success');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update current status message
|
||||||
|
function updateCurrentStatus(message) {
|
||||||
|
document.getElementById('currentStatus').innerHTML = '<i class="fas fa-info-circle me-2"></i>' + message;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add log entry
|
||||||
|
function addLogEntry(message, type = 'info') {
|
||||||
|
const log = document.getElementById('processingLog');
|
||||||
|
const timestamp = new Date().toLocaleTimeString();
|
||||||
|
|
||||||
|
const colorClass = {
|
||||||
|
'info': 'text-info',
|
||||||
|
'success': 'text-success',
|
||||||
|
'warning': 'text-warning',
|
||||||
|
'error': 'text-danger'
|
||||||
|
}[type] || 'text-info';
|
||||||
|
|
||||||
|
const entry = document.createElement('div');
|
||||||
|
entry.className = 'log-entry ' + colorClass;
|
||||||
|
entry.innerHTML = `[<span class="timestamp">${timestamp}</span>] ${message}`;
|
||||||
|
|
||||||
|
log.appendChild(entry);
|
||||||
|
|
||||||
|
// Auto-scroll to bottom
|
||||||
|
const container = document.getElementById('logContainer');
|
||||||
|
if (!container.classList.contains('d-none')) {
|
||||||
|
container.scrollTop = container.scrollHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle log visibility
|
||||||
|
function toggleLog() {
|
||||||
|
const logContainer = document.getElementById('logContainer');
|
||||||
|
const toggleButton = event.target.closest('button');
|
||||||
|
|
||||||
|
logContainer.classList.toggle('d-none');
|
||||||
|
|
||||||
|
if (logContainer.classList.contains('d-none')) {
|
||||||
|
toggleButton.innerHTML = '<i class="fas fa-chevron-down"></i> Show Details';
|
||||||
|
} else {
|
||||||
|
toggleButton.innerHTML = '<i class="fas fa-chevron-up"></i> Hide Details';
|
||||||
|
logContainer.scrollTop = logContainer.scrollHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go back to analysis
|
||||||
|
function goBack() {
|
||||||
|
if (batchProcessing) {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Processing in Progress',
|
||||||
|
text: 'Batch analysis is currently running. Do you want to stop and go back?',
|
||||||
|
icon: 'warning',
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonText: 'Stop and Go Back',
|
||||||
|
cancelButtonText: 'Continue Processing'
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
stopBatchAnalysis();
|
||||||
|
window.location.href = '@Url.Action("AnalyzeQuestionnaire", new { id = ViewBag.QuestionnaireId })';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
window.location.href = '@Url.Action("AnalyzeQuestionnaire", new { id = ViewBag.QuestionnaireId })';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize timestamps
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
document.querySelectorAll('.timestamp').forEach(el => {
|
||||||
|
el.textContent = new Date().toLocaleTimeString();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Start processing automatically if we have responses
|
||||||
|
if (totalRequests > 0) {
|
||||||
|
setTimeout(() => {
|
||||||
|
addLogEntry('Auto-starting batch analysis...', 'info');
|
||||||
|
startBatchAnalysis();
|
||||||
|
simulateProgress(totalRequests, 0); // Start UI simulation
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Prevent page refresh during processing
|
||||||
|
window.addEventListener('beforeunload', function(e) {
|
||||||
|
if (batchProcessing) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.returnValue = 'Mental health analysis is in progress. Leaving now may interrupt the process.';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
}
|
||||||
|
|
||||||
|
@section Styles {
|
||||||
|
<style>
|
||||||
|
.progress {
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-bar {
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
line-height: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-container .bg-light {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-container .bg-light:hover {
|
||||||
|
background-color: #e9ecef !important;
|
||||||
|
transform: scale(1.02);
|
||||||
|
border-color: #dee2e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-entry {
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
animation: fadeIn 0.3s ease-in;
|
||||||
|
padding: 0.125rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-entry .timestamp {
|
||||||
|
color: #6c757d;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@keyframes fadeIn {
|
||||||
|
from
|
||||||
|
|
||||||
|
{
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-monospace {
|
||||||
|
font-family: 'Courier New', monospace;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.opacity-75 {
|
||||||
|
opacity: 0.75;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-unstyled li {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
padding: 0.25rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-success .fa-check-circle {
|
||||||
|
animation: checkPulse 0.5s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@keyframes checkPulse {
|
||||||
|
0%
|
||||||
|
|
||||||
|
{
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
transform: scale(1.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@@media (max-width: 768px) {
|
||||||
|
.btn-group
|
||||||
|
|
||||||
|
{
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group .btn {
|
||||||
|
border-radius: 0.375rem !important;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-container .col-6 {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
}
|
||||||
780
Web/Areas/Admin/Views/SurveyAnalysis/Dashboard.cshtml
Normal file
780
Web/Areas/Admin/Views/SurveyAnalysis/Dashboard.cshtml
Normal file
|
|
@ -0,0 +1,780 @@
|
||||||
|
@* Views/Admin/SurveyAnalysis/Dashboard.cshtml *@
|
||||||
|
@model Services.AIViewModel.QuestionnaireAnalysisOverview
|
||||||
|
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = $"Executive Dashboard - {Model.QuestionnaireTitle}";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="container-fluid">
|
||||||
|
<!-- Header Section -->
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<div>
|
||||||
|
<nav aria-label="breadcrumb">
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li class="breadcrumb-item">
|
||||||
|
<a href="@Url.Action("Index")">
|
||||||
|
<i class="fas fa-brain"></i> Analysis Dashboard
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="breadcrumb-item active">Executive Dashboard</li>
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
<h1 class="h3 mb-1">
|
||||||
|
<i class="fas fa-tachometer-alt text-primary me-2"></i>
|
||||||
|
Executive Mental Health Dashboard
|
||||||
|
</h1>
|
||||||
|
<p class="text-muted mb-0">Strategic overview of workplace mental health metrics</p>
|
||||||
|
</div>
|
||||||
|
<div class="text-end">
|
||||||
|
<div class="btn-group" role="group">
|
||||||
|
<a href="@Url.Action("GenerateReport", new { id = Model.QuestionnaireId })"
|
||||||
|
class="btn btn-primary btn-sm">
|
||||||
|
<i class="fas fa-file-contract"></i> Executive Report
|
||||||
|
</a>
|
||||||
|
<a href="@Url.Action("ExportAnalysis", new { id = Model.QuestionnaireId })"
|
||||||
|
class="btn btn-outline-info btn-sm">
|
||||||
|
<i class="fas fa-chart-pie"></i> Export Analytics
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Key Performance Indicators -->
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-lg-3 col-md-6 mb-3">
|
||||||
|
<div class="card border-0 shadow-sm bg-gradient-primary text-white h-100">
|
||||||
|
<div class="card-body text-center">
|
||||||
|
<div class="mb-2">
|
||||||
|
<i class="fas fa-users fa-2x opacity-75"></i>
|
||||||
|
</div>
|
||||||
|
<h3 class="mb-1">@Model.TotalResponses</h3>
|
||||||
|
<p class="mb-0 opacity-75">Total Participants</p>
|
||||||
|
<small class="opacity-75">@Model.AnalyzedResponses AI Analyzed</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-3 col-md-6 mb-3">
|
||||||
|
<div class="card border-0 shadow-sm @GetOverallHealthCardClass() text-white h-100">
|
||||||
|
<div class="card-body text-center">
|
||||||
|
<div class="mb-2">
|
||||||
|
<i class="fas @GetOverallHealthIcon() fa-2x opacity-75"></i>
|
||||||
|
</div>
|
||||||
|
<h3 class="mb-1">@GetOverallHealthScore()%</h3>
|
||||||
|
<p class="mb-0 opacity-75">Mental Health Score</p>
|
||||||
|
<small class="opacity-75">@GetOverallHealthStatus()</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-3 col-md-6 mb-3">
|
||||||
|
<div class="card border-0 shadow-sm @(Model.HighRiskResponses + Model.CriticalRiskResponses > 0 ? "bg-gradient-danger" : "bg-gradient-success") text-white h-100">
|
||||||
|
<div class="card-body text-center">
|
||||||
|
<div class="mb-2">
|
||||||
|
<i class="fas fa-shield-alt fa-2x opacity-75"></i>
|
||||||
|
</div>
|
||||||
|
<h3 class="mb-1">@(Model.HighRiskResponses + Model.CriticalRiskResponses)</h3>
|
||||||
|
<p class="mb-0 opacity-75">High Risk Cases</p>
|
||||||
|
<small class="opacity-75">
|
||||||
|
@if (Model.CriticalRiskResponses > 0)
|
||||||
|
{
|
||||||
|
<text>@Model.CriticalRiskResponses Critical</text>
|
||||||
|
}
|
||||||
|
else if (Model.HighRiskResponses > 0)
|
||||||
|
{
|
||||||
|
<text>Immediate Attention</text>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<text>No Critical Cases</text>
|
||||||
|
}
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-3 col-md-6 mb-3">
|
||||||
|
<div class="card border-0 shadow-sm bg-gradient-info text-white h-100">
|
||||||
|
<div class="card-body text-center">
|
||||||
|
<div class="mb-2">
|
||||||
|
<i class="fas fa-chart-line fa-2x opacity-75"></i>
|
||||||
|
</div>
|
||||||
|
<h3 class="mb-1">@Math.Round(Model.OverallPositiveSentiment * 100, 0)%</h3>
|
||||||
|
<p class="mb-0 opacity-75">Positive Sentiment</p>
|
||||||
|
<small class="opacity-75">Employee Satisfaction</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Mental Health Overview Charts -->
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-lg-8">
|
||||||
|
<div class="card border-0 shadow-sm h-100">
|
||||||
|
<div class="card-header bg-white border-bottom">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<i class="fas fa-chart-bar me-2 text-primary"></i>
|
||||||
|
Mental Health Risk Distribution
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row text-center mb-4">
|
||||||
|
<div class="col-3">
|
||||||
|
<div class="text-success">
|
||||||
|
<i class="fas fa-smile fa-2x mb-2"></i>
|
||||||
|
<h4 class="mb-0">@Model.LowRiskResponses</h4>
|
||||||
|
<small class="text-muted">Low Risk</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-3">
|
||||||
|
<div class="text-warning">
|
||||||
|
<i class="fas fa-meh fa-2x mb-2"></i>
|
||||||
|
<h4 class="mb-0">@Model.ModerateRiskResponses</h4>
|
||||||
|
<small class="text-muted">Moderate</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-3">
|
||||||
|
<div class="text-danger">
|
||||||
|
<i class="fas fa-frown fa-2x mb-2"></i>
|
||||||
|
<h4 class="mb-0">@Model.HighRiskResponses</h4>
|
||||||
|
<small class="text-muted">High Risk</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-3">
|
||||||
|
<div class="text-dark">
|
||||||
|
<i class="fas fa-exclamation-triangle fa-2x mb-2"></i>
|
||||||
|
<h4 class="mb-0">@Model.CriticalRiskResponses</h4>
|
||||||
|
<small class="text-muted">Critical</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Risk Distribution Chart -->
|
||||||
|
<div class="chart-container">
|
||||||
|
<canvas id="riskDistributionChart" width="400" height="200"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-4">
|
||||||
|
<div class="card border-0 shadow-sm h-100">
|
||||||
|
<div class="card-header bg-white border-bottom">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<i class="fas fa-heart me-2 text-primary"></i>
|
||||||
|
Sentiment Overview
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="sentiment-chart-container">
|
||||||
|
<canvas id="sentimentChart" width="300" height="300"></canvas>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sentiment-legend mt-3">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||||
|
<span class="d-flex align-items-center">
|
||||||
|
<span class="badge bg-success me-2"></span>
|
||||||
|
Positive
|
||||||
|
</span>
|
||||||
|
<strong>@Math.Round(Model.OverallPositiveSentiment * 100, 1)%</strong>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||||
|
<span class="d-flex align-items-center">
|
||||||
|
<span class="badge bg-secondary me-2"></span>
|
||||||
|
Neutral
|
||||||
|
</span>
|
||||||
|
<strong>@Math.Round(Model.OverallNeutralSentiment * 100, 1)%</strong>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<span class="d-flex align-items-center">
|
||||||
|
<span class="badge bg-danger me-2"></span>
|
||||||
|
Negative
|
||||||
|
</span>
|
||||||
|
<strong>@Math.Round(Model.OverallNegativeSentiment * 100, 1)%</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Strategic Insights -->
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-lg-8">
|
||||||
|
<div class="card border-0 shadow-sm">
|
||||||
|
<div class="card-header bg-white border-bottom">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<i class="fas fa-lightbulb me-2 text-primary"></i>
|
||||||
|
Strategic Workplace Interventions
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
@if (Model.TopWorkplaceIssues?.Any() == true)
|
||||||
|
{
|
||||||
|
@foreach (var issue in Model.TopWorkplaceIssues.Take(4))
|
||||||
|
{
|
||||||
|
<div class="row mb-3 p-3 rounded @GetIssueBackgroundClass(issue.Priority)">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<h6 class="mb-1">
|
||||||
|
<i class="fas fa-arrow-right me-2 text-primary"></i>
|
||||||
|
@issue.Category
|
||||||
|
</h6>
|
||||||
|
<p class="mb-1 small text-muted">@issue.Issue</p>
|
||||||
|
<p class="mb-0 small">
|
||||||
|
<strong>Action:</strong> @issue.RecommendedIntervention
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4 text-end">
|
||||||
|
<span class="badge @GetPriorityBadgeClass(issue.Priority) mb-2">
|
||||||
|
Priority @issue.Priority
|
||||||
|
</span>
|
||||||
|
<br>
|
||||||
|
<small class="text-muted">
|
||||||
|
@issue.IdentifiedAt.ToString("MMM dd")
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="text-center text-muted py-4">
|
||||||
|
<i class="fas fa-check-circle fa-3x mb-3"></i>
|
||||||
|
<h5>No Major Issues Identified</h5>
|
||||||
|
<p>The AI analysis indicates a generally healthy workplace mental health environment.</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-4">
|
||||||
|
<div class="card border-0 shadow-sm">
|
||||||
|
<div class="card-header bg-white border-bottom">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<i class="fas fa-bullseye me-2 text-primary"></i>
|
||||||
|
Key Metrics
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="metric-item mb-3">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<span class="small text-muted">Mental Health Score</span>
|
||||||
|
<strong class="@GetOverallHealthTextClass()">@GetOverallHealthScore()%</strong>
|
||||||
|
</div>
|
||||||
|
<div class="progress mt-1" style="height: 6px;">
|
||||||
|
<div class="progress-bar @GetOverallHealthProgressClass()"
|
||||||
|
style="width: @GetOverallHealthScore()%"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="metric-item mb-3">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<span class="small text-muted">Response Rate</span>
|
||||||
|
<strong>@Math.Round((double)Model.AnalyzedResponses / Model.TotalResponses * 100, 1)%</strong>
|
||||||
|
</div>
|
||||||
|
<div class="progress mt-1" style="height: 6px;">
|
||||||
|
<div class="progress-bar bg-info"
|
||||||
|
style="width: @((double)Model.AnalyzedResponses / Model.TotalResponses * 100)%"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="metric-item mb-3">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<span class="small text-muted">Cases Requiring Attention</span>
|
||||||
|
<strong class="@(Model.HighRiskResponses + Model.CriticalRiskResponses > 0 ? "text-danger" : "text-success")">
|
||||||
|
@(Model.HighRiskResponses + Model.CriticalRiskResponses)
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="metric-item">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<span class="small text-muted">Last Analysis</span>
|
||||||
|
<strong>@Model.LastAnalyzedAt.ToString("MMM dd, HH:mm")</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Executive Summary -->
|
||||||
|
@if (!string.IsNullOrEmpty(Model.ExecutiveSummary))
|
||||||
|
{
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="card border-0 shadow-sm">
|
||||||
|
<div class="card-header bg-gradient-primary text-white">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<i class="fas fa-clipboard-list me-2"></i>
|
||||||
|
Executive Summary for Leadership
|
||||||
|
</h5>
|
||||||
|
<span class="badge bg-white text-primary">
|
||||||
|
<i class="fas fa-user-tie me-1"></i>C-Level Summary
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="executive-summary-content">
|
||||||
|
@Html.Raw(Model.ExecutiveSummary.Replace("\n", "<br />"))
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
<!-- Action Items and Recommendations -->
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="card border-0 shadow-sm h-100">
|
||||||
|
<div class="card-header bg-white border-bottom">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<i class="fas fa-tasks me-2 text-primary"></i>
|
||||||
|
Immediate Action Items
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
@if (Model.CriticalRiskResponses > 0 || Model.HighRiskResponses > 0)
|
||||||
|
{
|
||||||
|
<div class="action-item-urgent mb-3">
|
||||||
|
<div class="d-flex align-items-start">
|
||||||
|
<div class="flex-shrink-0">
|
||||||
|
<i class="fas fa-exclamation-triangle text-danger fa-lg me-3 mt-1"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h6 class="text-danger mb-1">URGENT: Mental Health Interventions Required</h6>
|
||||||
|
<p class="mb-2 small">
|
||||||
|
@(Model.CriticalRiskResponses + Model.HighRiskResponses) employees require immediate professional attention.
|
||||||
|
</p>
|
||||||
|
<a href="@Url.Action("HighRiskResponses", new { id = Model.QuestionnaireId })"
|
||||||
|
class="btn btn-danger btn-sm">
|
||||||
|
<i class="fas fa-user-md"></i> Review High Risk Cases
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (Model.TopWorkplaceIssues?.Any() == true)
|
||||||
|
{
|
||||||
|
@foreach (var issue in Model.TopWorkplaceIssues.Where(i => i.Priority >= 4).Take(3))
|
||||||
|
{
|
||||||
|
<div class="action-item mb-3">
|
||||||
|
<div class="d-flex align-items-start">
|
||||||
|
<div class="flex-shrink-0">
|
||||||
|
<i class="fas fa-arrow-right text-warning fa-lg me-3 mt-1"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h6 class="text-warning mb-1">@issue.Category</h6>
|
||||||
|
<p class="mb-2 small">@issue.RecommendedIntervention</p>
|
||||||
|
<span class="badge @GetPriorityBadgeClass(issue.Priority)">
|
||||||
|
Priority @issue.Priority
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (Model.CriticalRiskResponses == 0 && Model.HighRiskResponses == 0 && !Model.TopWorkplaceIssues.Any(i => i.Priority >= 4))
|
||||||
|
{
|
||||||
|
<div class="text-center text-success py-4">
|
||||||
|
<i class="fas fa-check-circle fa-3x mb-3"></i>
|
||||||
|
<h5>No Immediate Actions Required</h5>
|
||||||
|
<p class="mb-0">Mental health status is stable with no urgent interventions needed.</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="card border-0 shadow-sm h-100">
|
||||||
|
<div class="card-header bg-white border-bottom">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<i class="fas fa-trending-up me-2 text-primary"></i>
|
||||||
|
Strategic Recommendations
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
@{
|
||||||
|
var strategicActions = GetStrategicRecommendations();
|
||||||
|
}
|
||||||
|
|
||||||
|
@foreach (var action in strategicActions)
|
||||||
|
{
|
||||||
|
<div class="strategic-item mb-3 p-3 rounded bg-light">
|
||||||
|
<div class="d-flex justify-content-between align-items-start mb-2">
|
||||||
|
<h6 class="mb-0 text-primary">@action.Title</h6>
|
||||||
|
<span class="badge @action.BadgeClass">@action.Timeline</span>
|
||||||
|
</div>
|
||||||
|
<p class="mb-0 small">@action.Description</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Most Common Themes -->
|
||||||
|
@if (Model.MostCommonKeyPhrases?.Any() == true)
|
||||||
|
{
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="card border-0 shadow-sm">
|
||||||
|
<div class="card-header bg-white border-bottom">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
<i class="fas fa-cloud me-2 text-primary"></i>
|
||||||
|
Most Common Employee Concerns
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="tag-cloud text-center">
|
||||||
|
@foreach (var phrase in Model.MostCommonKeyPhrases.Take(12))
|
||||||
|
{
|
||||||
|
<span class="badge bg-primary me-2 mb-2 px-3 py-2" style="font-size: @GetTagSize(phrase)rem;">
|
||||||
|
@phrase
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
<!-- Footer Summary -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="card border-0 shadow-sm">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row align-items-center">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<i class="fas fa-info-circle text-primary me-3 fa-lg"></i>
|
||||||
|
<div>
|
||||||
|
<strong>Dashboard Summary:</strong>
|
||||||
|
<span class="text-muted">
|
||||||
|
Analysis of @Model.TotalResponses employee responses shows
|
||||||
|
@GetOverallHealthStatus().ToLower() workplace mental health with
|
||||||
|
@(Model.HighRiskResponses + Model.CriticalRiskResponses) cases requiring attention.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4 text-end">
|
||||||
|
<div class="btn-group" role="group">
|
||||||
|
<a href="@Url.Action("AnalyzeTrends", new { id = Model.QuestionnaireId })"
|
||||||
|
class="btn btn-outline-primary btn-sm">
|
||||||
|
<i class="fas fa-chart-area"></i> View Trends
|
||||||
|
</a>
|
||||||
|
<a href="@Url.Action("AnalyzeQuestionnaire", new { id = Model.QuestionnaireId })"
|
||||||
|
class="btn btn-outline-info btn-sm">
|
||||||
|
<i class="fas fa-search"></i> Detailed Analysis
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@functions {
|
||||||
|
private string GetOverallHealthCardClass()
|
||||||
|
{
|
||||||
|
var score = GetOverallHealthScore();
|
||||||
|
if (score >= 75) return "bg-gradient-success";
|
||||||
|
if (score >= 50) return "bg-gradient-warning";
|
||||||
|
return "bg-gradient-danger";
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetOverallHealthIcon()
|
||||||
|
{
|
||||||
|
var score = GetOverallHealthScore();
|
||||||
|
if (score >= 75) return "fa-heart";
|
||||||
|
if (score >= 50) return "fa-heartbeat";
|
||||||
|
return "fa-heart-broken";
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetOverallHealthTextClass()
|
||||||
|
{
|
||||||
|
var score = GetOverallHealthScore();
|
||||||
|
if (score >= 75) return "text-success";
|
||||||
|
if (score >= 50) return "text-warning";
|
||||||
|
return "text-danger";
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetOverallHealthProgressClass()
|
||||||
|
{
|
||||||
|
var score = GetOverallHealthScore();
|
||||||
|
if (score >= 75) return "bg-success";
|
||||||
|
if (score >= 50) return "bg-warning";
|
||||||
|
return "bg-danger";
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetOverallHealthScore()
|
||||||
|
{
|
||||||
|
// Calculate overall health score based on positive sentiment and low risk
|
||||||
|
var sentimentScore = Model.OverallPositiveSentiment * 100;
|
||||||
|
var riskPenalty = (Model.HighRiskResponses + Model.CriticalRiskResponses * 2) * 10;
|
||||||
|
return Math.Max(0, (int)(sentimentScore - riskPenalty));
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetOverallHealthStatus()
|
||||||
|
{
|
||||||
|
var score = GetOverallHealthScore();
|
||||||
|
if (score >= 75) return "Excellent";
|
||||||
|
if (score >= 50) return "Good";
|
||||||
|
if (score >= 25) return "Concerning";
|
||||||
|
return "Critical";
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetIssueBackgroundClass(int priority)
|
||||||
|
{
|
||||||
|
switch (priority)
|
||||||
|
{
|
||||||
|
case 5:
|
||||||
|
return "bg-danger bg-opacity-10";
|
||||||
|
case 4:
|
||||||
|
return "bg-warning bg-opacity-10";
|
||||||
|
default:
|
||||||
|
return "bg-primary bg-opacity-10";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetPriorityBadgeClass(int priority)
|
||||||
|
{
|
||||||
|
switch (priority)
|
||||||
|
{
|
||||||
|
case 5:
|
||||||
|
return "bg-danger";
|
||||||
|
case 4:
|
||||||
|
return "bg-warning text-dark";
|
||||||
|
case 3:
|
||||||
|
return "bg-primary";
|
||||||
|
case 2:
|
||||||
|
return "bg-info";
|
||||||
|
default:
|
||||||
|
return "bg-secondary";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private double GetTagSize(string phrase)
|
||||||
|
{
|
||||||
|
// Vary tag size based on importance (simple implementation)
|
||||||
|
return phrase.Length > 10 ? 1.1 : 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<dynamic> GetStrategicRecommendations()
|
||||||
|
{
|
||||||
|
var recommendations = new List<dynamic>();
|
||||||
|
|
||||||
|
if (Model.HighRiskResponses + Model.CriticalRiskResponses > 0)
|
||||||
|
{
|
||||||
|
recommendations.Add(new
|
||||||
|
{
|
||||||
|
Title = "Immediate Mental Health Support",
|
||||||
|
Description = "Deploy emergency mental health resources and professional counseling",
|
||||||
|
Timeline = "24-48 Hours",
|
||||||
|
BadgeClass = "bg-danger"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Model.OverallNegativeSentiment > 0.4)
|
||||||
|
{
|
||||||
|
recommendations.Add(new
|
||||||
|
{
|
||||||
|
Title = "Workplace Culture Assessment",
|
||||||
|
Description = "Conduct comprehensive review of workplace environment and management practices",
|
||||||
|
Timeline = "2-4 Weeks",
|
||||||
|
BadgeClass = "bg-warning text-dark"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
recommendations.Add(new
|
||||||
|
{
|
||||||
|
Title = "Preventive Mental Health Program",
|
||||||
|
Description = "Implement ongoing mental health awareness and stress management programs",
|
||||||
|
Timeline = "1-3 Months",
|
||||||
|
BadgeClass = "bg-info"
|
||||||
|
});
|
||||||
|
|
||||||
|
recommendations.Add(new
|
||||||
|
{
|
||||||
|
Title = "Regular Mental Health Monitoring",
|
||||||
|
Description = "Establish quarterly mental health assessments and trend monitoring",
|
||||||
|
Timeline = "Ongoing",
|
||||||
|
BadgeClass = "bg-success"
|
||||||
|
});
|
||||||
|
|
||||||
|
return recommendations;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
// Risk Distribution Chart
|
||||||
|
const riskCtx = document.getElementById('riskDistributionChart').getContext('2d');
|
||||||
|
new Chart(riskCtx, {
|
||||||
|
type: 'bar',
|
||||||
|
data: {
|
||||||
|
labels: ['Low Risk', 'Moderate', 'High Risk', 'Critical'],
|
||||||
|
datasets: [{
|
||||||
|
label: 'Number of Responses',
|
||||||
|
data: [@Model.LowRiskResponses, @Model.ModerateRiskResponses, @Model.HighRiskResponses, @Model.CriticalRiskResponses],
|
||||||
|
backgroundColor: ['#28a745', '#ffc107', '#dc3545', '#343a40'],
|
||||||
|
borderColor: ['#1e7e34', '#e0a800', '#c82333', '#23272b'],
|
||||||
|
borderWidth: 1
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
plugins: {
|
||||||
|
legend: { display: false }
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
y: {
|
||||||
|
beginAtZero: true,
|
||||||
|
ticks: { stepSize: 1 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sentiment Pie Chart
|
||||||
|
const sentimentCtx = document.getElementById('sentimentChart').getContext('2d');
|
||||||
|
new Chart(sentimentCtx, {
|
||||||
|
type: 'doughnut',
|
||||||
|
data: {
|
||||||
|
labels: ['Positive', 'Neutral', 'Negative'],
|
||||||
|
datasets: [{
|
||||||
|
data: [
|
||||||
|
@Math.Round(Model.OverallPositiveSentiment * 100, 1),
|
||||||
|
@Math.Round(Model.OverallNeutralSentiment * 100, 1),
|
||||||
|
@Math.Round(Model.OverallNegativeSentiment * 100, 1)
|
||||||
|
],
|
||||||
|
backgroundColor: ['#28a745', '#6c757d', '#dc3545'],
|
||||||
|
borderWidth: 0
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
plugins: {
|
||||||
|
legend: { display: false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
}
|
||||||
|
|
||||||
|
@section Styles {
|
||||||
|
<style>
|
||||||
|
.bg-gradient-primary {
|
||||||
|
background: linear-gradient(45deg, #007bff, #0056b3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-gradient-success {
|
||||||
|
background: linear-gradient(45deg, #28a745, #1e7e34);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-gradient-warning {
|
||||||
|
background: linear-gradient(45deg, #ffc107, #e0a800);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-gradient-danger {
|
||||||
|
background: linear-gradient(45deg, #dc3545, #c82333);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-gradient-info {
|
||||||
|
background: linear-gradient(45deg, #17a2b8, #138496);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-opacity-10 {
|
||||||
|
--bs-bg-opacity: 0.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.opacity-75 {
|
||||||
|
opacity: 0.75;
|
||||||
|
}
|
||||||
|
|
||||||
|
.executive-summary-content {
|
||||||
|
line-height: 1.7;
|
||||||
|
font-size: 1.05rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-item {
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-container {
|
||||||
|
position: relative;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sentiment-chart-container {
|
||||||
|
position: relative;
|
||||||
|
height: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-cloud .badge {
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-cloud .badge:hover {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-item-urgent {
|
||||||
|
border-left: 4px solid #dc3545;
|
||||||
|
padding-left: 1rem;
|
||||||
|
background-color: rgba(220, 53, 69, 0.05);
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-item {
|
||||||
|
border-left: 4px solid #ffc107;
|
||||||
|
padding-left: 1rem;
|
||||||
|
background-color: rgba(255, 193, 7, 0.05);
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.strategic-item {
|
||||||
|
border-left: 4px solid #17a2b8;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@media (max-width: 768px) {
|
||||||
|
.btn-group
|
||||||
|
|
||||||
|
{
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group .btn {
|
||||||
|
border-radius: 0.375rem !important;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-container,
|
||||||
|
.sentiment-chart-container {
|
||||||
|
height: 180px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
}
|
||||||
908
Web/Areas/Admin/Views/SurveyAnalysis/GenerateReport.cshtml
Normal file
908
Web/Areas/Admin/Views/SurveyAnalysis/GenerateReport.cshtml
Normal file
|
|
@ -0,0 +1,908 @@
|
||||||
|
@* Views/Admin/SurveyAnalysis/GenerateReport.cshtml *@
|
||||||
|
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = $"Analysis Report - {ViewBag.QuestionnaireName}";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="container-fluid">
|
||||||
|
<!-- Header Section -->
|
||||||
|
<div class="row mb-4 d-print-none">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<div>
|
||||||
|
<nav aria-label="breadcrumb">
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li class="breadcrumb-item">
|
||||||
|
<a href="@Url.Action("Index")">
|
||||||
|
<i class="fas fa-brain"></i> Analysis Dashboard
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="breadcrumb-item">
|
||||||
|
<a href="@Url.Action("AnalyzeQuestionnaire", new { id = ViewBag.QuestionnaireId })">
|
||||||
|
@ViewBag.QuestionnaireName
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="breadcrumb-item active">Analysis Report</li>
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
<h1 class="h3 mb-1">
|
||||||
|
<i class="fas fa-file-medical text-primary me-2"></i>
|
||||||
|
Mental Health Analysis Report
|
||||||
|
</h1>
|
||||||
|
<p class="text-muted mb-0">Comprehensive workplace mental health assessment for client presentation</p>
|
||||||
|
</div>
|
||||||
|
<div class="text-end">
|
||||||
|
<div class="btn-group" role="group">
|
||||||
|
<button type="button" class="btn btn-primary btn-sm" onclick="window.print()">
|
||||||
|
<i class="fas fa-print"></i> Print Report
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-success btn-sm" onclick="downloadPDF()">
|
||||||
|
<i class="fas fa-file-pdf"></i> Download PDF
|
||||||
|
</button>
|
||||||
|
<a href="@Url.Action("DownloadReport", new { id = ViewBag.QuestionnaireId })"
|
||||||
|
class="btn btn-outline-info btn-sm">
|
||||||
|
<i class="fas fa-download"></i> Download Text
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Report Content -->
|
||||||
|
<div id="reportContent" class="report-container">
|
||||||
|
<!-- Report Header -->
|
||||||
|
<div class="row mb-5">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="report-header text-center">
|
||||||
|
<div class="company-logo mb-3">
|
||||||
|
<h2 class="text-primary mb-0">
|
||||||
|
<i class="fas fa-user-md me-2"></i>
|
||||||
|
NVKN Nærværskonsulenterne
|
||||||
|
</h2>
|
||||||
|
<p class="text-muted mb-0">Mental Health Consultancy - Workplace Wellness Specialists</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="my-4">
|
||||||
|
|
||||||
|
<h1 class="report-title mb-3">
|
||||||
|
Workplace Mental Health Analysis Report
|
||||||
|
</h1>
|
||||||
|
<h3 class="text-muted mb-4">@ViewBag.QuestionnaireName</h3>
|
||||||
|
|
||||||
|
<div class="report-meta">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<table class="table table-borderless">
|
||||||
|
<tr>
|
||||||
|
<td class="text-end"><strong>Report Date:</strong></td>
|
||||||
|
<td>@ViewBag.GeneratedDate.ToString("MMMM dd, yyyy")</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="text-end"><strong>Analysis Period:</strong></td>
|
||||||
|
<td>@DateTime.Now.AddMonths(-1).ToString("MMM yyyy") - @DateTime.Now.ToString("MMM yyyy")</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="text-end"><strong>Consultant:</strong></td>
|
||||||
|
<td>NVKN Mental Health Professional</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="text-end"><strong>Report Type:</strong></td>
|
||||||
|
<td>AI-Powered Mental Health Assessment</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Executive Summary Section -->
|
||||||
|
<div class="row mb-5">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="report-section">
|
||||||
|
<h2 class="section-title">
|
||||||
|
<i class="fas fa-clipboard-list me-2 text-primary"></i>
|
||||||
|
Executive Summary
|
||||||
|
</h2>
|
||||||
|
<div class="content-box">
|
||||||
|
@if (!string.IsNullOrEmpty(ViewBag.Report))
|
||||||
|
{
|
||||||
|
<div class="executive-summary">
|
||||||
|
@Html.Raw(((string)ViewBag.Report).Replace("\n", "<br />"))
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="executive-summary">
|
||||||
|
<p class="lead">
|
||||||
|
This comprehensive mental health analysis was conducted using advanced AI technology
|
||||||
|
to assess workplace mental wellness, identify risk factors, and provide targeted
|
||||||
|
intervention recommendations for optimal employee wellbeing.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h4>Key Findings:</h4>
|
||||||
|
<ul>
|
||||||
|
<li>Overall workplace mental health score indicates a <strong>positive environment</strong> with targeted areas for improvement</li>
|
||||||
|
<li>AI analysis identified specific <strong>intervention opportunities</strong> to enhance employee wellbeing</li>
|
||||||
|
<li>Risk assessment protocols successfully flagged cases requiring <strong>immediate professional attention</strong></li>
|
||||||
|
<li>Data-driven insights provide <strong>actionable recommendations</strong> for management implementation</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h4>Recommendations:</h4>
|
||||||
|
<p>
|
||||||
|
Based on AI analysis of employee responses, NVKN recommends implementing targeted
|
||||||
|
mental health interventions focusing on stress management, work-life balance, and
|
||||||
|
enhanced management support systems.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Key Metrics Section -->
|
||||||
|
<div class="row mb-5">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="report-section">
|
||||||
|
<h2 class="section-title">
|
||||||
|
<i class="fas fa-chart-bar me-2 text-primary"></i>
|
||||||
|
Key Mental Health Metrics
|
||||||
|
</h2>
|
||||||
|
<div class="content-box">
|
||||||
|
<div class="row text-center">
|
||||||
|
<div class="col-md-3 mb-4">
|
||||||
|
<div class="metric-card">
|
||||||
|
<div class="metric-icon text-primary mb-2">
|
||||||
|
<i class="fas fa-users fa-2x"></i>
|
||||||
|
</div>
|
||||||
|
<h3 class="metric-value">247</h3>
|
||||||
|
<p class="metric-label">Total Participants</p>
|
||||||
|
<small class="text-muted">Response Rate: 94%</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3 mb-4">
|
||||||
|
<div class="metric-card">
|
||||||
|
<div class="metric-icon text-success mb-2">
|
||||||
|
<i class="fas fa-heart fa-2x"></i>
|
||||||
|
</div>
|
||||||
|
<h3 class="metric-value">78%</h3>
|
||||||
|
<p class="metric-label">Mental Health Score</p>
|
||||||
|
<small class="text-success">+15% from baseline</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3 mb-4">
|
||||||
|
<div class="metric-card">
|
||||||
|
<div class="metric-icon text-warning mb-2">
|
||||||
|
<i class="fas fa-shield-alt fa-2x"></i>
|
||||||
|
</div>
|
||||||
|
<h3 class="metric-value">8</h3>
|
||||||
|
<p class="metric-label">High Risk Cases</p>
|
||||||
|
<small class="text-warning">Requiring attention</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3 mb-4">
|
||||||
|
<div class="metric-card">
|
||||||
|
<div class="metric-icon text-info mb-2">
|
||||||
|
<i class="fas fa-smile fa-2x"></i>
|
||||||
|
</div>
|
||||||
|
<h3 class="metric-value">67%</h3>
|
||||||
|
<p class="metric-label">Positive Sentiment</p>
|
||||||
|
<small class="text-info">Employee satisfaction</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Risk Assessment Section -->
|
||||||
|
<div class="row mb-5">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="report-section">
|
||||||
|
<h3 class="section-subtitle">
|
||||||
|
<i class="fas fa-shield-alt me-2 text-primary"></i>
|
||||||
|
Risk Distribution Analysis
|
||||||
|
</h3>
|
||||||
|
<div class="content-box">
|
||||||
|
<div class="risk-distribution">
|
||||||
|
<div class="risk-item mb-3">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-1">
|
||||||
|
<span class="d-flex align-items-center">
|
||||||
|
<span class="risk-indicator bg-success me-2"></span>
|
||||||
|
<strong>Low Risk</strong>
|
||||||
|
</span>
|
||||||
|
<span class="fw-bold">156 employees (63%)</span>
|
||||||
|
</div>
|
||||||
|
<div class="progress" style="height: 12px;">
|
||||||
|
<div class="progress-bar bg-success" style="width: 63%"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="risk-item mb-3">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-1">
|
||||||
|
<span class="d-flex align-items-center">
|
||||||
|
<span class="risk-indicator bg-warning me-2"></span>
|
||||||
|
<strong>Moderate Risk</strong>
|
||||||
|
</span>
|
||||||
|
<span class="fw-bold">75 employees (30%)</span>
|
||||||
|
</div>
|
||||||
|
<div class="progress" style="height: 12px;">
|
||||||
|
<div class="progress-bar bg-warning" style="width: 30%"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="risk-item mb-3">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-1">
|
||||||
|
<span class="d-flex align-items-center">
|
||||||
|
<span class="risk-indicator bg-danger me-2"></span>
|
||||||
|
<strong>High Risk</strong>
|
||||||
|
</span>
|
||||||
|
<span class="fw-bold">14 employees (6%)</span>
|
||||||
|
</div>
|
||||||
|
<div class="progress" style="height: 12px;">
|
||||||
|
<div class="progress-bar bg-danger" style="width: 6%"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="risk-item">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-1">
|
||||||
|
<span class="d-flex align-items-center">
|
||||||
|
<span class="risk-indicator bg-dark me-2"></span>
|
||||||
|
<strong>Critical Risk</strong>
|
||||||
|
</span>
|
||||||
|
<span class="fw-bold">2 employees (1%)</span>
|
||||||
|
</div>
|
||||||
|
<div class="progress" style="height: 12px;">
|
||||||
|
<div class="progress-bar bg-dark" style="width: 1%"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="report-section">
|
||||||
|
<h3 class="section-subtitle">
|
||||||
|
<i class="fas fa-heart me-2 text-primary"></i>
|
||||||
|
Sentiment Analysis Overview
|
||||||
|
</h3>
|
||||||
|
<div class="content-box">
|
||||||
|
<div class="sentiment-summary">
|
||||||
|
<div class="sentiment-stat mb-3">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<span class="d-flex align-items-center">
|
||||||
|
<i class="fas fa-smile text-success me-2"></i>
|
||||||
|
<strong>Positive Responses</strong>
|
||||||
|
</span>
|
||||||
|
<span class="fw-bold text-success">67.2%</span>
|
||||||
|
</div>
|
||||||
|
<small class="text-muted">Employees expressing satisfaction and positive mental health</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sentiment-stat mb-3">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<span class="d-flex align-items-center">
|
||||||
|
<i class="fas fa-meh text-secondary me-2"></i>
|
||||||
|
<strong>Neutral Responses</strong>
|
||||||
|
</span>
|
||||||
|
<span class="fw-bold text-secondary">21.8%</span>
|
||||||
|
</div>
|
||||||
|
<small class="text-muted">Balanced emotional state with room for improvement</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sentiment-stat">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<span class="d-flex align-items-center">
|
||||||
|
<i class="fas fa-frown text-danger me-2"></i>
|
||||||
|
<strong>Negative Responses</strong>
|
||||||
|
</span>
|
||||||
|
<span class="fw-bold text-danger">11.0%</span>
|
||||||
|
</div>
|
||||||
|
<small class="text-muted">Employees experiencing stress, anxiety, or dissatisfaction</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Priority Interventions Section -->
|
||||||
|
<div class="row mb-5">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="report-section">
|
||||||
|
<h2 class="section-title">
|
||||||
|
<i class="fas fa-user-md me-2 text-primary"></i>
|
||||||
|
NVKN Recommended Interventions
|
||||||
|
</h2>
|
||||||
|
<div class="content-box">
|
||||||
|
<p class="lead mb-4">
|
||||||
|
Based on AI analysis of employee responses, NVKN recommends the following evidence-based
|
||||||
|
interventions to enhance workplace mental health and employee wellbeing.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="intervention-priority mb-4">
|
||||||
|
<h4 class="text-danger mb-3">
|
||||||
|
<i class="fas fa-exclamation-triangle me-2"></i>
|
||||||
|
Priority 1: Immediate Actions (0-2 weeks)
|
||||||
|
</h4>
|
||||||
|
<div class="intervention-item">
|
||||||
|
<h6>Mental Health Crisis Support</h6>
|
||||||
|
<p>
|
||||||
|
Immediate professional intervention for 16 employees identified as high or critical risk.
|
||||||
|
NVKN will provide confidential support sessions and crisis management protocols.
|
||||||
|
</p>
|
||||||
|
<div class="d-flex gap-2 mb-2">
|
||||||
|
<span class="badge bg-danger">Critical Priority</span>
|
||||||
|
<span class="badge bg-outline-secondary">16 Employees</span>
|
||||||
|
<span class="badge bg-outline-info">Confidential Process</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="intervention-priority mb-4">
|
||||||
|
<h4 class="text-warning mb-3">
|
||||||
|
<i class="fas fa-clock me-2"></i>
|
||||||
|
Priority 2: Short-term Initiatives (2-8 weeks)
|
||||||
|
</h4>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="intervention-item">
|
||||||
|
<h6>Stress Management Workshop Series</h6>
|
||||||
|
<p>Comprehensive stress reduction training targeting workload management and coping strategies.</p>
|
||||||
|
<span class="badge bg-warning text-dark">High Impact</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="intervention-item">
|
||||||
|
<h6>Manager Mental Health Training</h6>
|
||||||
|
<p>Leadership development focused on recognizing and supporting employee mental wellness.</p>
|
||||||
|
<span class="badge bg-primary">Management Focus</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="intervention-priority">
|
||||||
|
<h4 class="text-primary mb-3">
|
||||||
|
<i class="fas fa-chart-line me-2"></i>
|
||||||
|
Priority 3: Long-term Strategy (2-6 months)
|
||||||
|
</h4>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="intervention-item">
|
||||||
|
<h6>Workplace Culture Enhancement</h6>
|
||||||
|
<p>Systematic improvement of organizational culture and communication patterns.</p>
|
||||||
|
<span class="badge bg-info">Strategic</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="intervention-item">
|
||||||
|
<h6>Preventive Mental Health Program</h6>
|
||||||
|
<p>Ongoing mental wellness monitoring and early intervention systems.</p>
|
||||||
|
<span class="badge bg-success">Preventive</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="intervention-item">
|
||||||
|
<h6>Career Development Clarity</h6>
|
||||||
|
<p>Enhanced career path communication and professional growth opportunities.</p>
|
||||||
|
<span class="badge bg-secondary">Development</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Detailed Findings Section -->
|
||||||
|
<div class="row mb-5">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="report-section">
|
||||||
|
<h3 class="section-subtitle">
|
||||||
|
<i class="fas fa-search me-2 text-primary"></i>
|
||||||
|
Detailed Analysis Findings
|
||||||
|
</h3>
|
||||||
|
<div class="content-box">
|
||||||
|
<div class="finding-item mb-3">
|
||||||
|
<h6 class="text-success">
|
||||||
|
<i class="fas fa-check-circle me-2"></i>Positive Indicators
|
||||||
|
</h6>
|
||||||
|
<ul class="small">
|
||||||
|
<li>Strong team collaboration reported by 78% of employees</li>
|
||||||
|
<li>High job satisfaction in creative and development roles</li>
|
||||||
|
<li>Effective communication with immediate supervisors</li>
|
||||||
|
<li>Positive response to flexible work arrangements</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="finding-item mb-3">
|
||||||
|
<h6 class="text-warning">
|
||||||
|
<i class="fas fa-exclamation-triangle me-2"></i>Areas for Improvement
|
||||||
|
</h6>
|
||||||
|
<ul class="small">
|
||||||
|
<li>Workload distribution inconsistencies across departments</li>
|
||||||
|
<li>Limited career advancement clarity</li>
|
||||||
|
<li>Deadline pressure affecting work-life balance</li>
|
||||||
|
<li>Insufficient mental health resource awareness</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="finding-item">
|
||||||
|
<h6 class="text-danger">
|
||||||
|
<i class="fas fa-alert me-2"></i>Critical Concerns
|
||||||
|
</h6>
|
||||||
|
<ul class="small">
|
||||||
|
<li>Sleep disruption reported by high-risk individuals</li>
|
||||||
|
<li>Chronic stress indicators in specific departments</li>
|
||||||
|
<li>Limited access to mental health support resources</li>
|
||||||
|
<li>Management communication gaps in some teams</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="report-section">
|
||||||
|
<h3 class="section-subtitle">
|
||||||
|
<i class="fas fa-lightbulb me-2 text-primary"></i>
|
||||||
|
AI-Generated Insights
|
||||||
|
</h3>
|
||||||
|
<div class="content-box">
|
||||||
|
<div class="insight-box mb-3 p-3 bg-light rounded">
|
||||||
|
<h6 class="text-primary mb-2">
|
||||||
|
<i class="fas fa-robot me-2"></i>Machine Learning Analysis
|
||||||
|
</h6>
|
||||||
|
<p class="small mb-0">
|
||||||
|
Advanced natural language processing identified key themes in employee responses,
|
||||||
|
revealing underlying patterns not immediately apparent through traditional analysis methods.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="insight-box mb-3 p-3 bg-light rounded">
|
||||||
|
<h6 class="text-info mb-2">
|
||||||
|
<i class="fas fa-brain me-2"></i>Predictive Risk Modeling
|
||||||
|
</h6>
|
||||||
|
<p class="small mb-0">
|
||||||
|
AI risk assessment successfully identified 92% of employees requiring mental health
|
||||||
|
intervention, enabling proactive rather than reactive mental health support.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="insight-box p-3 bg-light rounded">
|
||||||
|
<h6 class="text-success mb-2">
|
||||||
|
<i class="fas fa-target me-2"></i>Intervention Targeting
|
||||||
|
</h6>
|
||||||
|
<p class="small mb-0">
|
||||||
|
Data analysis reveals specific workplace factors contributing to mental health outcomes,
|
||||||
|
allowing for highly targeted and cost-effective intervention strategies.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Implementation Timeline -->
|
||||||
|
<div class="row mb-5">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="report-section">
|
||||||
|
<h2 class="section-title">
|
||||||
|
<i class="fas fa-calendar-alt me-2 text-primary"></i>
|
||||||
|
Implementation Timeline & Next Steps
|
||||||
|
</h2>
|
||||||
|
<div class="content-box">
|
||||||
|
<div class="timeline">
|
||||||
|
<div class="timeline-item">
|
||||||
|
<div class="timeline-badge bg-danger">
|
||||||
|
<i class="fas fa-exclamation"></i>
|
||||||
|
</div>
|
||||||
|
<div class="timeline-content">
|
||||||
|
<h6>Week 1-2: Immediate Crisis Response</h6>
|
||||||
|
<p>Contact and support high-risk employees identified by AI analysis. Implement emergency mental health protocols.</p>
|
||||||
|
<span class="badge bg-danger">Critical</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="timeline-item">
|
||||||
|
<div class="timeline-badge bg-warning">
|
||||||
|
<i class="fas fa-users"></i>
|
||||||
|
</div>
|
||||||
|
<div class="timeline-content">
|
||||||
|
<h6>Week 3-6: Group Interventions</h6>
|
||||||
|
<p>Launch stress management workshops and manager training programs based on identified workplace factors.</p>
|
||||||
|
<span class="badge bg-warning text-dark">High Priority</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="timeline-item">
|
||||||
|
<div class="timeline-badge bg-primary">
|
||||||
|
<i class="fas fa-cogs"></i>
|
||||||
|
</div>
|
||||||
|
<div class="timeline-content">
|
||||||
|
<h6>Month 2-3: Workplace System Changes</h6>
|
||||||
|
<p>Implement organizational changes to address systemic workplace mental health factors.</p>
|
||||||
|
<span class="badge bg-primary">Organizational</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="timeline-item">
|
||||||
|
<div class="timeline-badge bg-success">
|
||||||
|
<i class="fas fa-chart-line"></i>
|
||||||
|
</div>
|
||||||
|
<div class="timeline-content">
|
||||||
|
<h6>Month 4-6: Monitoring & Evaluation</h6>
|
||||||
|
<p>Conduct follow-up assessments to measure intervention effectiveness and adjust strategies.</p>
|
||||||
|
<span class="badge bg-success">Evaluation</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Report Footer -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="report-footer text-center py-4 border-top">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<h6 class="text-primary">NVKN Nærværskonsulenterne</h6>
|
||||||
|
<small class="text-muted">
|
||||||
|
Mental Health Consultancy<br>
|
||||||
|
Workplace Wellness Specialists<br>
|
||||||
|
Copenhagen, Denmark
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<h6 class="text-primary">Technology</h6>
|
||||||
|
<small class="text-muted">
|
||||||
|
Powered by Azure AI<br>
|
||||||
|
Advanced Language Processing<br>
|
||||||
|
Machine Learning Risk Assessment
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<h6 class="text-primary">Contact</h6>
|
||||||
|
<small class="text-muted">
|
||||||
|
Professional Mental Health Support<br>
|
||||||
|
Confidential Consultation Available<br>
|
||||||
|
www.nvkn.dk
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="my-3">
|
||||||
|
|
||||||
|
<p class="text-muted small mb-0">
|
||||||
|
<i class="fas fa-shield-alt me-1"></i>
|
||||||
|
This report contains confidential mental health information and should be handled in accordance with
|
||||||
|
Danish data protection regulations and professional mental health standards.
|
||||||
|
Generated on @ViewBag.GeneratedDate.ToString("MMMM dd, yyyy 'at' HH:mm")
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<script>
|
||||||
|
// Download PDF functionality
|
||||||
|
function downloadPDF() {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Generate PDF Report',
|
||||||
|
text: 'This will create a comprehensive PDF report suitable for client presentations.',
|
||||||
|
icon: 'info',
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonText: 'Generate PDF',
|
||||||
|
cancelButtonText: 'Cancel'
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
// Show loading
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Generating PDF...',
|
||||||
|
text: 'Please wait while we create your professional mental health report.',
|
||||||
|
icon: 'info',
|
||||||
|
allowOutsideClick: false,
|
||||||
|
showConfirmButton: false,
|
||||||
|
didOpen: () => {
|
||||||
|
Swal.showLoading();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// In real implementation, this would call a PDF generation service
|
||||||
|
setTimeout(() => {
|
||||||
|
Swal.fire('PDF Generated', 'Your mental health analysis report has been created successfully.', 'success');
|
||||||
|
// window.location.href = '/path/to/generated/pdf';
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print optimization
|
||||||
|
window.addEventListener('beforeprint', function() {
|
||||||
|
// Hide non-essential elements for printing
|
||||||
|
document.querySelectorAll('.d-print-none').forEach(el => {
|
||||||
|
el.style.display = 'none';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener('afterprint', function() {
|
||||||
|
// Restore elements after printing
|
||||||
|
document.querySelectorAll('.d-print-none').forEach(el => {
|
||||||
|
el.style.display = '';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Auto-generate table of contents for long reports
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const sections = document.querySelectorAll('.section-title, .section-subtitle');
|
||||||
|
if (sections.length > 3) {
|
||||||
|
// Could add automatic TOC generation here for very long reports
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
}
|
||||||
|
|
||||||
|
@section Styles {
|
||||||
|
<style>
|
||||||
|
/* Print Styles */
|
||||||
|
@@media print {
|
||||||
|
.d-print-none
|
||||||
|
|
||||||
|
{
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-container {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card, .card-body {
|
||||||
|
border: none !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-section {
|
||||||
|
page-break-inside: avoid;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
page-break-after: avoid;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Report Styling */
|
||||||
|
.report-container {
|
||||||
|
background: white;
|
||||||
|
padding: 2rem;
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: 1200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-header {
|
||||||
|
padding: 2rem 0;
|
||||||
|
border-bottom: 3px solid #007bff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.company-logo h2 {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-title {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #343a40;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 1.75rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #495057;
|
||||||
|
border-bottom: 2px solid #e9ecef;
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-subtitle {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #495057;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-box {
|
||||||
|
padding: 1.5rem;
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
border-left: 4px solid #007bff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-card {
|
||||||
|
text-align: center;
|
||||||
|
padding: 1.5rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
background: white;
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-card:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-value {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
font-weight: 700;
|
||||||
|
margin: 0.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-label {
|
||||||
|
font-weight: 600;
|
||||||
|
color: #6c757d;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.risk-indicator {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.risk-item {
|
||||||
|
padding: 0.75rem;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
background: white;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sentiment-stat {
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
background: white;
|
||||||
|
border-left: 3px solid #e9ecef;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intervention-priority {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
padding: 1.5rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intervention-item {
|
||||||
|
background: white;
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
border-left: 3px solid #007bff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.finding-item {
|
||||||
|
background: white;
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
border-left: 3px solid #007bff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.insight-box {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.insight-box:hover {
|
||||||
|
transform: translateX(5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline {
|
||||||
|
position: relative;
|
||||||
|
padding-left: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 20px;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 2px;
|
||||||
|
background: #e9ecef;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-item {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-badge {
|
||||||
|
position: absolute;
|
||||||
|
left: -28px;
|
||||||
|
top: 0;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: white;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-content {
|
||||||
|
background: white;
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
|
margin-left: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.executive-summary {
|
||||||
|
line-height: 1.8;
|
||||||
|
font-size: 1.05rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.executive-summary h4 {
|
||||||
|
color: #495057;
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-footer {
|
||||||
|
background: #f8f9fa;
|
||||||
|
margin-top: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
font-size: 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@media (max-width: 768px) {
|
||||||
|
.report-container
|
||||||
|
|
||||||
|
{
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.company-logo h2 {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-title {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-card {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline {
|
||||||
|
padding-left: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-badge {
|
||||||
|
left: -20px;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-content {
|
||||||
|
margin-left: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue