309 lines
20 KiB
Text
309 lines
20 KiB
Text
@model QuestionnaireViewModel
|
|
@{
|
|
ViewData["Title"] = "Questionnaire Details";
|
|
var totalAnswers = Model.Questions?.Sum(q => q.Answers?.Count ?? 0) ?? 0;
|
|
var otherCount = Model.Questions?.Count(q => q.Answers != null && q.Answers.Any(a => a.IsOtherOption)) ?? 0;
|
|
var typeCount = Model.Questions?.Select(q => q.Type).Distinct().Count() ?? 0;
|
|
var qCount = Model.Questions?.Count ?? 0;
|
|
}
|
|
|
|
<style>
|
|
@@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap');
|
|
:root {
|
|
--bg:#0f1923;--bg-card:#1a2332;--bg-elevated:#1f2b3d;--bg-input:#16202e;
|
|
--text-primary:#e8edf2;--text-secondary:#9ba8b9;--text-muted:#5e6e82;--text-faint:#3d4e63;
|
|
--teal:#33b3ae;--teal-soft:rgba(51,179,174,0.1);--teal-medium:rgba(51,179,174,0.2);--teal-glow:rgba(51,179,174,0.12);--teal-dark:#2a9490;
|
|
--amber:#f59e0b;--amber-soft:rgba(245,158,11,0.1);--amber-border:rgba(245,158,11,0.35);
|
|
--purple:#7c3aed;--purple-soft:rgba(124,58,237,0.1);--purple-border:rgba(124,58,237,0.35);
|
|
--red:#ef4444;--red-soft:rgba(239,68,68,0.1);
|
|
--green:#10b981;--green-soft:rgba(16,185,129,0.1);--green-border:rgba(16,185,129,0.35);
|
|
--info:#06b6d4;--info-soft:rgba(6,182,212,0.1);--info-border:rgba(6,182,212,0.35);
|
|
--border:rgba(255,255,255,0.06);--border-light:rgba(255,255,255,0.04);
|
|
--shadow-xs:0 1px 3px rgba(0,0,0,0.2);--shadow-sm:0 2px 8px rgba(0,0,0,0.25);--shadow-md:0 4px 16px rgba(0,0,0,0.3);--shadow-lg:0 8px 32px rgba(0,0,0,0.35);--shadow-teal:0 4px 20px rgba(51,179,174,0.2);
|
|
--radius-sm:8px;--radius-md:12px;--radius-lg:16px;
|
|
--transition:all 0.2s cubic-bezier(0.4,0,0.2,1);--transition-spring:all 0.35s cubic-bezier(0.34,1.56,0.64,1);
|
|
}
|
|
@@keyframes slideUp{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}}
|
|
@@keyframes scaleIn{from{opacity:0;transform:scale(0.96)}to{opacity:1;transform:scale(1)}}
|
|
@@keyframes fadeIn{from{opacity:0}to{opacity:1}}
|
|
@@keyframes pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.08)}}
|
|
@@keyframes shimmer{0%{background-position:-200% 0}100%{background-position:200% 0}}
|
|
*{box-sizing:border-box}
|
|
|
|
.details-page{font-family:'Inter',-apple-system,BlinkMacSystemFont,sans-serif;background:var(--bg);min-height:100vh;padding:32px 40px 80px;-webkit-font-smoothing:antialiased;color:var(--text-primary)}
|
|
|
|
/* ===== PAGE HEADER ===== */
|
|
.page-top{max-width:1100px;margin:0 auto 28px;animation:slideUp .5s ease both}
|
|
.page-breadcrumb{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--text-muted);margin-bottom:16px}
|
|
.page-breadcrumb a{color:var(--text-muted);text-decoration:none;transition:var(--transition)}
|
|
.page-breadcrumb a:hover{color:var(--teal)}
|
|
.page-breadcrumb .sep{color:var(--text-faint)}
|
|
.page-title-row{display:flex;align-items:center;justify-content:space-between;gap:20px;flex-wrap:wrap}
|
|
.page-title{font-size:28px;font-weight:700;color:var(--text-primary);letter-spacing:-0.5px;margin:0;display:flex;align-items:center;gap:14px}
|
|
.page-title-icon{width:44px;height:44px;border-radius:var(--radius-md);background:linear-gradient(135deg,var(--teal),var(--teal-dark));display:flex;align-items:center;justify-content:center;font-size:20px;color:#fff;box-shadow:var(--shadow-teal)}
|
|
.page-title-accent{display:inline-block;width:8px;height:8px;background:var(--teal);border-radius:50%;margin-left:4px;vertical-align:super;animation:pulse 2s ease infinite}
|
|
.btn-back{display:inline-flex;align-items:center;gap:8px;padding:10px 22px;background:var(--bg-card);color:var(--text-secondary);border:1.5px solid var(--border);border-radius:var(--radius-sm);font-size:13px;font-weight:500;font-family:inherit;cursor:pointer;transition:var(--transition);text-decoration:none}
|
|
.btn-back:hover{background:var(--bg-elevated);border-color:rgba(255,255,255,0.1);color:var(--text-primary);text-decoration:none}
|
|
|
|
/* ===== STATS BAR ===== */
|
|
.stats-bar{max-width:1100px;margin:0 auto 24px;display:grid;grid-template-columns:repeat(4,1fr);gap:16px;animation:slideUp .5s ease .08s both}
|
|
.stat-card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius-md);padding:20px 24px;text-align:center;transition:var(--transition);position:relative;overflow:hidden}
|
|
.stat-card::before{content:'';position:absolute;top:0;left:0;right:0;height:3px;border-radius:3px 3px 0 0}
|
|
.stat-card:nth-child(1)::before{background:var(--teal)}
|
|
.stat-card:nth-child(2)::before{background:var(--info)}
|
|
.stat-card:nth-child(3)::before{background:var(--amber)}
|
|
.stat-card:nth-child(4)::before{background:var(--purple)}
|
|
.stat-card:hover{box-shadow:var(--shadow-sm);border-color:rgba(255,255,255,0.1);transform:translateY(-2px)}
|
|
.stat-number{font-size:32px;font-weight:800;line-height:1;margin-bottom:6px;background:linear-gradient(135deg,var(--text-primary),var(--text-secondary));-webkit-background-clip:text;-webkit-text-fill-color:transparent}
|
|
.stat-card:nth-child(1) .stat-number{background:linear-gradient(135deg,var(--teal),#5eead4);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
|
|
.stat-card:nth-child(2) .stat-number{background:linear-gradient(135deg,var(--info),#67e8f9);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
|
|
.stat-card:nth-child(3) .stat-number{background:linear-gradient(135deg,var(--amber),#fcd34d);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
|
|
.stat-card:nth-child(4) .stat-number{background:linear-gradient(135deg,var(--purple),#a78bfa);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
|
|
.stat-label{font-size:12px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:0.6px}
|
|
|
|
/* ===== META CARD ===== */
|
|
.meta-card{max-width:1100px;margin:0 auto 24px;background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius-lg);padding:28px 32px;box-shadow:var(--shadow-xs);animation:slideUp .5s ease .12s both;transition:var(--transition)}
|
|
.meta-card:hover{box-shadow:var(--shadow-sm);border-color:rgba(255,255,255,0.08)}
|
|
.meta-section-header{display:flex;align-items:center;gap:12px;margin-bottom:20px}
|
|
.meta-section-icon{width:36px;height:36px;border-radius:var(--radius-sm);display:flex;align-items:center;justify-content:center;font-size:16px;color:#fff}
|
|
.meta-section-icon.info-icon{background:var(--info)}
|
|
.meta-section-title{font-size:16px;font-weight:700;color:var(--text-primary);margin:0}
|
|
.meta-grid{display:grid;grid-template-columns:1fr 1fr;gap:20px}
|
|
.meta-item{padding:16px 20px;background:var(--bg-elevated);border:1px solid var(--border-light);border-radius:var(--radius-sm);transition:var(--transition)}
|
|
.meta-item:hover{border-color:rgba(255,255,255,0.08)}
|
|
.meta-item.full-width{grid-column:1/-1}
|
|
.meta-label{font-size:11px;font-weight:700;color:var(--text-muted);text-transform:uppercase;letter-spacing:0.6px;margin-bottom:8px;display:flex;align-items:center;gap:6px}
|
|
.meta-label i{font-size:12px;color:var(--teal)}
|
|
.meta-value{font-size:15px;font-weight:600;color:var(--text-primary);line-height:1.4;word-break:break-word}
|
|
.meta-value.id-value{color:var(--teal);font-family:'JetBrains Mono',monospace}
|
|
.description-value{font-size:14px;font-weight:400;color:var(--text-secondary);line-height:1.7}
|
|
.description-value p{margin:0}
|
|
.empty-desc{color:var(--text-faint);font-style:italic;font-weight:400}
|
|
|
|
/* ===== QUESTIONS SECTION ===== */
|
|
.questions-section{max-width:1100px;margin:0 auto;animation:slideUp .5s ease .18s both}
|
|
.questions-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;flex-wrap:wrap;gap:12px}
|
|
.questions-title{display:flex;align-items:center;gap:12px}
|
|
.questions-icon{width:36px;height:36px;border-radius:var(--radius-sm);background:var(--green);display:flex;align-items:center;justify-content:center;font-size:16px;color:#fff}
|
|
.questions-title h2{font-size:18px;font-weight:700;color:var(--text-primary);margin:0}
|
|
.questions-count-pill{display:flex;align-items:center;gap:6px;background:var(--green-soft);border:1px solid var(--green-border);border-radius:100px;padding:6px 16px;font-size:12px;font-weight:600;color:var(--green)}
|
|
|
|
/* ===== QUESTION CARD ===== */
|
|
.q-card{background:var(--bg-card);border:1.5px solid var(--border);border-radius:var(--radius-md);margin-bottom:16px;overflow:hidden;transition:var(--transition);box-shadow:var(--shadow-xs)}
|
|
.q-card:hover{box-shadow:var(--shadow-sm);border-color:rgba(255,255,255,0.1)}
|
|
.q-card-header{padding:18px 24px;display:flex;align-items:center;gap:14px;cursor:pointer;transition:var(--transition);position:relative}
|
|
.q-card-header:hover{background:var(--bg-elevated)}
|
|
.q-card-header::after{content:'';position:absolute;bottom:0;left:24px;right:24px;height:1px;background:var(--border-light)}
|
|
.q-num{width:32px;height:32px;border-radius:var(--radius-sm);background:var(--teal);color:#fff;display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:700;flex-shrink:0}
|
|
.q-text-wrap{flex:1;min-width:0}
|
|
.q-text{font-size:15px;font-weight:600;color:var(--text-primary);margin:0;line-height:1.5}
|
|
.q-meta-tags{display:flex;align-items:center;gap:8px;margin-top:6px;flex-wrap:wrap}
|
|
.q-tag{font-size:10px;font-weight:600;padding:3px 10px;border-radius:100px;white-space:nowrap;text-transform:uppercase;letter-spacing:0.3px}
|
|
.q-tag.type-tag{color:var(--teal);background:var(--teal-soft);border:1px solid var(--teal-medium)}
|
|
.q-tag.id-tag{color:var(--text-muted);background:var(--bg-input);border:1px solid var(--border)}
|
|
.q-tag.ans-count-tag{color:var(--info);background:var(--info-soft);border:1px solid var(--info-border)}
|
|
.q-tag.other-tag{color:var(--amber);background:var(--amber-soft);border:1px solid var(--amber-border)}
|
|
.q-chevron{color:var(--text-faint);font-size:14px;transition:transform .25s ease;padding:4px;flex-shrink:0}
|
|
.q-chevron.open{transform:rotate(180deg)}
|
|
|
|
/* ===== ANSWER AREA ===== */
|
|
.q-answers{display:none;padding:20px 24px;animation:fadeIn .2s ease}
|
|
.q-answers.show{display:block}
|
|
.ans-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:10px}
|
|
.ans-card{display:flex;align-items:flex-start;gap:10px;padding:12px 16px;background:var(--bg-elevated);border:1.5px solid var(--border);border-radius:var(--radius-sm);transition:var(--transition);position:relative}
|
|
.ans-card:hover{border-color:rgba(255,255,255,0.1);background:var(--bg-hover)}
|
|
.ans-card.is-other{border-color:var(--amber-border);background:var(--amber-soft)}
|
|
.ans-card.is-other::before{content:'OTHER';position:absolute;top:-7px;left:12px;background:var(--amber);color:#fff;padding:1px 7px;border-radius:4px;font-size:8px;font-weight:700;letter-spacing:0.5px}
|
|
.ans-bullet{width:24px;height:24px;border-radius:6px;background:var(--info-soft);border:1px solid var(--info-border);display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;color:var(--info);flex-shrink:0;margin-top:1px}
|
|
.ans-card.is-other .ans-bullet{background:var(--amber-soft);border-color:var(--amber-border);color:var(--amber)}
|
|
.ans-content{flex:1;min-width:0}
|
|
.ans-text{font-size:13px;font-weight:500;color:var(--text-primary);line-height:1.5;word-break:break-word}
|
|
.ans-id{font-size:10px;color:var(--text-faint);margin-top:3px;font-family:'JetBrains Mono',monospace}
|
|
|
|
/* ===== EMPTY STATE ===== */
|
|
.empty-state{text-align:center;padding:48px 24px;color:var(--text-muted)}
|
|
.empty-state-icon{width:64px;height:64px;border-radius:var(--radius-lg);background:var(--bg-elevated);display:flex;align-items:center;justify-content:center;font-size:28px;color:var(--text-faint);margin:0 auto 16px}
|
|
.empty-state h3{font-size:16px;font-weight:600;color:var(--text-secondary);margin:0 0 6px}
|
|
.empty-state p{font-size:13px;color:var(--text-muted);margin:0}
|
|
|
|
.no-answers-msg{text-align:center;padding:20px;color:var(--text-muted);font-size:13px;font-style:italic}
|
|
|
|
/* ===== FOOTER ===== */
|
|
.footer-row{max-width:1100px;margin:28px auto 0;display:flex;justify-content:center;gap:12px;animation:slideUp .5s ease .25s both}
|
|
.btn-edit{display:inline-flex;align-items:center;gap:8px;padding:12px 28px;background:var(--teal);color:#fff;border:none;border-radius:var(--radius-sm);font-size:14px;font-weight:600;font-family:inherit;cursor:pointer;transition:var(--transition-spring);box-shadow:var(--shadow-teal);text-decoration:none}
|
|
.btn-edit:hover{background:var(--teal-dark);transform:translateY(-2px);box-shadow:0 8px 28px rgba(51,179,174,0.25);color:#fff;text-decoration:none}
|
|
|
|
/* ===== RESPONSIVE ===== */
|
|
@@media(max-width:768px){
|
|
.details-page{padding:16px}
|
|
.stats-bar{grid-template-columns:repeat(2,1fr);gap:10px}
|
|
.meta-grid{grid-template-columns:1fr}
|
|
.ans-grid{grid-template-columns:1fr}
|
|
.page-title-row{flex-direction:column;align-items:flex-start}
|
|
.footer-row{flex-direction:column}
|
|
.footer-row .btn-back,.footer-row .btn-edit{width:100%;justify-content:center}
|
|
}
|
|
</style>
|
|
|
|
<div class="details-page">
|
|
|
|
<!-- Page Header -->
|
|
<div class="page-top">
|
|
<div class="page-breadcrumb">
|
|
<a href="@Url.Action("Index", "Questionnaire")">Questionnaires</a>
|
|
<span class="sep">/</span>
|
|
<span>Details</span>
|
|
</div>
|
|
<div class="page-title-row">
|
|
<h1 class="page-title">
|
|
<span class="page-title-icon"><i class="bi bi-file-text-fill"></i></span>
|
|
Questionnaire Details<span class="page-title-accent"></span>
|
|
</h1>
|
|
<a href="@Url.Action("Index", "Questionnaire")" class="btn-back"><i class="bi bi-arrow-left"></i> Back to List</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Stats Bar -->
|
|
<div class="stats-bar">
|
|
<div class="stat-card">
|
|
<div class="stat-number">@qCount</div>
|
|
<div class="stat-label">Questions</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-number">@totalAnswers</div>
|
|
<div class="stat-label">Total Answers</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-number">@otherCount</div>
|
|
<div class="stat-label">Other Options</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-number">@typeCount</div>
|
|
<div class="stat-label">Question Types</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Overview Meta -->
|
|
<div class="meta-card">
|
|
<div class="meta-section-header">
|
|
<div class="meta-section-icon info-icon"><i class="bi bi-info-circle-fill"></i></div>
|
|
<h2 class="meta-section-title">Overview</h2>
|
|
</div>
|
|
<div class="meta-grid">
|
|
<div class="meta-item">
|
|
<div class="meta-label"><i class="bi bi-hash"></i> ID</div>
|
|
<div class="meta-value id-value">#@Model.Id</div>
|
|
</div>
|
|
<div class="meta-item">
|
|
<div class="meta-label"><i class="bi bi-card-heading"></i> Title</div>
|
|
<div class="meta-value">@Model.Title</div>
|
|
</div>
|
|
<div class="meta-item full-width">
|
|
<div class="meta-label"><i class="bi bi-card-text"></i> Description</div>
|
|
@if (!string.IsNullOrEmpty(Model.Description))
|
|
{
|
|
<div class="description-value">@Html.Raw(Model.Description)</div>
|
|
}
|
|
else
|
|
{
|
|
<div class="description-value empty-desc">No description provided</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Questions -->
|
|
<div class="questions-section">
|
|
<div class="questions-header">
|
|
<div class="questions-title">
|
|
<div class="questions-icon"><i class="bi bi-question-circle-fill"></i></div>
|
|
<h2>Questions</h2>
|
|
</div>
|
|
<div class="questions-count-pill">
|
|
<i class="bi bi-check2-circle"></i>
|
|
@qCount Question@(qCount != 1 ? "s" : "")
|
|
</div>
|
|
</div>
|
|
|
|
@if (Model.Questions != null && Model.Questions.Any())
|
|
{
|
|
<div class="questions-list">
|
|
@foreach (var question in Model.Questions.Select((q, index) => new { Q = q, Idx = index }))
|
|
{
|
|
var ansCount = question.Q.Answers?.Count ?? 0;
|
|
var hasOther = question.Q.Answers != null && question.Q.Answers.Any(a => a.IsOtherOption);
|
|
<div class="q-card" data-qi="@question.Idx">
|
|
<div class="q-card-header" onclick="toggleQ(@question.Idx)">
|
|
<span class="q-num">@(question.Idx + 1)</span>
|
|
<div class="q-text-wrap">
|
|
<p class="q-text">@question.Q.Text</p>
|
|
<div class="q-meta-tags">
|
|
<span class="q-tag type-tag">@question.Q.Type.ToString().Replace("_", " ")</span>
|
|
<span class="q-tag id-tag">ID: @question.Q.Id</span>
|
|
<span class="q-tag ans-count-tag"><i class="bi bi-list-ul"></i> @ansCount answer@(ansCount != 1 ? "s" : "")</span>
|
|
@if (hasOther)
|
|
{
|
|
<span class="q-tag other-tag"><i class="bi bi-chat-dots"></i> Has Other</span>
|
|
}
|
|
</div>
|
|
</div>
|
|
<span class="q-chevron" id="chevron_@question.Idx"><i class="bi bi-chevron-down"></i></span>
|
|
</div>
|
|
<div class="q-answers" id="qAns_@question.Idx">
|
|
@if (question.Q.Answers != null && question.Q.Answers.Any())
|
|
{
|
|
<div class="ans-grid">
|
|
@foreach (var answer in question.Q.Answers.Select((a, ai) => new { A = a, Ai = ai }))
|
|
{
|
|
<div class="ans-card @(answer.A.IsOtherOption ? "is-other" : "")">
|
|
<span class="ans-bullet">@((char)('A' + answer.Ai))</span>
|
|
<div class="ans-content">
|
|
<div class="ans-text">@answer.A.Text</div>
|
|
<div class="ans-id">ID: @answer.A.Id</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
<div class="no-answers-msg"><i class="bi bi-inbox"></i> No answer options for this question</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
<div class="empty-state">
|
|
<div class="empty-state-icon"><i class="bi bi-question-circle"></i></div>
|
|
<h3>No Questions</h3>
|
|
<p>This questionnaire doesn't contain any questions yet.</p>
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
<!-- Footer -->
|
|
<div class="footer-row">
|
|
<a href="@Url.Action("Index", "Questionnaire")" class="btn-back"><i class="bi bi-arrow-left"></i> Back to List</a>
|
|
<a href="@Url.Action("Edit", "Questionnaire", new { id = Model.Id })" class="btn-edit"><i class="bi bi-pencil"></i> Edit Questionnaire</a>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function toggleQ(idx) {
|
|
const body = document.getElementById('qAns_' + idx);
|
|
const chev = document.getElementById('chevron_' + idx);
|
|
body.classList.toggle('show');
|
|
chev.classList.toggle('open');
|
|
}
|
|
|
|
// Auto-expand first question
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
const first = document.querySelector('.q-answers');
|
|
const firstChev = document.querySelector('.q-chevron');
|
|
if (first) { first.classList.add('show'); }
|
|
if (firstChev) { firstChev.classList.add('open'); }
|
|
});
|
|
</script>
|