SurveyVista/Web/Areas/Admin/Views/SurveyAnalysis/Index.cshtml

2621 lines
No EOL
93 KiB
Text

@* Views/Admin/SurveyAnalysis/Index.cshtml *@
@model IEnumerable<dynamic>
@{
ViewData["Title"] = "Mental Health Survey Analysis - Dashboard";
}
<div class="dashboard-container">
<!-- Beautiful Hero Banner -->
<div class="hero-banner">
<div class="hero-background">
<div class="hero-pattern"></div>
<div class="hero-glow"></div>
</div>
<div class="container-fluid px-4">
<div class="row align-items-center min-vh-30">
<div class="col-lg-8">
<div class="hero-content">
<div class="hero-badge mb-4">
<i class="fas fa-sparkles me-2"></i>
AI-Powered Analytics
</div>
<h1 class="hero-title mb-4">
Mental Health Survey
<span class="hero-highlight">Analysis Platform</span>
</h1>
<p class="hero-subtitle mb-5">
Transform workplace mental health data into actionable insights with advanced AI analysis.
Identify risks, understand trends, and create healthier work environments.
</p>
<div class="hero-actions">
<button type="button" class="btn btn-hero-primary me-3" onclick="testAIServices()">
<i class="fas fa-heartbeat me-2"></i>Test AI Services
</button>
<button type="button" class="btn btn-hero-secondary" data-bs-toggle="modal" data-bs-target="#testAnalysisModal">
<i class="fas fa-flask me-2"></i>Test Analysis
</button>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="hero-visual">
<div class="floating-card card-1">
<i class="fas fa-brain text-primary"></i>
<span>AI Analysis</span>
</div>
<div class="floating-card card-2">
<i class="fas fa-chart-line text-success"></i>
<span>Real-time Insights</span>
</div>
<div class="floating-card card-3">
<i class="fas fa-shield-alt text-warning"></i>
<span>Risk Assessment</span>
</div>
<div class="hero-illustration">
<div class="pulse-circle"></div>
<i class="fas fa-user-md hero-icon"></i>
</div>
</div>
</div>
</div>
</div>
<!-- Company Badge -->
<div class="company-badge">
<i class="fas fa-user-md me-2"></i>
NVKN Nærværskonsulenterne
</div>
</div>
<!-- Main Content -->
<div class="main-content">
<div class="container-fluid px-4">
<!-- AI Services Status -->
@if (ViewBag.ServiceHealth != null)
{
var serviceHealth = ViewBag.ServiceHealth as Dictionary<string, bool>;
<div class="row mb-5">
<div class="col-12">
<div class="status-card">
<div class="status-header">
<div class="status-icon">
<i class="fas fa-server"></i>
</div>
<div class="status-info">
<h5><i class="fas fa-wifi me-2"></i>AI Services Status</h5>
<p><i class="fas fa-eye me-2"></i>Real-time monitoring of all AI services</p>
</div>
</div>
<div class="status-services">
@foreach (var service in serviceHealth)
{
<div class="service-status @(service.Value ? "online" : "offline")">
<div class="service-indicator"></div>
<span class="service-name">@service.Key.Replace("Azure", "")</span>
<span class="service-label">@(service.Value ? "Online" : "Offline")</span>
</div>
}
</div>
</div>
</div>
</div>
}
<!-- Alert Messages -->
@if (TempData["ErrorMessage"] != null)
{
<div class="alert alert-modern alert-danger" role="alert">
<div class="alert-icon">
<i class="fas fa-exclamation-triangle"></i>
</div>
<div class="alert-content">
<strong>Error:</strong> @TempData["ErrorMessage"]
</div>
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
}
@if (TempData["SuccessMessage"] != null)
{
<div class="alert alert-modern alert-success" role="alert">
<div class="alert-icon">
<i class="fas fa-check-circle"></i>
</div>
<div class="alert-content">
<strong>Success:</strong> @TempData["SuccessMessage"]
</div>
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
}
@if (TempData["WarningMessage"] != null)
{
<div class="alert alert-modern alert-warning" role="alert">
<div class="alert-icon">
<i class="fas fa-exclamation-circle"></i>
</div>
<div class="alert-content">
<strong>Warning:</strong> @TempData["WarningMessage"]
</div>
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
}
<!-- Questionnaires Section -->
<div class="section-header mb-5">
<h2 class="section-title">
<span class="section-icon">
<i class="fas fa-clipboard-check"></i>
</span>
Active Questionnaires
</h2>
<p class="section-subtitle">Manage and analyze your mental health surveys</p>
</div>
<!-- Questionnaires Grid -->
<div class="questionnaires-grid">
@{
var hasAnyQuestionnairesWithResponses = false;
var modelList = Model?.ToList() ?? new List<dynamic>();
foreach (var q in modelList)
{
if (q.ResponseCount > 0)
{
hasAnyQuestionnairesWithResponses = true;
break;
}
}
}
@if (Model != null && modelList.Count > 0)
{
@foreach (var questionnaire in modelList)
{
// Only show questionnaires with responses
@if (questionnaire.ResponseCount > 0)
{
<div class="questionnaire-card">
<div class="card-header">
<div class="card-title-section">
<h3 class="card-title">@questionnaire.Title</h3>
<!-- User Information -->
@{
var hasUsers = false;
var userCount = 0;
try {
if (questionnaire.Users != null)
{
userCount = questionnaire.Users.Count;
hasUsers = userCount > 0;
}
} catch {
hasUsers = false;
userCount = 0;
}
}
@if (hasUsers)
{
<div class="participants-section">
<div class="participants-header">
<i class="fas fa-users"></i>
<span>Recent Participants</span>
</div>
<div class="participants-list">
@for (int i = 0; i < Math.Min(3, userCount); i++)
{
var user = questionnaire.Users[i];
<div class="participant">
<div class="participant-avatar">
@user.UserName.Substring(0, 1).ToUpper()
</div>
<div class="participant-info">
<span class="participant-name">@user.UserName</span>
<span class="participant-email">@user.Email</span>
</div>
</div>
}
@if (userCount > 3)
{
<div class="participants-more">
<span>+@(userCount - 3) more</span>
</div>
}
</div>
</div>
}
else if (questionnaire.ResponseCount > 0)
{
<div class="participation-stats">
<div class="stat-item">
<i class="fas fa-chart-bar"></i>
<span>@questionnaire.ResponseCount Responses</span>
</div>
<div class="stat-item">
<i class="fas fa-comments"></i>
<span>@questionnaire.TextResponseCount Text Responses</span>
</div>
</div>
}
</div>
<!-- Card Actions Dropdown -->
<div class="card-actions">
<button class="btn-card-menu" type="button" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-v"></i>
</button>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item" href="@Url.Action("AnalyzeQuestionnaire", new { id = questionnaire.Id })">
<i class="fas fa-chart-line text-primary"></i>Full Analysis
</a></li>
<li><a class="dropdown-item" href="@Url.Action("HighRiskResponses", new { id = questionnaire.Id })">
<i class="fas fa-exclamation-triangle text-danger"></i>High Risk
</a></li>
<li><a class="dropdown-item" href="@Url.Action("Dashboard", new { id = questionnaire.Id })">
<i class="fas fa-tachometer-alt text-info"></i>Dashboard
</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="@Url.Action("GenerateReport", new { id = questionnaire.Id })">
<i class="fas fa-file-alt text-success"></i>Generate Report
</a></li>
</ul>
</div>
</div>
<!-- Card Body -->
<div class="card-body">
<!-- Statistics -->
<div class="stats-grid">
<div class="stat-box stat-primary">
<div class="stat-icon">
<i class="fas fa-question"></i>
</div>
<div class="stat-value">@questionnaire.QuestionCount</div>
<div class="stat-label">Questions</div>
</div>
<div class="stat-box stat-success">
<div class="stat-icon">
<i class="fas fa-reply"></i>
</div>
<div class="stat-value">@questionnaire.ResponseCount</div>
<div class="stat-label">Responses</div>
</div>
<div class="stat-box stat-info">
<div class="stat-icon">
<i class="fas fa-comment"></i>
</div>
<div class="stat-value">@questionnaire.TextResponseCount</div>
<div class="stat-label">Text Answers</div>
</div>
</div>
<!-- Last Response -->
@if (questionnaire.LastResponse != null && questionnaire.LastResponse != DateTime.MinValue)
{
<div class="last-activity">
<i class="fas fa-clock"></i>
<span>Last response: @((DateTime)questionnaire.LastResponse).ToString("MMM dd, yyyy")</span>
</div>
}
</div>
<!-- Card Footer -->
<div class="card-footer">
@if (questionnaire.TextResponseCount > 0)
{
<!-- Ready Status -->
<div class="status-ready">
<i class="fas fa-check-circle"></i>
<span>Ready for AI Analysis</span>
</div>
<!-- Primary Action -->
<button onclick="startAnalysisWithProgress(@questionnaire.Id, '@questionnaire.Title')"
class="btn-analyze">
<span class="btn-content">
<i class="fas fa-rocket"></i>
Start AI Analysis
</span>
<div class="btn-shine"></div>
</button>
<!-- Quick Actions -->
<div class="quick-actions-grid">
<a href="@Url.Action("HighRiskResponses", new { id = questionnaire.Id })"
class="quick-action-btn risk">
<div class="quick-action-icon">
<i class="fas fa-shield-alt"></i>
</div>
<span class="quick-action-label">High Risk</span>
<div class="quick-action-subtitle">Critical responses</div>
</a>
<a href="@Url.Action("BatchAnalyze", new { id = questionnaire.Id })"
class="quick-action-btn batch">
<div class="quick-action-icon">
<i class="fas fa-layer-group"></i>
</div>
<span class="quick-action-label">Batch Process</span>
<div class="quick-action-subtitle">Bulk analysis</div>
</a>
<a href="@Url.Action("AnalyzeTrends", new { id = questionnaire.Id })"
class="quick-action-btn trends">
<div class="quick-action-icon">
<i class="fas fa-chart-line"></i>
</div>
<span class="quick-action-label">Analyze Trends</span>
<div class="quick-action-subtitle">Time patterns</div>
</a>
</div>
}
else
{
<div class="status-unavailable">
<i class="fas fa-info-circle"></i>
<span>No Text Data Available</span>
</div>
<button class="btn-disabled" disabled>
<i class="fas fa-ban me-2"></i>
Analysis Not Available
</button>
}
</div>
</div>
}
}
<!-- Empty State -->
@if (!hasAnyQuestionnairesWithResponses)
{
<div class="empty-state">
<div class="empty-illustration">
<i class="fas fa-clipboard-check"></i>
<div class="empty-glow"></div>
</div>
<h3><i class="fas fa-search me-2"></i>No Questionnaires with Responses</h3>
<p><i class="fas fa-info-circle me-2"></i>There are no questionnaires with responses available for analysis at the moment.</p>
<a href="@Url.Action("Index", "Questionnaire")" class="btn-create">
<i class="fas fa-plus-circle me-2"></i>
Create New Questionnaire
</a>
</div>
}
}
else
{
<div class="empty-state">
<div class="empty-illustration">
<i class="fas fa-clipboard-check"></i>
<div class="empty-glow"></div>
</div>
<h3><i class="fas fa-search me-2"></i>No Questionnaires Found</h3>
<p><i class="fas fa-info-circle me-2"></i>There are no questionnaires available for analysis at the moment.</p>
<a href="@Url.Action("Index", "Questionnaire")" class="btn-create">
<i class="fas fa-plus-circle me-2"></i>
Create New Questionnaire
</a>
</div>
}
</div>
</div>
</div>
</div>
<!-- Enhanced AI Services Status Modal -->
<div class="modal fade" id="aiServicesModal" tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content" style="border-radius: 1rem; overflow: hidden; border: none; box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);">
<div class="modal-header" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border: none; padding: 2rem;">
<div style="display: flex; align-items: center; gap: 1rem;">
<div style="width: 50px; height: 50px; background: rgba(255,255,255,0.2); border-radius: 12px; display: flex; align-items: center; justify-content: center;">
<i class="fas fa-server" style="color: white; font-size: 1.25rem;"></i>
</div>
<div>
<h5 class="modal-title" style="color: white; font-weight: 700; margin-bottom: 0.25rem; font-size: 1.25rem;">AI Services Health Check</h5>
<p style="color: rgba(255,255,255,0.8); margin: 0; font-size: 0.875rem;">Real-time monitoring of AI services</p>
</div>
</div>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" style="position: absolute; top: 1.5rem; right: 1.5rem;"></button>
</div>
<div class="modal-body" style="padding: 2rem; background: white;">
<div id="servicesStatusContent">
<div style="text-center: true; padding: 2rem;">
<div style="display: inline-block; width: 40px; height: 40px; border: 3px solid #e2e8f0; border-top: 3px solid #667eea; border-radius: 50%; animation: spin 1s linear infinite; margin-bottom: 1rem;"></div>
<h6 style="font-weight: 600; color: #1e293b; margin-bottom: 0.5rem;">Checking AI Services</h6>
<p style="color: #64748b; margin: 0;">Please wait while we verify all systems...</p>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Test Analysis Modal -->
<div class="modal fade" id="testAnalysisModal" tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content" style="border-radius: 1rem; overflow: hidden; border: none; box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);">
<div class="modal-header" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border: none; padding: 2rem;">
<div style="display: flex; align-items: center; gap: 1rem;">
<div style="width: 50px; height: 50px; background: rgba(255,255,255,0.2); border-radius: 12px; display: flex; align-items: center; justify-content: center;">
<i class="fas fa-flask" style="color: white; font-size: 1.25rem;"></i>
</div>
<div>
<h5 class="modal-title" style="color: white; font-weight: 700; margin-bottom: 0.25rem; font-size: 1.25rem;">AI Analysis Testing</h5>
<p style="color: rgba(255,255,255,0.8); margin: 0; font-size: 0.875rem;">Test AI capabilities with sample data</p>
</div>
</div>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" style="position: absolute; top: 1.5rem; right: 1.5rem;"></button>
</div>
<div class="modal-body" style="padding: 2rem; background: white;">
<form id="testAnalysisForm">
<div class="mb-4">
<label for="sampleText" class="form-label" style="display: flex; align-items: center; font-weight: 600; color: #1e293b; margin-bottom: 0.75rem;">
<i class="fas fa-comment-dots me-2"></i>
Sample Response Text
</label>
<textarea class="form-control" id="sampleText" rows="4"
style="padding: 1rem; border: 2px solid #e2e8f0; border-radius: 0.75rem; background: #f8fafc; resize: vertical; font-family: inherit;"
placeholder="Enter sample employee response for testing AI analysis..."></textarea>
<div class="form-text" style="display: flex; align-items: flex-start; gap: 0.5rem; margin-top: 0.75rem; font-size: 0.8rem; color: #64748b; padding: 0.75rem; background: #f1f5f9; border-radius: 0.5rem; border-left: 3px solid #667eea;">
<i class="fas fa-info-circle" style="margin-top: 0.125rem;"></i>
<span>Example: "I feel overwhelmed with my workload and have trouble sleeping due to work stress."</span>
</div>
</div>
</form>
<div id="testResults" class="d-none">
<div style="height: 1px; background: linear-gradient(90deg, transparent, #e2e8f0, transparent); margin: 2rem 0;"></div>
<div style="display: flex; align-items: center; gap: 0.75rem; font-weight: 700; color: #1e293b; font-size: 1.125rem; margin-bottom: 1.5rem;">
<i class="fas fa-chart-bar"></i>
<span>Analysis Results</span>
</div>
<div id="testResultsContent"></div>
</div>
</div>
<div class="modal-footer" style="padding: 1.5rem 2rem; background: #f8fafc; border: none; display: flex; gap: 1rem; justify-content: flex-end;">
<button type="button" class="btn" style="padding: 0.75rem 1.5rem; background: white; color: #64748b; border: 2px solid #e2e8f0; border-radius: 0.75rem; font-weight: 600;" data-bs-dismiss="modal">
<i class="fas fa-times me-2"></i>Close
</button>
<button type="button" class="btn" style="padding: 0.75rem 1.5rem; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; border-radius: 0.75rem; font-weight: 600;" onclick="performTestAnalysis()">
<i class="fas fa-play me-2"></i>Run Analysis
</button>
</div>
</div>
</div>
</div>
<!-- Analysis Progress Modal -->
<div class="modal fade" id="analysisProgressModal" tabindex="-1" data-bs-backdrop="static">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content" style="border-radius: 1rem; overflow: hidden; border: none; box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);">
<div class="modal-header" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border: none; padding: 2rem;">
<div style="display: flex; align-items: center; gap: 1rem;">
<div style="width: 50px; height: 50px; background: rgba(255,255,255,0.2); border-radius: 12px; display: flex; align-items: center; justify-content: center;">
<i class="fas fa-robot" style="color: white; font-size: 1.25rem;"></i>
</div>
<div>
<h5 class="modal-title" style="color: white; font-weight: 700; margin-bottom: 0.25rem; font-size: 1.25rem;">AI Analysis in Progress</h5>
<p style="color: rgba(255,255,255,0.8); margin: 0; font-size: 0.875rem;">Processing your mental health data</p>
</div>
</div>
</div>
<div class="modal-body text-center" style="padding: 3rem 2rem; background: white;">
<div class="mb-4">
<i class="fas fa-brain text-primary" style="font-size: 4rem; color: #667eea !important;"></i>
</div>
<h6 class="fw-bold mb-3" id="progressTitle" style="color: #1e293b;">Analyzing Questionnaire...</h6>
<div class="progress mb-4" style="height: 8px; background: #e2e8f0; border-radius: 4px;">
<div class="progress-bar progress-bar-striped progress-bar-animated"
role="progressbar" style="width: 0%; background: #667eea;"></div>
</div>
<div id="progressSteps" class="text-start">
<div class="progress-step" style="display: flex; align-items: center; padding: 0.5rem 0; color: #1e293b;">
<i class="fas fa-check-circle text-success me-2" style="color: #22c55e !important;"></i>
<span>Initializing AI services...</span>
</div>
<div class="progress-step text-muted" style="display: flex; align-items: center; padding: 0.5rem 0; opacity: 0.5;">
<i class="fas fa-circle me-2"></i>
<span>Processing responses...</span>
</div>
<div class="progress-step text-muted" style="display: flex; align-items: center; padding: 0.5rem 0; opacity: 0.5;">
<i class="fas fa-circle me-2"></i>
<span>Analyzing sentiment...</span>
</div>
<div class="progress-step text-muted" style="display: flex; align-items: center; padding: 0.5rem 0; opacity: 0.5;">
<i class="fas fa-circle me-2"></i>
<span>Generating insights...</span>
</div>
<div class="progress-step text-muted" style="display: flex; align-items: center; padding: 0.5rem 0; opacity: 0.5;">
<i class="fas fa-circle me-2"></i>
<span>Creating summary...</span>
</div>
</div>
</div>
</div>
</div>
</div>
@section Scripts {
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script>
// Enhanced Test AI Services with Beautiful Modal
function testAIServices() {
const modal = new bootstrap.Modal(document.getElementById('aiServicesModal'));
modal.show();
$.get('@Url.Action("ServiceHealth")')
.done(function(data) {
if (data.success && data.services) {
let content = '';
// Azure Language Service
const langService = data.services['AzureLanguageService'] || false;
content += createServiceCard('Azure Language Service', 'Sentiment Analysis & Text Processing', langService, 'fa-comments');
// Azure OpenAI
const openaiService = data.services['AzureOpenAI'] || false;
content += createServiceCard('Azure OpenAI', 'AI-Powered Risk Assessment', openaiService, 'fa-brain');
// Overall Status
const allOnline = langService && openaiService;
content += `
<div class="mt-4 p-3 rounded-3 ${allOnline ? 'bg-success' : 'bg-warning'} bg-opacity-10">
<div class="d-flex align-items-center">
<i class="fas ${allOnline ? 'fa-check-circle text-success' : 'fa-exclamation-triangle text-warning'} me-3 fs-4"></i>
<div>
<strong>${allOnline ? 'All Systems Operational' : 'Service Issues Detected'}</strong>
<br><small class="text-muted">${data.message}</small>
</div>
</div>
</div>
`;
document.getElementById('servicesStatusContent').innerHTML = content;
} else {
document.getElementById('servicesStatusContent').innerHTML = `
<div class="alert alert-danger border-0 rounded-3">
<i class="fas fa-exclamation-triangle me-2"></i>
<strong>Error:</strong> ${data.error || 'Unable to check service status'}
</div>
`;
}
})
.fail(function() {
document.getElementById('servicesStatusContent').innerHTML = `
<div class="alert alert-danger border-0 rounded-3">
<i class="fas fa-times-circle me-2"></i>
<strong>Connection Error:</strong> Unable to connect to service health endpoint
</div>
`;
});
}
function createServiceCard(name, description, isOnline, icon) {
const statusClass = isOnline ? 'success' : 'danger';
const statusIcon = isOnline ? 'fa-check-circle' : 'fa-times-circle';
const statusText = isOnline ? 'Online' : 'Offline';
return `
<div class="service-card mb-3 p-4 border rounded-3 ${isOnline ? 'border-success' : 'border-danger'} bg-opacity-10 ${isOnline ? 'bg-success' : 'bg-danger'}">
<div class="d-flex align-items-center">
<div class="service-icon me-4">
<i class="fas ${icon} text-${statusClass} fs-2"></i>
</div>
<div class="flex-grow-1">
<h6 class="mb-1 fw-bold">${name}</h6>
<p class="mb-2 text-muted small">${description}</p>
<div class="d-flex align-items-center">
<i class="fas ${statusIcon} text-${statusClass} me-2"></i>
<span class="fw-semibold text-${statusClass}">${statusText}</span>
</div>
</div>
</div>
</div>
`;
}
// Enhanced Test Analysis
function performTestAnalysis() {
const sampleText = document.getElementById('sampleText').value.trim();
if (!sampleText) {
Swal.fire({
title: 'Input Required',
text: 'Please enter sample text for analysis',
icon: 'warning',
confirmButtonClass: 'btn btn-warning rounded-pill px-4'
});
return;
}
const resultsDiv = document.getElementById('testResults');
const contentDiv = document.getElementById('testResultsContent');
contentDiv.innerHTML = `
<div class="text-center py-4">
<div class="spinner-border text-primary mb-3" role="status"></div>
<p class="text-muted">Analyzing with AI services...</p>
</div>
`;
resultsDiv.classList.remove('d-none');
$.post('@Url.Action("TestAnalysis")', { sampleText: sampleText })
.done(function(data) {
if (data.success) {
contentDiv.innerHTML = createAnalysisResults(data);
} else {
contentDiv.innerHTML = `
<div class="alert alert-danger border-0 rounded-3">
<i class="fas fa-exclamation-triangle me-2"></i>
${data.message}
</div>
`;
}
})
.fail(function() {
contentDiv.innerHTML = `
<div class="alert alert-danger border-0 rounded-3">
<i class="fas fa-times-circle me-2"></i>
Error performing analysis
</div>
`;
});
}
function createAnalysisResults(data) {
return `
<div class="analysis-results">
<div class="row g-3 mb-4">
<div class="col-md-6">
<div style="background: #f8fafc; border: 2px solid #e2e8f0; border-radius: 0.75rem; padding: 1.5rem; text-align: center;">
<div style="display: flex; align-items: center; justify-content: center; margin-bottom: 1rem;">
<i class="fas fa-heart" style="color: #64748b; margin-right: 0.5rem;"></i>
<strong style="color: #1e293b;">Sentiment</strong>
</div>
<span style="background: ${getSentimentBg(data.sentiment)}; color: white; padding: 0.5rem 1.25rem; border-radius: 50px; font-weight: 600; font-size: 0.875rem;">
${data.sentiment || 'N/A'}
</span>
</div>
</div>
<div class="col-md-6">
<div style="background: #f8fafc; border: 2px solid #e2e8f0; border-radius: 0.75rem; padding: 1.5rem; text-align: center;">
<div style="display: flex; align-items: center; justify-content: center; margin-bottom: 1rem;">
<i class="fas fa-shield-alt" style="color: #64748b; margin-right: 0.5rem;"></i>
<strong style="color: #1e293b;">Risk Level</strong>
</div>
<span style="background: ${getRiskBg(data.riskLevel)}; color: white; padding: 0.5rem 1.25rem; border-radius: 50px; font-weight: 600; font-size: 0.875rem;">
${data.riskLevel || 'N/A'}
</span>
</div>
</div>
</div>
<div style="margin-bottom: 1.5rem;">
<div style="display: flex; align-items: center; margin-bottom: 1rem;">
<i class="fas fa-key" style="color: #64748b; margin-right: 0.5rem;"></i>
<strong style="color: #1e293b;">Key Phrases</strong>
</div>
<div style="display: flex; flex-wrap: wrap; gap: 0.5rem; min-height: 2rem;">
${data.keyPhrases && data.keyPhrases.length > 0 ?
data.keyPhrases.map(phrase =>
`<span style="background: #f1f5f9; color: #374151; padding: 0.375rem 0.75rem; border-radius: 0.375rem; font-size: 0.875rem; border: 1px solid #d1d5db;">${phrase}</span>`
).join('') :
'<span style="color: #9ca3af; font-style: italic;">No key phrases detected</span>'}
</div>
</div>
<div>
<div style="display: flex; align-items: center; margin-bottom: 1rem;">
<i class="fas fa-tags" style="color: #64748b; margin-right: 0.5rem;"></i>
<strong style="color: #1e293b;">Categories</strong>
</div>
<div style="display: flex; flex-wrap: wrap; gap: 0.5rem; min-height: 2rem;">
${data.insights && data.insights.length > 0 ?
data.insights.map(category =>
`<span style="background: #0891b2; color: white; padding: 0.375rem 0.75rem; border-radius: 0.375rem; font-size: 0.875rem; font-weight: 500;">${category}</span>`
).join('') :
'<span style="color: #9ca3af; font-style: italic;">No categories identified</span>'}
</div>
</div>
</div>
`;
}
function getSentimentBg(sentiment) {
switch(sentiment?.toLowerCase()) {
case 'positive': return '#22c55e';
case 'negative': return '#ef4444';
case 'neutral': return '#6b7280';
default: return '#6b7280';
}
}
function getRiskBg(riskLevel) {
switch(riskLevel?.toLowerCase()) {
case 'low': return '#22c55e';
case 'moderate': return '#f59e0b';
case 'high': return '#ef4444';
case 'critical': return '#7c2d12';
default: return '#6b7280';
}
}
// Start Analysis with Progress Bar
function startAnalysisWithProgress(questionnaireId, title) {
document.getElementById('progressTitle').textContent = `Analyzing "${title}"`;
const modal = new bootstrap.Modal(document.getElementById('analysisProgressModal'));
modal.show();
// Simulate progress
let progress = 0;
const progressBar = document.querySelector('#analysisProgressModal .progress-bar');
const steps = document.querySelectorAll('#progressSteps .progress-step');
const interval = setInterval(() => {
progress += Math.random() * 20;
if (progress > 90) progress = 90;
progressBar.style.width = progress + '%';
// Update steps
const currentStep = Math.floor(progress / 20);
steps.forEach((step, index) => {
if (index < currentStep) {
step.classList.remove('text-muted');
step.style.opacity = '1';
step.style.color = '#22c55e';
const icon = step.querySelector('i');
icon.className = 'fas fa-check-circle me-2';
icon.style.color = '#22c55e';
} else if (index === currentStep) {
step.classList.remove('text-muted');
step.style.opacity = '1';
step.style.color = '#667eea';
const icon = step.querySelector('i');
icon.className = 'fas fa-spinner fa-spin me-2';
icon.style.color = '#667eea';
}
});
if (progress >= 90) {
clearInterval(interval);
setTimeout(() => {
progressBar.style.width = '100%';
steps.forEach((step, index) => {
step.classList.remove('text-muted');
step.style.opacity = '1';
step.style.color = '#22c55e';
const icon = step.querySelector('i');
icon.className = 'fas fa-check-circle me-2';
icon.style.color = '#22c55e';
});
setTimeout(() => {
window.location.href = '@Url.Action("AnalyzeQuestionnaire")?id=' + questionnaireId;
}, 1000);
}, 1000);
}
}, 200);
}
function getSentimentColor(sentiment) {
switch(sentiment?.toLowerCase()) {
case 'positive': return 'success';
case 'negative': return 'danger';
case 'neutral': return 'secondary';
default: return 'secondary';
}
}
function getRiskColor(riskLevel) {
switch(riskLevel?.toLowerCase()) {
case 'low': return 'success';
case 'moderate': return 'warning';
case 'high': return 'danger';
case 'critical': return 'dark';
default: return 'secondary';
}
}
</script>
}
@section Styles {
<style>
:root {
--primary: #2563eb;
--primary-dark: #1d4ed8;
--secondary: #64748b;
--success: #10b981;
--warning: #f59e0b;
--danger: #ef4444;
--info: #06b6d4;
--bg-primary: #0f172a;
--bg-secondary: #1e293b;
--bg-tertiary: #334155;
--gradient-primary: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
--gradient-hero: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%);
--gradient-success: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
--gradient-warning: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%);
--gradient-danger: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
--gradient-info: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
--shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
--radius-sm: 8px;
--radius-md: 12px;
--radius-lg: 16px;
--radius-xl: 24px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
min-height: 100vh;
color: #334155;
}
.dashboard-container {
min-height: 100vh;
}
/* Hero Banner */
.hero-banner {
position: relative;
min-height: 35vh;
display: flex;
align-items: center;
overflow: hidden;
}
.hero-background {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: var(--gradient-hero);
z-index: 0;
}
.hero-pattern {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image:
radial-gradient(circle at 25% 25%, rgba(255,255,255,0.1) 1px, transparent 1px),
radial-gradient(circle at 75% 75%, rgba(255,255,255,0.1) 1px, transparent 1px);
background-size: 50px 50px;
animation: float 20s ease-in-out infinite;
}
.hero-glow {
position: absolute;
top: 20%;
right: 10%;
width: 400px;
height: 400px;
background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%);
border-radius: 50%;
animation: pulse 4s ease-in-out infinite;
}
.hero-content {
position: relative;
z-index: 2;
color: white;
}
.hero-badge {
display: inline-flex;
align-items: center;
padding: 0.5rem 1.25rem;
background: rgba(255, 255, 255, 0.2);
backdrop-filter: blur(10px);
border-radius: 50px;
font-size: 0.875rem;
font-weight: 600;
color: rgba(255, 255, 255, 0.9);
border: 1px solid rgba(255, 255, 255, 0.2);
}
.hero-title {
font-size: 3.5rem;
font-weight: 800;
line-height: 1.1;
margin-bottom: 1.5rem;
}
.hero-highlight {
background: linear-gradient(135deg, #fbbf24, #f59e0b);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.hero-subtitle {
font-size: 1.25rem;
line-height: 1.6;
color: rgba(255, 255, 255, 0.8);
max-width: 600px;
}
.hero-actions {
display: flex;
gap: 1rem;
flex-wrap: wrap;
}
.btn-hero-primary {
padding: 1rem 2rem;
background: rgba(255, 255, 255, 0.2);
backdrop-filter: blur(10px);
color: white;
border: 2px solid rgba(255, 255, 255, 0.3);
border-radius: var(--radius-lg);
font-weight: 600;
font-size: 1rem;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.btn-hero-primary:hover {
background: rgba(255, 255, 255, 0.3);
border-color: rgba(255, 255, 255, 0.5);
color: white;
transform: translateY(-2px);
box-shadow: var(--shadow-lg);
}
.btn-hero-secondary {
padding: 1rem 2rem;
background: transparent;
color: white;
border: 2px solid rgba(255, 255, 255, 0.3);
border-radius: var(--radius-lg);
font-weight: 600;
font-size: 1rem;
transition: all 0.3s ease;
}
.btn-hero-secondary:hover {
background: rgba(255, 255, 255, 0.1);
border-color: rgba(255, 255, 255, 0.5);
color: white;
transform: translateY(-2px);
}
/* Hero Visual */
.hero-visual {
position: relative;
z-index: 2;
height: 400px;
}
.floating-card {
position: absolute;
display: flex;
align-items: center;
gap: 0.75rem;
padding: 1rem 1.5rem;
background: rgba(255, 255, 255, 0.15);
backdrop-filter: blur(20px);
border-radius: var(--radius-lg);
border: 1px solid rgba(255, 255, 255, 0.2);
color: white;
font-weight: 600;
animation: float 6s ease-in-out infinite;
}
.floating-card i {
font-size: 1.25rem;
}
.floating-card.card-1 {
top: 10%;
left: 10%;
animation-delay: 0s;
}
.floating-card.card-2 {
top: 30%;
right: 20%;
animation-delay: 2s;
}
.floating-card.card-3 {
bottom: 25%;
left: 20%;
animation-delay: 4s;
}
.hero-illustration {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.pulse-circle {
width: 120px;
height: 120px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.1);
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
animation: pulse 3s ease-in-out infinite;
}
.pulse-circle::before {
content: '';
position: absolute;
top: -20px;
left: -20px;
right: -20px;
bottom: -20px;
border-radius: 50%;
border: 2px solid rgba(255, 255, 255, 0.2);
animation: pulse 3s ease-in-out infinite 1s;
}
.hero-icon {
font-size: 3rem;
color: white;
position: relative;
z-index: 2;
}
.company-badge {
position: absolute;
top: 2rem;
right: 2rem;
padding: 0.75rem 1.5rem;
background: rgba(255, 255, 255, 0.15);
backdrop-filter: blur(10px);
border-radius: 50px;
color: rgba(255, 255, 255, 0.9);
font-weight: 600;
font-size: 0.875rem;
border: 1px solid rgba(255, 255, 255, 0.2);
z-index: 3;
}
/* Main Content */
.main-content {
position: relative;
background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
padding: 4rem 0;
margin-top: -2rem;
border-radius: var(--radius-xl) var(--radius-xl) 0 0;
z-index: 3;
}
/* Status Card */
.status-card {
background: white;
border-radius: var(--radius-xl);
padding: 2rem;
box-shadow: var(--shadow-lg);
border: 1px solid rgba(255, 255, 255, 0.8);
transition: all 0.3s ease;
}
.status-card:hover {
transform: translateY(-4px);
box-shadow: var(--shadow-2xl);
}
.status-header {
display: flex;
align-items: center;
gap: 1.5rem;
margin-bottom: 2rem;
}
.status-icon {
width: 60px;
height: 60px;
background: var(--gradient-primary);
border-radius: var(--radius-lg);
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 1.5rem;
}
.status-info h5 {
font-weight: 700;
color: #1e293b;
margin-bottom: 0.25rem;
}
.status-info p {
color: var(--secondary);
margin: 0;
}
.status-services {
display: flex;
gap: 2rem;
flex-wrap: wrap;
}
.service-status {
display: flex;
align-items: center;
gap: 1rem;
padding: 1rem 1.5rem;
background: #f8fafc;
border-radius: var(--radius-lg);
border: 2px solid transparent;
transition: all 0.3s ease;
}
.service-status.online {
border-color: var(--success);
background: rgba(16, 185, 129, 0.05);
}
.service-status.offline {
border-color: var(--danger);
background: rgba(239, 68, 68, 0.05);
}
.service-indicator {
width: 12px;
height: 12px;
border-radius: 50%;
animation: pulse 2s infinite;
}
.service-status.online .service-indicator {
background: var(--success);
box-shadow: 0 0 0 4px rgba(16, 185, 129, 0.2);
}
.service-status.offline .service-indicator {
background: var(--danger);
box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.2);
}
.service-name {
font-weight: 600;
color: #1e293b;
}
.service-label {
font-size: 0.875rem;
color: var(--secondary);
}
/* Alert Messages */
.alert-modern {
display: flex;
align-items: center;
padding: 1.25rem;
border-radius: var(--radius-lg);
border: none;
box-shadow: var(--shadow-md);
margin-bottom: 1.5rem;
}
.alert-icon {
font-size: 1.5rem;
margin-right: 1rem;
}
.alert-content {
flex: 1;
}
/* Section Header */
.section-header {
text-align: center;
margin-bottom: 3rem;
}
.section-title {
display: flex;
align-items: center;
justify-content: center;
gap: 1rem;
font-size: 2.5rem;
font-weight: 800;
color: #1e293b;
margin-bottom: 1rem;
}
.section-icon {
width: 60px;
height: 60px;
background: var(--gradient-primary);
border-radius: var(--radius-lg);
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 1.5rem;
}
.section-subtitle {
font-size: 1.125rem;
color: var(--secondary);
max-width: 600px;
margin: 0 auto;
}
/* Questionnaires Grid */
.questionnaires-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
gap: 2rem;
}
/* Questionnaire Cards */
.questionnaire-card {
background: white;
border-radius: var(--radius-xl);
box-shadow: var(--shadow-lg);
overflow: hidden;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
border: 1px solid rgba(255, 255, 255, 0.8);
}
.questionnaire-card:hover {
transform: translateY(-8px);
box-shadow: var(--shadow-2xl);
}
.card-header {
padding: 2rem;
background: linear-gradient(135deg, #f8f9ff 0%, #e6efff 100%);
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.card-title-section {
flex: 1;
}
.card-title {
font-size: 1.5rem;
font-weight: 700;
color: #1e293b;
margin-bottom: 1.5rem;
line-height: 1.3;
}
.participants-section {
background: rgba(255, 255, 255, 0.7);
border-radius: var(--radius-lg);
padding: 1.5rem;
margin-top: 1rem;
}
.participants-header {
display: flex;
align-items: center;
gap: 0.75rem;
margin-bottom: 1rem;
font-weight: 600;
color: var(--secondary);
font-size: 0.875rem;
}
.participants-list {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.participant {
display: flex;
align-items: center;
gap: 1rem;
}
.participant-avatar {
width: 40px;
height: 40px;
background: var(--gradient-primary);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: 600;
font-size: 1rem;
}
.participant-info {
display: flex;
flex-direction: column;
}
.participant-name {
font-weight: 600;
color: #1e293b;
font-size: 0.875rem;
}
.participant-email {
font-size: 0.75rem;
color: var(--secondary);
}
.participants-more {
text-align: center;
color: var(--secondary);
font-size: 0.875rem;
font-weight: 500;
padding: 0.5rem;
}
.participation-stats {
background: rgba(255, 255, 255, 0.7);
border-radius: var(--radius-lg);
padding: 1.5rem;
margin-top: 1rem;
}
.stat-item {
display: flex;
align-items: center;
gap: 0.75rem;
margin-bottom: 0.75rem;
font-size: 0.875rem;
}
.stat-item:last-child {
margin-bottom: 0;
}
.stat-item i {
color: var(--secondary);
}
.card-actions {
position: relative;
}
.btn-card-menu {
width: 40px;
height: 40px;
background: rgba(255, 255, 255, 0.8);
border: none;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: var(--secondary);
transition: all 0.3s ease;
}
.btn-card-menu:hover {
background: white;
color: var(--primary);
box-shadow: var(--shadow-md);
}
.card-body {
padding: 2rem;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
margin-bottom: 2rem;
}
.stat-box {
background: #f8fafc;
border-radius: var(--radius-lg);
padding: 1.5rem;
text-align: center;
transition: all 0.3s ease;
border: 2px solid transparent;
}
.stat-box:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-md);
}
.stat-box.stat-primary {
border-color: var(--primary);
background: rgba(37, 99, 235, 0.05);
}
.stat-box.stat-success {
border-color: var(--success);
background: rgba(16, 185, 129, 0.05);
}
.stat-box.stat-info {
border-color: var(--info);
background: rgba(6, 182, 212, 0.05);
}
.stat-icon {
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 1rem;
color: white;
}
.stat-primary .stat-icon {
background: var(--primary);
}
.stat-success .stat-icon {
background: var(--success);
}
.stat-info .stat-icon {
background: var(--info);
}
.stat-value {
font-size: 2rem;
font-weight: 700;
color: #1e293b;
margin-bottom: 0.25rem;
}
.stat-label {
font-size: 0.875rem;
color: var(--secondary);
font-weight: 500;
}
.last-activity {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 1rem;
background: #f8fafc;
border-radius: var(--radius-lg);
margin-top: 1rem;
font-size: 0.875rem;
color: var(--secondary);
}
.card-footer {
padding: 2rem;
background: #fafbfc;
border-top: 1px solid rgba(0, 0, 0, 0.05);
}
.status-ready {
display: flex;
align-items: center;
justify-content: center;
gap: 0.75rem;
padding: 0.75rem 1.25rem;
background: var(--gradient-success);
color: white;
border-radius: 50px;
font-weight: 600;
font-size: 0.875rem;
margin-bottom: 1.5rem;
}
.btn-analyze {
width: 100%;
padding: 1.25rem;
background: var(--gradient-primary);
color: white;
border: none;
border-radius: var(--radius-lg);
font-size: 1rem;
font-weight: 600;
margin-bottom: 1rem;
position: relative;
overflow: hidden;
transition: all 0.3s ease;
cursor: pointer;
}
.btn-analyze:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-xl);
}
.btn-analyze:active {
transform: translateY(0);
}
.btn-content {
display: flex;
align-items: center;
justify-content: center;
gap: 0.75rem;
position: relative;
z-index: 2;
}
.btn-shine {
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);
transition: left 0.6s;
}
.btn-analyze:hover .btn-shine {
left: 100%;
}
.quick-actions-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
}
.quick-action-btn {
background: white;
border: 2px solid;
border-radius: 1rem;
padding: 1.5rem 1rem;
text-decoration: none;
text-align: center;
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
min-height: 140px;
}
.quick-action-btn:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
text-decoration: none;
}
.quick-action-btn.risk {
border-color: #ff6b6b;
color: #e03131;
}
.quick-action-btn.risk:hover {
background: #fff5f5;
}
.quick-action-btn.batch {
border-color: #4ecdc4;
color: #0ca5a5;
}
.quick-action-btn.batch:hover {
background: #f0fdfc;
}
.quick-action-btn.trends {
border-color: #51cf66;
color: #37b24d;
}
.quick-action-btn.trends:hover {
background: #f4fcf4;
}
.quick-action-icon {
width: 50px;
height: 50px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 1rem;
font-size: 1.25rem;
color: white;
}
.quick-action-btn.risk .quick-action-icon {
background: #ff6b6b;
}
.quick-action-btn.batch .quick-action-icon {
background: #4ecdc4;
}
.quick-action-btn.trends .quick-action-icon {
background: #51cf66;
}
.quick-action-label {
font-weight: 700;
font-size: 1rem;
margin-bottom: 0.5rem;
line-height: 1.2;
}
.quick-action-subtitle {
font-size: 0.875rem;
opacity: 0.8;
line-height: 1.3;
}
.status-unavailable {
display: flex;
align-items: center;
justify-content: center;
gap: 0.75rem;
padding: 0.75rem 1.25rem;
background: #f1f5f9;
color: var(--secondary);
border-radius: 50px;
font-weight: 600;
font-size: 0.875rem;
margin-bottom: 1.5rem;
border: 1px solid #e2e8f0;
}
.btn-disabled {
width: 100%;
padding: 1.25rem;
background: #e2e8f0;
color: var(--secondary);
border: none;
border-radius: var(--radius-lg);
font-size: 1rem;
font-weight: 600;
cursor: not-allowed;
display: flex;
align-items: center;
justify-content: center;
gap: 0.75rem;
}
/* Empty State */
.empty-state {
grid-column: 1 / -1;
background: white;
border-radius: var(--radius-xl);
padding: 4rem 2rem;
text-align: center;
box-shadow: var(--shadow-lg);
position: relative;
overflow: hidden;
}
.empty-illustration {
position: relative;
margin-bottom: 2rem;
}
.empty-illustration i {
font-size: 5rem;
color: #cbd5e1;
}
.empty-glow {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 150px;
height: 150px;
background: radial-gradient(circle, rgba(37, 99, 235, 0.1) 0%, transparent 70%);
border-radius: 50%;
animation: pulse 3s ease-in-out infinite;
}
.empty-state h3 {
font-size: 1.875rem;
font-weight: 700;
color: #1e293b;
margin-bottom: 1rem;
}
.empty-state p {
font-size: 1.125rem;
color: var(--secondary);
margin-bottom: 2rem;
max-width: 500px;
margin-left: auto;
margin-right: auto;
}
.btn-create {
padding: 1rem 2rem;
background: var(--gradient-primary);
color: white;
text-decoration: none;
border-radius: var(--radius-lg);
font-weight: 600;
font-size: 1rem;
display: inline-flex;
align-items: center;
gap: 0.75rem;
transition: all 0.3s ease;
}
.btn-create:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-xl);
color: white;
}
/* Animations */
@@keyframes float {
0%, 100% { transform: translateY(0px); }
50% { transform: translateY(-20px); }
}
@@keyframes pulse {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.8; transform: scale(1.05); }
}
@@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
@@keyframes pulse-ring {
0% { transform: scale(1); opacity: 0.3; }
50% { transform: scale(1.1); opacity: 0.1; }
100% { transform: scale(1); opacity: 0.3; }
}
@@keyframes shimmer {
0% { transform: translateX(-100%); }
100% { transform: translateX(200%); }
}
/* Responsive Design */
@@media (max-width: 1200px) {
.questionnaires-grid {
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
}
}
@@media (max-width: 768px) {
.hero-banner {
min-height: 40vh;
}
.hero-title {
font-size: 2.5rem;
}
.hero-subtitle {
font-size: 1rem;
}
.hero-actions {
flex-direction: column;
}
.btn-hero-primary,
.btn-hero-secondary {
width: 100%;
justify-content: center;
}
.questionnaires-grid {
grid-template-columns: 1fr;
}
.stats-grid {
grid-template-columns: 1fr;
}
.quick-actions-grid {
grid-template-columns: 1fr;
}
.status-services {
flex-direction: column;
gap: 1rem;
}
.floating-card {
display: none;
}
.company-badge {
position: relative;
top: auto;
right: auto;
margin: 1rem 0;
}
.modal-content-wrapper {
padding: 1.5rem;
}
.modal-header-content {
padding: 1.5rem;
}
.modal-footer-modern {
padding: 1.5rem;
flex-direction: column;
}
.btn-secondary-modern,
.btn-primary-modern {
width: 100%;
justify-content: center;
}
}
@@media (max-width: 480px) {
.hero-banner {
min-height: 35vh;
}
.card-header,
.card-body,
.card-footer {
padding: 1.5rem;
}
.main-content {
padding: 2rem 0;
}
.hero-title {
font-size: 2rem;
}
.section-title {
font-size: 2rem;
flex-direction: column;
gap: 0.5rem;
}
.quick-action-btn {
padding: 1rem 0.75rem;
}
.quick-action-icon {
width: 40px;
height: 40px;
font-size: 1rem;
}
}
/* Enhanced Modals */
.modal-backdrop {
backdrop-filter: blur(12px);
background-color: rgba(15, 23, 42, 0.6);
}
.modern-modal {
border: none;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
overflow: hidden;
}
.rounded-5 {
border-radius: 1.5rem !important;
}
.modal-header-modern {
padding: 0;
border: none;
background: var(--gradient-primary);
position: relative;
overflow: hidden;
}
.modal-header-modern::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, rgba(255,255,255,0.1) 0%, transparent 50%);
}
.modal-header-content {
display: flex;
align-items: center;
gap: 1.5rem;
padding: 2rem 2.5rem;
position: relative;
z-index: 2;
}
.modal-icon {
width: 60px;
height: 60px;
background: rgba(255, 255, 255, 0.15);
backdrop-filter: blur(10px);
border-radius: var(--radius-lg);
display: flex;
align-items: center;
justify-content: center;
font-size: 1.5rem;
color: white;
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
}
.modal-title-section .modal-title {
font-size: 1.375rem;
font-weight: 700;
color: white;
margin-bottom: 0.25rem;
}
.modal-subtitle {
font-size: 0.875rem;
color: rgba(255, 255, 255, 0.8);
margin: 0;
}
.modern-close {
position: absolute;
top: 1.5rem;
right: 1.5rem;
width: 44px;
height: 44px;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
z-index: 3;
border: 1px solid rgba(255, 255, 255, 0.2);
}
.modern-close:hover {
background: rgba(255, 255, 255, 0.2);
transform: scale(1.05);
}
.modal-body-modern {
padding: 0;
background: #fafbfc;
}
.modal-content-wrapper {
padding: 2.5rem;
background: white;
}
.input-group-modern {
position: relative;
}
.form-label-modern {
display: flex;
align-items: center;
font-weight: 600;
color: #1e293b;
margin-bottom: 1rem;
font-size: 0.9rem;
}
.form-control-modern {
width: 100%;
padding: 1.25rem 1.5rem;
border: 2px solid #e2e8f0;
border-radius: var(--radius-lg);
background: #f8fafc;
font-size: 0.9rem;
transition: all 0.3s ease;
resize: vertical;
font-family: inherit;
}
.form-control-modern:focus {
outline: none;
border-color: var(--primary);
background: white;
box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.1);
}
.form-help {
display: flex;
align-items: flex-start;
gap: 0.75rem;
margin-top: 1rem;
font-size: 0.8rem;
color: #64748b;
padding: 1rem 1.25rem;
background: linear-gradient(135deg, #f1f5f9, #e2e8f0);
border-radius: var(--radius-md);
border-left: 4px solid var(--primary);
}
.results-divider {
height: 1px;
background: linear-gradient(90deg, transparent, #e2e8f0, transparent);
margin: 2.5rem 0;
}
.results-header {
display: flex;
align-items: center;
gap: 0.75rem;
font-weight: 700;
color: #1e293b;
font-size: 1.125rem;
margin-bottom: 2rem;
padding-bottom: 0.75rem;
border-bottom: 2px solid #f1f5f9;
}
.modal-footer-modern {
padding: 1.5rem 2.5rem;
background: #f8fafc;
border: none;
display: flex;
gap: 1rem;
justify-content: flex-end;
border-top: 1px solid #e2e8f0;
}
.btn-secondary-modern {
padding: 0.875rem 1.75rem;
background: white;
color: #64748b;
border: 2px solid #e2e8f0;
border-radius: var(--radius-lg);
font-weight: 600;
font-size: 0.875rem;
transition: all 0.3s ease;
display: flex;
align-items: center;
gap: 0.5rem;
}
.btn-secondary-modern:hover {
background: #f1f5f9;
border-color: #cbd5e1;
color: #475569;
transform: translateY(-1px);
}
.btn-primary-modern {
padding: 0.875rem 1.75rem;
background: var(--gradient-primary);
color: white;
border: 2px solid transparent;
border-radius: var(--radius-lg);
font-weight: 600;
font-size: 0.875rem;
transition: all 0.3s ease;
display: flex;
align-items: center;
gap: 0.5rem;
position: relative;
overflow: hidden;
}
.btn-primary-modern:hover {
transform: translateY(-1px);
box-shadow: 0 10px 25px rgba(37, 99, 235, 0.3);
}
.btn-primary-modern::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
transition: left 0.5s;
}
.btn-primary-modern:hover::before {
left: 100%;
}
/* Service Status Cards - Modern Design */
.service-status-card {
background: white;
border-radius: var(--radius-lg);
padding: 1.5rem;
margin-bottom: 1rem;
border: 2px solid;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.service-status-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: currentColor;
}
.service-status-card.online {
border-color: rgba(37, 99, 235, 0.2);
color: var(--primary);
background: linear-gradient(135deg, rgba(37, 99, 235, 0.02), rgba(37, 99, 235, 0.05));
}
.service-status-card.offline {
border-color: rgba(239, 68, 68, 0.2);
color: var(--danger);
background: linear-gradient(135deg, rgba(239, 68, 68, 0.02), rgba(239, 68, 68, 0.05));
}
.service-card-header {
display: flex;
align-items: center;
gap: 1rem;
margin-bottom: 0.75rem;
}
.service-card-icon {
width: 48px;
height: 48px;
border-radius: var(--radius-md);
display: flex;
align-items: center;
justify-content: center;
font-size: 1.25rem;
background: rgba(255, 255, 255, 0.8);
border: 2px solid currentColor;
}
.service-card-content h6 {
font-weight: 700;
color: #1e293b;
margin-bottom: 0.25rem;
font-size: 1rem;
}
.service-card-content p {
color: #64748b;
margin: 0;
font-size: 0.875rem;
}
.service-status-indicator {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.5rem 1rem;
background: rgba(255, 255, 255, 0.6);
border-radius: 50px;
font-size: 0.875rem;
font-weight: 600;
margin-top: 1rem;
}
.status-dot {
width: 10px;
height: 10px;
border-radius: 50%;
background: currentColor;
animation: pulse 2s infinite;
}
.summary-card {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-radius: var(--radius-lg);
padding: 2rem;
margin-top: 1.5rem;
position: relative;
overflow: hidden;
}
.summary-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, rgba(255,255,255,0.1) 0%, transparent 50%);
}
.summary-content {
position: relative;
z-index: 2;
}
.summary-icon {
width: 60px;
height: 60px;
background: rgba(255, 255, 255, 0.2);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.5rem;
margin-bottom: 1rem;
}
/* Loading State - Modern Design */
.loading-state {
text-align: center;
padding: 3rem 2rem;
}
.loading-animation {
margin-bottom: 2rem;
}
.spinner-modern {
width: 60px;
height: 60px;
border: 3px solid #e2e8f0;
border-top: 3px solid var(--primary);
border-radius: 50%;
animation: spin 1s linear infinite;
}
.loading-title {
font-size: 1.125rem;
font-weight: 600;
color: #1e293b;
margin-bottom: 0.5rem;
}
.loading-subtitle {
color: var(--secondary);
margin: 0;
}
/* Analysis Results Styling */
.result-card {
background: white;
border: 2px solid #f1f5f9;
border-radius: var(--radius-lg);
padding: 1.5rem;
transition: all 0.3s ease;
height: 100%;
}
.result-card:hover {
border-color: #e2e8f0;
transform: translateY(-2px);
box-shadow: var(--shadow-md);
}
.result-header {
display: flex;
align-items: center;
gap: 1rem;
margin-bottom: 1.5rem;
}
.result-icon {
width: 48px;
height: 48px;
border-radius: var(--radius-md);
display: flex;
align-items: center;
justify-content: center;
font-size: 1.125rem;
color: white;
}
.result-icon.sentiment {
background: linear-gradient(135deg, #ec4899, #be185d);
}
.result-icon.risk {
background: linear-gradient(135deg, #ef4444, #dc2626);
}
.result-info h6 {
font-weight: 700;
color: #1e293b;
margin-bottom: 0.25rem;
font-size: 0.875rem;
}
.result-info p {
color: #64748b;
margin: 0;
font-size: 0.75rem;
}
.result-value {
display: flex;
justify-content: center;
}
.badge-modern {
padding: 0.5rem 1.25rem;
border-radius: 50px;
font-weight: 600;
font-size: 0.875rem;
border: 2px solid currentColor;
}
.insights-section {
background: #f8fafc;
border-radius: var(--radius-lg);
padding: 1.5rem;
border: 1px solid #e2e8f0;
}
.section-header {
display: flex;
align-items: center;
gap: 1rem;
margin-bottom: 1.25rem;
}
.section-icon {
width: 40px;
height: 40px;
background: var(--gradient-primary);
border-radius: var(--radius-md);
display: flex;
align-items: center;
justify-content: center;
font-size: 1rem;
color: white;
}
.section-info h6 {
font-weight: 700;
color: #1e293b;
margin-bottom: 0.25rem;
font-size: 0.875rem;
}
.section-info p {
color: #64748b;
margin: 0;
font-size: 0.75rem;
}
.phrases-grid,
.categories-grid {
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
min-height: 2rem;
align-items: flex-start;
}
.phrase-tag {
background: white;
color: #1e293b;
padding: 0.5rem 1rem;
border-radius: var(--radius-md);
border: 2px solid #e2e8f0;
font-size: 0.8rem;
font-weight: 500;
transition: all 0.2s ease;
}
.phrase-tag:hover {
border-color: var(--primary);
transform: translateY(-1px);
}
.category-tag {
background: linear-gradient(135deg, var(--info), #0891b2);
color: white;
padding: 0.5rem 1rem;
border-radius: var(--radius-md);
border: 2px solid transparent;
font-size: 0.8rem;
font-weight: 500;
transition: all 0.2s ease;
}
.category-tag:hover {
transform: translateY(-1px);
box-shadow: var(--shadow-sm);
}
.empty-result {
color: #94a3b8;
font-style: italic;
font-size: 0.875rem;
text-align: center;
width: 100%;
padding: 1rem;
}
/* Progress Modal Enhancements */
.progress-illustration {
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.progress-icon {
width: 80px;
height: 80px;
background: var(--gradient-primary);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
color: white;
position: relative;
z-index: 2;
}
.progress-circles {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.circle {
position: absolute;
border: 2px solid var(--primary);
border-radius: 50%;
opacity: 0.3;
}
.circle-1 {
width: 100px;
height: 100px;
top: -50px;
left: -50px;
animation: pulse-ring 2s ease-in-out infinite;
}
.circle-2 {
width: 130px;
height: 130px;
top: -65px;
left: -65px;
animation: pulse-ring 2s ease-in-out infinite 0.5s;
}
.circle-3 {
width: 160px;
height: 160px;
top: -80px;
left: -80px;
animation: pulse-ring 2s ease-in-out infinite 1s;
}
.progress-title {
font-size: 1.125rem;
font-weight: 600;
color: #1e293b;
}
.progress-modern {
height: 12px;
background: #e2e8f0;
border-radius: 6px;
overflow: hidden;
box-shadow: inset 0 2px 4px rgba(0,0,0,0.1);
}
.progress-bar-modern {
background: var(--gradient-primary);
border-radius: 6px;
transition: width 0.3s ease;
position: relative;
overflow: hidden;
}
.progress-bar-modern::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);
animation: shimmer 1.5s ease-in-out infinite;
}
.progress-steps {
display: flex;
flex-direction: column;
gap: 1rem;
text-align: left;
max-width: 300px;
margin: 0 auto;
}
.progress-step {
display: flex;
align-items: center;
gap: 1rem;
transition: all 0.3s ease;
opacity: 0.5;
}
.progress-step.step-active {
opacity: 1;
}
.progress-step.step-completed {
opacity: 1;
}
.progress-step.step-completed .step-text {
color: var(--success);
font-weight: 500;
}
.step-icon {
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.875rem;
}
.step-text {
font-size: 0.875rem;
color: #64748b;
}
.progress-step.step-active .step-text {
color: #1e293b;
font-weight: 500;
}
/* Bootstrap enhancements */
.dropdown-menu {
border: none;
box-shadow: var(--shadow-lg);
border-radius: var(--radius-md);
padding: 0.5rem 0;
}
.dropdown-item {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.75rem 1.25rem;
transition: all 0.2s ease;
}
.dropdown-item:hover {
background: #f8fafc;
}
.dropdown-item i {
width: 1.25rem;
}
</style>
}