622 lines
34 KiB
HTML
622 lines
34 KiB
HTML
{% extends "layouts/base.html" %}
|
|
{% load i18n %}
|
|
{% load static %}
|
|
{% load survey_filters %}
|
|
|
|
{% block title %}{% trans "Survey" %} #{{ survey.id|slice:":8" }} - PX360{% endblock %}
|
|
|
|
{% block extra_css %}
|
|
<style>
|
|
.lang-ar-block {
|
|
direction: rtl;
|
|
text-align: right;
|
|
padding: 8px 12px;
|
|
margin-top: 8px;
|
|
background: #f0f9ff;
|
|
border-radius: 8px;
|
|
border-right: 3px solid #3b82f6;
|
|
font-size: 0.9rem;
|
|
line-height: 1.7;
|
|
color: #1e3a5f;
|
|
}
|
|
.response-language-indicator {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
padding: 3px 8px;
|
|
background: #f0f9ff;
|
|
border: 1px solid #bae6fd;
|
|
border-radius: 6px;
|
|
font-size: 0.7rem;
|
|
font-weight: 600;
|
|
color: #0369a1;
|
|
}
|
|
.response-language-indicator i {
|
|
width: 12px;
|
|
height: 12px;
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<!-- Back Button -->
|
|
<div class="mb-6">
|
|
<a href="{% url 'surveys:instance_list' %}" class="inline-flex items-center gap-2 px-4 py-2 border border-slate-200 rounded-xl text-slate hover:text-navy hover:bg-light transition text-sm font-semibold">
|
|
<i data-lucide="arrow-left" class="w-4 h-4"></i> {% trans "Back to Surveys" %}
|
|
</a>
|
|
</div>
|
|
|
|
<!-- Breadcrumb & Header -->
|
|
<header class="mb-6">
|
|
<div class="flex items-center gap-2 text-sm text-slate mb-2">
|
|
<a href="{% url 'surveys:instance_list' %}">{% trans "Surveys" %}</a>
|
|
<i data-lucide="chevron-right" class="w-4 h-4"></i>
|
|
<span class="font-bold text-navy">#{{ survey.id|slice:":8" }}</span>
|
|
<span class="ml-2 px-2 py-0.5 rounded-full text-[10px] font-bold uppercase tracking-wider
|
|
{% if survey.status == 'completed' %}bg-green-100 text-green-700
|
|
{% elif survey.status == 'sent' %}bg-yellow-100 text-yellow-700
|
|
{% elif survey.status == 'active' %}bg-blue-100 text-blue-700
|
|
{% else %}bg-gray-100 text-gray-700{% endif %}">
|
|
{{ survey.get_status_display }}
|
|
</span>
|
|
</div>
|
|
<div class="flex items-center justify-between">
|
|
<h1 class="text-2xl font-bold text-navy">{{ survey.survey_template.name }}</h1>
|
|
<div class="flex items-center gap-3">
|
|
<span class="px-2.5 py-1 rounded-lg text-xs font-bold bg-light text-navy">{{ survey.survey_template.get_survey_type_display }}</span>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- Score Comparison Banner (if completed) -->
|
|
{% if survey.status == 'completed' and survey.total_score %}
|
|
<div class="bg-gradient-to-br from-navy to-blue rounded-2xl p-6 mb-6 text-white shadow-lg">
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<div class="text-center">
|
|
<div class="text-white/80 text-sm font-semibold mb-2">{% trans "Patient Score" %}</div>
|
|
<div class="text-5xl font-bold mb-1">{{ survey.total_score|floatformat:1 }}</div>
|
|
<div class="text-xl text-white/70">/ 5.0</div>
|
|
</div>
|
|
<div class="text-center md:border-l md:border-white/25">
|
|
<div class="text-white/80 text-sm font-semibold mb-2">{% trans "Template Average" %}</div>
|
|
<div class="text-5xl font-bold mb-1">{{ template_average|floatformat:1 }}</div>
|
|
<div class="text-xl text-white/70">/ 5.0</div>
|
|
</div>
|
|
</div>
|
|
<div class="text-center mt-4">
|
|
{% if survey.total_score >= template_average %}
|
|
<span class="px-4 py-2 bg-white text-green-600 rounded-xl font-bold text-sm inline-flex items-center gap-1">
|
|
<i data-lucide="arrow-up" class="w-4 h-4"></i> {% trans "Above average" %}
|
|
</span>
|
|
{% else %}
|
|
<span class="px-4 py-2 bg-white text-orange-600 rounded-xl font-bold text-sm inline-flex items-center gap-1">
|
|
<i data-lucide="arrow-down" class="w-4 h-4"></i> {% trans "Below average" %}
|
|
</span>
|
|
{% endif %}
|
|
{% if survey.is_negative %}
|
|
<span class="px-4 py-2 bg-red-500 text-white rounded-xl font-bold text-sm inline-flex items-center gap-1 ml-2">
|
|
<i data-lucide="alert-triangle" class="w-4 h-4"></i> {% trans "Negative feedback" %}
|
|
</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Main Content Grid -->
|
|
<div class="grid grid-cols-12 gap-8">
|
|
<!-- Left Column (Content) -->
|
|
<div class="col-span-8 space-y-6">
|
|
|
|
<!-- Survey Responses Card -->
|
|
<section class="bg-white rounded-2xl p-6 shadow-sm border border-slate-100">
|
|
<div class="flex items-center justify-between mb-4">
|
|
<h3 class="font-bold text-navy flex items-center gap-2 text-lg">
|
|
<i data-lucide="message-square" class="w-5 h-5 text-blue"></i>
|
|
{% trans "Survey Responses" %}
|
|
</h3>
|
|
{% if survey.completed_language %}
|
|
<div class="flex items-center gap-2">
|
|
<span class="text-sm text-slate">{% trans "Completed in" %}:</span>
|
|
<span class="response-language-indicator">
|
|
<i data-lucide="globe" class="w-3 h-3"></i>
|
|
{% if survey.completed_language == 'ar' %}{% trans "Arabic" %}{% else %}{% trans "English" %}{% endif %}
|
|
</span>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% if responses %}
|
|
<div class="overflow-x-auto">
|
|
<table class="w-full text-sm border-collapse">
|
|
<thead>
|
|
<tr class="bg-gray-800 text-white">
|
|
<th class="border border-gray-300 px-3 py-2 text-left w-10">#</th>
|
|
<th class="border border-gray-300 px-3 py-2 text-left">{% trans "Question" %}</th>
|
|
<th class="border border-gray-300 px-3 py-2 text-left">{% trans "Question (AR)" %}</th>
|
|
<th class="border border-gray-300 px-3 py-2 text-center w-24">{% trans "Type" %}</th>
|
|
<th class="border border-gray-300 px-3 py-2 text-left w-64">{% trans "Response" %}</th>
|
|
<th class="border border-gray-300 px-3 py-2 text-center w-20">{% trans "Avg" %}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for response in responses %}
|
|
<tr class="{% if forloop.counter|divisibleby:'2' %}bg-gray-50{% endif %} hover:bg-blue-50 transition-colors">
|
|
<td class="border border-gray-300 px-3 py-2 text-center font-bold text-navy">{{ forloop.counter }}</td>
|
|
<td class="border border-gray-300 px-3 py-2">
|
|
<div class="font-semibold text-navy leading-snug">{{ response.question.text }}</div>
|
|
</td>
|
|
<td class="border border-gray-300 px-3 py-2" dir="rtl">
|
|
{% if response.question.text_ar %}
|
|
<div class="text-right leading-snug" style="color: #1e3a5f;">{{ response.question.text_ar }}</div>
|
|
{% endif %}
|
|
</td>
|
|
<td class="border border-gray-300 px-3 py-2 text-center">
|
|
<span class="px-1.5 py-0.5 rounded text-[10px] font-semibold bg-slate-100 text-slate-500">{{ response.question.get_question_type_display }}</span>
|
|
</td>
|
|
<td class="border border-gray-300 px-3 py-2">
|
|
{% if response.question.question_type == 'rating' %}
|
|
<span class="font-bold {% if response.numeric_value >= 4 %}text-green-600{% elif response.numeric_value >= 3 %}text-orange-500{% else %}text-red-500{% endif %}">
|
|
{{ response.numeric_value|floatformat:1 }}
|
|
</span>
|
|
<span class="text-slate-400">/ 5</span>
|
|
|
|
{% elif response.question.question_type == 'nps' %}
|
|
<span class="font-bold {% if response.numeric_value >= 9 %}text-green-600{% elif response.numeric_value >= 7 %}text-blue-600{% else %}text-red-500{% endif %}">
|
|
{{ response.numeric_value|floatformat:0 }}
|
|
</span>
|
|
<span class="text-xs text-slate-400 ml-1">
|
|
{% if response.numeric_value >= 9 %}({% trans "Promoter" %})
|
|
{% elif response.numeric_value >= 7 %}({% trans "Passive" %})
|
|
{% else %}({% trans "Detractor" %}){% endif %}
|
|
</span>
|
|
|
|
{% elif response.question.question_type == 'yes_no' %}
|
|
{% if response.choice_value == 'yes' %}
|
|
<span class="inline-flex items-center gap-1 px-2 py-0.5 bg-green-100 text-green-700 rounded font-semibold text-xs">
|
|
<i data-lucide="check" class="w-3 h-3"></i> {% trans "Yes" %}
|
|
</span>
|
|
{% else %}
|
|
<span class="inline-flex items-center gap-1 px-2 py-0.5 bg-red-100 text-red-700 rounded font-semibold text-xs">
|
|
<i data-lucide="x" class="w-3 h-3"></i> {% trans "No" %}
|
|
</span>
|
|
{% endif %}
|
|
|
|
{% elif response.question.question_type in 'multiple_choice,single_choice' %}
|
|
<span class="{% if survey.completed_language == 'ar' %}ar{% endif %}">{{ response.text_value }}</span>
|
|
|
|
{% elif response.question.question_type in 'text,textarea' and response.text_value %}
|
|
<span class="{% if survey.completed_language == 'ar' %}ar{% endif %} text-slate-700">{{ response.text_value|truncatechars:120 }}</span>
|
|
|
|
{% else %}
|
|
<span class="text-slate-300">—</span>
|
|
{% endif %}
|
|
</td>
|
|
<td class="border border-gray-300 px-3 py-2 text-center text-slate">
|
|
{% if response.question.id in question_stats %}
|
|
{% with question_stat=question_stats|get_item:response.question.id %}
|
|
<span class="font-semibold">{{ question_stat.average|floatformat:1 }}</span>
|
|
{% endwith %}
|
|
{% else %}
|
|
<span class="text-slate-300">—</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
|
|
{% if response.question.question_type in 'text,textarea' and response.text_value and response.text_value|length > 120 %}
|
|
<tr class="{% if forloop.counter|divisibleby:'2' %}bg-gray-50{% endif %}">
|
|
<td class="border border-gray-300"></td>
|
|
<td colspan="3" class="border border-gray-300 px-3 py-2 text-xs text-slate-600 leading-relaxed {% if survey.completed_language == 'ar' %}ar{% endif %}">
|
|
{{ response.text_value }}
|
|
</td>
|
|
<td class="border border-gray-300"></td>
|
|
</tr>
|
|
{% endif %}
|
|
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% else %}
|
|
<div class="text-center py-12">
|
|
<div class="w-20 h-20 mx-auto mb-4 rounded-full bg-slate-50 flex items-center justify-center">
|
|
<i data-lucide="clipboard-list" class="w-10 h-10 text-slate-300"></i>
|
|
</div>
|
|
<p class="text-slate font-semibold">{% trans "No responses yet" %}</p>
|
|
<p class="text-slate-400 text-sm mt-1">{% trans "The patient hasn't submitted any answers" %}</p>
|
|
</div>
|
|
{% endif %}
|
|
</section>
|
|
|
|
<!-- Patient Comment & AI Analysis -->
|
|
{% if survey.status == 'completed' %}
|
|
<section id="patient-comment" class="bg-white rounded-2xl p-6 shadow-sm border border-slate-100">
|
|
<h3 class="font-bold text-navy flex items-center gap-2 mb-6 text-lg">
|
|
<i data-lucide="chat-quote" class="w-5 h-5 text-blue"></i>
|
|
{% trans "Patient Comment" %}
|
|
</h3>
|
|
|
|
{% if survey.comment %}
|
|
<div class="mb-6">
|
|
<div class="bg-slate-50 rounded-xl p-5">
|
|
<p class="text-slate mb-0">{{ survey.comment|linebreaks }}</p>
|
|
</div>
|
|
<span class="text-slate text-sm mt-2 block">
|
|
<i data-lucide="clock" class="w-4 h-4 inline mr-1"></i>{% trans "Submitted" %}: {{ survey.completed_at|date:"M d, Y H:i" }}
|
|
</span>
|
|
</div>
|
|
|
|
<!-- AI Analysis -->
|
|
{% if survey.comment_analyzed and survey.comment_analysis %}
|
|
<div class="bg-light border border-blue-200 rounded-xl p-6">
|
|
<h4 class="font-bold text-navy mb-4 flex items-center gap-2">
|
|
<i data-lucide="sparkles" class="w-5 h-5 text-blue"></i>{% trans "AI Analysis" %}
|
|
</h4>
|
|
|
|
<!-- Sentiment -->
|
|
<div class="mb-4">
|
|
<strong class="text-slate">{% trans "Sentiment" %}:</strong>
|
|
<span class="ml-2 px-2.5 py-1 rounded-lg text-xs font-bold {% if survey.comment_analysis.sentiment == 'positive' %}bg-green-100 text-green-600{% elif survey.comment_analysis.sentiment == 'negative' %}bg-red-100 text-red-600{% else %}bg-slate-100 text-slate-600{% endif %}">
|
|
{{ survey.comment_analysis.sentiment|title }}
|
|
</span>
|
|
{% if survey.comment_analysis.sentiment_score %}
|
|
<span class="text-slate text-sm ml-2">
|
|
(Score: {{ survey.comment_analysis.sentiment_score|floatformat:2 }})
|
|
</span>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Emotion -->
|
|
{% if survey.comment_analysis.emotion %}
|
|
<div class="mb-4">
|
|
<strong class="text-slate">{% trans "Emotion" %}:</strong>
|
|
<span class="ml-2 px-2.5 py-1 rounded-lg text-xs font-bold bg-blue-100 text-blue-600">
|
|
{{ survey.comment_analysis.emotion|title }}
|
|
</span>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Summary -->
|
|
{% if survey.comment_analysis.summary_en %}
|
|
<div class="mb-4">
|
|
<strong class="text-slate">{% trans "Summary" %}:</strong>
|
|
<p class="text-slate mt-2 mb-0">{{ survey.comment_analysis.summary_en }}</p>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Topics -->
|
|
{% if survey.comment_analysis.topics_en %}
|
|
<div class="mb-0">
|
|
<strong class="text-slate">{% trans "Key Topics" %}:</strong>
|
|
<div class="mt-2 flex flex-wrap gap-2">
|
|
{% for topic in survey.comment_analysis.topics_en %}
|
|
<span class="px-3 py-1 bg-white border border-slate-200 text-slate rounded-lg text-sm font-medium">{{ topic }}</span>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% elif survey.comment_analyzed %}
|
|
<div class="bg-amber-50 border border-amber-200 rounded-xl p-4 flex items-center gap-3">
|
|
<i data-lucide="alert-triangle" class="w-6 h-6 text-amber-500 flex-shrink-0"></i>
|
|
<span class="text-amber-700">{% trans "Comment analysis failed. Check system logs for details." %}</span>
|
|
</div>
|
|
{% else %}
|
|
<div class="bg-slate-50 rounded-xl p-4 flex items-center gap-3">
|
|
<i data-lucide="hourglass" class="w-6 h-6 text-slate-400 flex-shrink-0"></i>
|
|
<span class="text-slate">{% trans "Comment is being analyzed by AI..." %}</span>
|
|
</div>
|
|
{% endif %}
|
|
{% else %}
|
|
<div class="text-center py-8">
|
|
<i data-lucide="message-circle" class="w-12 h-12 mx-auto mb-3 text-slate-300"></i>
|
|
<p class="text-slate mb-0">{% trans "No comment provided by patient" %}</p>
|
|
</div>
|
|
{% endif %}
|
|
</section>
|
|
{% endif %}
|
|
|
|
<!-- Related Surveys -->
|
|
{% if related_surveys %}
|
|
<section class="bg-white rounded-2xl p-6 shadow-sm border border-slate-100">
|
|
<h3 class="font-bold text-navy flex items-center gap-2 mb-6 text-lg">
|
|
<i data-lucide="layers" class="w-5 h-5 text-blue"></i>
|
|
{% trans "Related Surveys from Patient" %}
|
|
</h3>
|
|
<div class="overflow-x-auto">
|
|
<table class="w-full">
|
|
<thead class="bg-slate-50 border-b border-slate-100">
|
|
<tr class="text-xs font-bold text-slate uppercase tracking-wider">
|
|
<th class="px-4 py-3 text-left">{% trans "Survey" %}</th>
|
|
<th class="px-4 py-3 text-left">{% trans "Type" %}</th>
|
|
<th class="px-4 py-3 text-left">{% trans "Score" %}</th>
|
|
<th class="px-4 py-3 text-left">{% trans "Date" %}</th>
|
|
<th class="px-4 py-3 text-left">{% trans "Actions" %}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-slate-100 text-sm">
|
|
{% for related in related_surveys %}
|
|
<tr class="hover:bg-light/30 transition">
|
|
<td class="px-4 py-3 text-slate-800">{{ related.survey_template.name }}</td>
|
|
<td class="px-4 py-3">
|
|
<span class="px-2 py-1 rounded-lg text-xs font-bold bg-light text-navy">{{ related.survey_template.get_survey_type_display }}</span>
|
|
</td>
|
|
<td class="px-4 py-3">
|
|
<span class="font-bold {% if related.total_score < 3 %}text-red-500{% elif related.total_score < 4 %}text-orange-500{% else %}text-green-600{% endif %}">
|
|
{{ related.total_score|floatformat:1 }}
|
|
</span>
|
|
</td>
|
|
<td class="px-4 py-3 text-slate text-xs">{{ related.completed_at|date:"M d, Y" }}</td>
|
|
<td class="px-4 py-3">
|
|
<a href="{% url 'surveys:instance_detail' related.id %}"
|
|
class="p-2 text-navy hover:bg-light rounded-lg transition inline-flex items-center gap-1">
|
|
<i data-lucide="eye" class="w-4 h-4"></i>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</section>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Right Column (Sidebar) -->
|
|
<div class="col-span-4 space-y-6">
|
|
|
|
<!-- Survey Link -->
|
|
<section class="bg-white rounded-2xl p-6 shadow-sm border border-slate-100">
|
|
<h3 class="font-bold text-navy mb-4 text-sm flex items-center gap-2">
|
|
<i data-lucide="link" class="w-4 h-4 text-blue"></i>
|
|
{% trans "Survey Link" %}
|
|
</h3>
|
|
<div class="bg-slate-50 rounded-lg p-3 mb-3">
|
|
<code id="survey-url" class="text-xs text-slate break-all">{{ survey_url }}</code>
|
|
</div>
|
|
<button onclick="navigator.clipboard.writeText(document.getElementById('survey-url').textContent); this.textContent='{% trans "Copied!" %}'; setTimeout(() => this.textContent='{% trans "Copy Link" %}', 2000)"
|
|
class="w-full px-4 py-2.5 bg-blue text-white rounded-lg text-sm font-bold flex items-center justify-center gap-2 hover:bg-blue-600 transition">
|
|
<i data-lucide="copy" class="w-4 h-4"></i> {% trans "Copy Link" %}
|
|
</button>
|
|
{% if survey.token_expires_at %}
|
|
<div class="text-xs text-slate mt-2 flex items-center gap-1">
|
|
<i data-lucide="clock" class="w-3 h-3"></i>
|
|
{% trans "Expires" %}: {{ survey.token_expires_at|date:"M d, Y H:i" }}
|
|
</div>
|
|
{% endif %}
|
|
</section>
|
|
|
|
{% if survey.status == 'completed' and survey.comment %}
|
|
<a href="{% url 'surveys:survey_comments_list' %}" class="flex items-center gap-2 px-5 py-3.5 bg-white rounded-2xl shadow-sm border border-slate-100 text-sm font-bold text-navy hover:bg-light transition">
|
|
<i data-lucide="message-circle" class="w-4 h-4 text-blue"></i>
|
|
{% trans "Survey Comments" %}
|
|
<i data-lucide="arrow-right" class="w-3 h-3 text-slate ml-auto"></i>
|
|
</a>
|
|
{% endif %}
|
|
|
|
<!-- Survey Information -->
|
|
<section class="bg-white rounded-2xl p-6 shadow-sm border border-slate-100">
|
|
<h3 class="font-bold text-navy mb-4 text-sm flex items-center gap-2">
|
|
<i data-lucide="info" class="w-4 h-4 text-blue"></i>
|
|
{% trans "Survey Information" %}
|
|
</h3>
|
|
<ul class="space-y-3 text-sm">
|
|
<li class="flex justify-between border-b border-slate-100 pb-2">
|
|
<span class="text-slate">{% trans "Status" %}</span>
|
|
<span class="font-bold">
|
|
{% if survey.status == 'completed' %}
|
|
<span class="px-2 py-0.5 rounded-lg text-xs font-bold bg-green-100 text-green-600">{{ survey.get_status_display }}</span>
|
|
{% elif survey.status == 'sent' %}
|
|
<span class="px-2 py-0.5 rounded-lg text-xs font-bold bg-yellow-100 text-yellow-600">{{ survey.get_status_display }}</span>
|
|
{% elif survey.status == 'active' %}
|
|
<span class="px-2 py-0.5 rounded-lg text-xs font-bold bg-blue-100 text-blue-600">{{ survey.get_status_display }}</span>
|
|
{% else %}
|
|
<span class="px-2 py-0.5 rounded-lg text-xs font-bold bg-slate-100 text-slate-600">{{ survey.get_status_display }}</span>
|
|
{% endif %}
|
|
</span>
|
|
</li>
|
|
{% if survey.total_score %}
|
|
<li class="flex justify-between border-b border-slate-100 pb-2">
|
|
<span class="text-slate">{% trans "Total Score" %}</span>
|
|
<span class="font-bold {% if survey.is_negative %}text-red-500{% else %}text-green-600{% endif %}">
|
|
{{ survey.total_score|floatformat:1 }}/5.0
|
|
</span>
|
|
</li>
|
|
{% endif %}
|
|
{% if survey.sent_at %}
|
|
<li class="flex justify-between border-b border-slate-100 pb-2">
|
|
<span class="text-slate">{% trans "Sent" %}</span>
|
|
<span class="font-bold text-slate-800">{{ survey.sent_at|date:"M d, Y H:i" }}</span>
|
|
</li>
|
|
{% endif %}
|
|
{% if survey.completed_at %}
|
|
<li class="flex justify-between border-b border-slate-100 pb-2">
|
|
<span class="text-slate">{% trans "Completed" %}</span>
|
|
<span class="font-bold text-slate-800">{{ survey.completed_at|date:"M d, Y H:i" }}</span>
|
|
</li>
|
|
{% endif %}
|
|
<li class="flex justify-between">
|
|
<span class="text-slate">{% trans "Type" %}</span>
|
|
<span class="px-2 py-0.5 rounded-lg text-xs font-bold bg-light text-navy">{{ survey.survey_template.get_survey_type_display }}</span>
|
|
</li>
|
|
{% if survey.completed_language %}
|
|
<li class="flex justify-between">
|
|
<span class="text-slate">{% trans "Language" %}</span>
|
|
<span class="font-bold text-slate-800 flex items-center gap-1">
|
|
{% if survey.completed_language == 'ar' %}
|
|
<span class="text-blue-600">العربية</span>
|
|
{% else %}
|
|
English
|
|
{% endif %}
|
|
</span>
|
|
</li>
|
|
{% endif %}
|
|
{% if survey.survey_template.hospital %}
|
|
<li class="flex justify-between border-t border-slate-100 pt-2 mt-2">
|
|
<span class="text-slate">{% trans "Hospital" %}</span>
|
|
<span class="font-bold text-slate-800">{{ survey.survey_template.hospital.name }}</span>
|
|
</li>
|
|
{% endif %}
|
|
</ul>
|
|
</section>
|
|
|
|
<!-- Patient Information -->
|
|
<section class="bg-white rounded-2xl p-6 shadow-sm border border-slate-100">
|
|
<h3 class="font-bold text-navy mb-4 text-sm flex items-center gap-2">
|
|
<i data-lucide="user" class="w-4 h-4 text-blue"></i>
|
|
{% trans "Patient Information" %}
|
|
</h3>
|
|
<ul class="space-y-3 text-sm">
|
|
<li class="flex justify-between border-b border-slate-100 pb-2">
|
|
<span class="text-slate">{% trans "Name" %}</span>
|
|
<span class="font-bold text-navy">{{ survey.patient.get_full_name }}</span>
|
|
</li>
|
|
<li class="flex justify-between border-b border-slate-100 pb-2">
|
|
<span class="text-slate">{% trans "Phone" %}</span>
|
|
<span class="font-bold text-slate-800">{{ survey.patient.phone }}</span>
|
|
</li>
|
|
<li class="flex justify-between">
|
|
<span class="text-slate">{% trans "MRN" %}</span>
|
|
<span class="font-bold text-slate-800">{{ survey.patient.mrn }}</span>
|
|
</li>
|
|
{% if survey.patient.email %}
|
|
<li class="flex justify-between border-t border-slate-100 pt-2 mt-2">
|
|
<span class="text-slate">{% trans "Email" %}</span>
|
|
<span class="font-bold text-slate-800 text-xs">{{ survey.patient.email }}</span>
|
|
</li>
|
|
{% endif %}
|
|
</ul>
|
|
</section>
|
|
|
|
<!-- Visit Timeline -->
|
|
{% if visit_timeline %}
|
|
<section class="bg-white rounded-2xl p-6 shadow-sm border border-slate-100">
|
|
<h3 class="font-bold text-navy mb-4 text-sm flex items-center gap-2">
|
|
<i data-lucide="clock" class="w-4 h-4 text-blue"></i>
|
|
{% trans "Visit Timeline" %}
|
|
</h3>
|
|
<div class="space-y-0">
|
|
{% for visit in visit_timeline %}
|
|
<div class="relative pl-6 pb-4 {% if not forloop.last %}border-l-2 border-slate-200 ml-2{% endif %}">
|
|
<div class="absolute -left-1.5 top-0 w-3 h-3 rounded-full {% if visit.visit_category == 'ED' %}bg-red-500{% elif visit.visit_category == 'IP' %}bg-blue-500{% elif visit.visit_category == 'OP' %}bg-green-500{% else %}bg-slate-400{% endif %}"></div>
|
|
<div class="text-xs text-slate-500 mb-0.5">{{ visit.bill_date }}</div>
|
|
<div class="text-sm font-medium text-navy">{{ visit.type }}</div>
|
|
<div class="text-xs text-slate-400 mt-0.5">
|
|
<span class="px-1.5 py-0.5 rounded text-xs font-semibold {% if visit.visit_category == 'ED' %}bg-red-100 text-red-700{% elif visit.visit_category == 'IP' %}bg-blue-100 text-blue-700{% elif visit.visit_category == 'OP' %}bg-green-100 text-green-700{% else %}bg-slate-100 text-slate-600{% endif %}">
|
|
{{ visit.patient_type }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</section>
|
|
{% endif %}
|
|
|
|
<!-- Journey Information (if applicable) -->
|
|
{% if survey.journey_instance %}
|
|
<section class="bg-white rounded-2xl p-6 shadow-sm border border-slate-100">
|
|
<h3 class="font-bold text-navy mb-4 text-sm flex items-center gap-2">
|
|
<i data-lucide="git-branch" class="w-4 h-4 text-green-600"></i>
|
|
{% trans "Journey Information" %}
|
|
</h3>
|
|
<ul class="space-y-3 text-sm mb-4">
|
|
<li class="flex justify-between border-b border-slate-100 pb-2">
|
|
<span class="text-slate">{% trans "Journey" %}</span>
|
|
<span class="font-bold text-slate-800">{{ survey.journey_instance.journey_template.name }}</span>
|
|
</li>
|
|
{% if survey.journey_instance %}
|
|
<li class="flex justify-between">
|
|
<span class="text-slate">{% trans "Stage" %}</span>
|
|
<span class="font-bold text-slate-800">{{ survey.journey_instance.journey_template.name }}</span>
|
|
</li>
|
|
{% endif %}
|
|
</ul>
|
|
<a href="{% url 'journeys:instance_detail' survey.journey_instance.id %}"
|
|
class="w-full px-4 py-3 bg-navy text-white rounded-xl font-semibold hover:bg-blue transition flex items-center justify-center gap-2 text-sm">
|
|
<i data-lucide="git-branch" class="w-4 h-4"></i>{% trans "View Journey" %}
|
|
</a>
|
|
</section>
|
|
{% endif %}
|
|
|
|
<!-- Follow-up Actions (for negative surveys) -->
|
|
{% if survey.is_negative %}
|
|
<section class="bg-white rounded-2xl p-6 shadow-sm border-2 border-red-200">
|
|
<h3 class="font-bold text-red-600 mb-4 text-sm flex items-center gap-2">
|
|
<i data-lucide="alert-triangle" class="w-4 h-4"></i>
|
|
{% trans "Follow-up Actions" %}
|
|
</h3>
|
|
|
|
{% if not survey.patient_contacted %}
|
|
<div class="bg-red-50 border border-red-200 rounded-xl p-4 mb-4 flex items-start gap-3">
|
|
<i data-lucide="info" class="w-5 h-5 text-red-500 flex-shrink-0 mt-0.5"></i>
|
|
<div>
|
|
<strong class="text-red-800 block text-sm">{% trans "Action Required" %}</strong>
|
|
<span class="text-red-700 text-xs">{% trans "Contact patient to discuss negative feedback" %}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<form method="post" action="{% url 'surveys:log_patient_contact' survey.id %}">
|
|
{% csrf_token %}
|
|
<div class="mb-4">
|
|
<label for="contact_notes" class="block text-xs font-semibold text-slate uppercase mb-2">{% trans "Contact Notes" %} <span class="text-red-500">*</span></label>
|
|
<textarea class="w-full px-4 py-3 border border-slate-200 rounded-xl text-sm focus:ring-2 focus:ring-navy focus:border-transparent transition resize-none"
|
|
id="contact_notes" name="contact_notes" rows="3" required
|
|
placeholder="{% trans 'Document your conversation...' %}"></textarea>
|
|
</div>
|
|
<div class="mb-4 flex items-center gap-2">
|
|
<input type="checkbox" id="issue_resolved" name="issue_resolved"
|
|
class="w-4 h-4 rounded border-slate-300 text-navy focus:ring-navy">
|
|
<label for="issue_resolved" class="text-sm text-slate">
|
|
{% trans "Issue resolved" %}
|
|
</label>
|
|
</div>
|
|
<button type="submit"
|
|
class="w-full px-4 py-3 bg-navy text-white rounded-xl font-semibold hover:bg-blue transition flex items-center justify-center gap-2 text-sm">
|
|
<i data-lucide="phone" class="w-4 h-4"></i>{% trans "Log Contact" %}
|
|
</button>
|
|
</form>
|
|
{% else %}
|
|
<div class="bg-green-50 border border-green-200 rounded-xl p-4 mb-4 flex items-start gap-3">
|
|
<i data-lucide="check-circle" class="w-5 h-5 text-green-600 flex-shrink-0 mt-0.5"></i>
|
|
<div>
|
|
<strong class="text-green-800 block text-sm">{% trans "Patient Contacted" %}</strong>
|
|
<span class="text-green-700 text-xs">
|
|
{{ survey.patient_contacted_by.get_full_name }} • {{ survey.patient_contacted_at|date:"M d, Y" }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-4">
|
|
<strong class="text-slate text-xs uppercase block mb-1">{% trans "Notes" %}</strong>
|
|
<p class="text-slate text-sm">{{ survey.contact_notes }}</p>
|
|
</div>
|
|
|
|
{% if not survey.satisfaction_feedback_sent %}
|
|
<form method="post" action="{% url 'surveys:send_satisfaction_feedback' survey.id %}">
|
|
{% csrf_token %}
|
|
<button type="submit"
|
|
class="w-full px-4 py-3 bg-navy text-white rounded-xl font-semibold hover:bg-blue transition flex items-center justify-center gap-2 text-sm">
|
|
<i data-lucide="send" class="w-4 h-4"></i>{% trans "Send Satisfaction Feedback" %}
|
|
</button>
|
|
</form>
|
|
{% else %}
|
|
<div class="bg-blue-50 border border-blue-200 rounded-xl p-4 flex items-start gap-3">
|
|
<i data-lucide="check-circle" class="w-5 h-5 text-blue-600 flex-shrink-0 mt-0.5"></i>
|
|
<div>
|
|
<strong class="text-blue-800 block text-sm">{% trans "Feedback Sent" %}</strong>
|
|
<span class="text-blue-700 text-xs">{{ survey.satisfaction_feedback_sent_at|date:"M d, Y" }}</span>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
{% endif %}
|
|
</section>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block extra_js %}
|
|
<script>
|
|
lucide.createIcons();
|
|
</script>
|
|
{% endblock %}
|