195 lines
14 KiB
HTML
195 lines
14 KiB
HTML
{% load i18n %}
|
|
{% if workflow_log %}
|
|
<div class="mt-8">
|
|
<h4 class="text-sm font-bold text-navy uppercase tracking-wide mb-4 flex items-center gap-2">
|
|
<i data-lucide="git-commit-vertical" class="w-4 h-4"></i>
|
|
{% trans "Workflow Timeline" %}
|
|
</h4>
|
|
|
|
<div class="relative pl-2">
|
|
<!-- Vertical line -->
|
|
<div class="absolute left-[15px] top-2 bottom-2 w-0.5 bg-slate-200"></div>
|
|
|
|
{% for event in workflow_log %}
|
|
{% if event.type == 'staff_responded' or event.type == 'reply_submitted' or event.type == 'direct_reply' %}
|
|
<div class="relative flex items-start gap-4 mb-5 last:mb-0">
|
|
<!-- Dot -->
|
|
<div class="relative z-10 shrink-0 mt-0.5">
|
|
<div class="w-8 h-8 rounded-full flex items-center justify-center ring-4 ring-white
|
|
{% if event.type == 'sent_to_dept' or event.type == 'explanation_sent' %}bg-blue-500
|
|
{% elif event.type == 'investigation_started' %}bg-amber-500
|
|
{% elif event.type == 'questions_sent' %}bg-blue-400
|
|
{% elif event.type == 'staff_responded' %}bg-green-500
|
|
{% elif event.type == 'staff_pending' %}bg-yellow-400
|
|
{% elif event.type == 'reply_submitted' or event.type == 'direct_reply' %}bg-green-600
|
|
{% else %}bg-slate-400{% endif %}">
|
|
{% if event.type == 'sent_to_dept' or event.type == 'explanation_sent' %}
|
|
<svg class="w-3.5 h-3.5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M5 10l7-7m0 0l7 7m-7-7v18"/></svg>
|
|
{% elif event.type == 'investigation_started' %}
|
|
<svg class="w-3.5 h-3.5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/></svg>
|
|
{% elif event.type == 'questions_sent' %}
|
|
<svg class="w-3.5 h-3.5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"/></svg>
|
|
{% elif event.type == 'staff_responded' or event.type == 'reply_submitted' or event.type == 'direct_reply' %}
|
|
<svg class="w-3.5 h-3.5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7"/></svg>
|
|
{% elif event.type == 'staff_pending' %}
|
|
<svg class="w-3.5 h-3.5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Content card -->
|
|
<div class="flex-1 bg-white rounded-xl border border-slate-200 shadow-sm p-3 min-w-0">
|
|
<!-- Header row -->
|
|
<div class="flex items-center justify-between gap-2 mb-1">
|
|
<div class="flex items-center gap-2 flex-wrap min-w-0">
|
|
{% if event.type == 'staff_responded' %}
|
|
<span class="text-sm font-bold text-green-600">{% trans "Investigation Response" %}</span>
|
|
{% elif event.type == 'reply_submitted' %}
|
|
<span class="text-sm font-bold text-green-700">{% trans "Department Response" %}</span>
|
|
{% elif event.type == 'direct_reply' %}
|
|
<span class="text-sm font-bold text-green-700">{% trans "Department Response" %}</span>
|
|
{% endif %}
|
|
</div>
|
|
{% if event.timestamp %}
|
|
<span class="text-[10px] text-slate-400 shrink-0">{{ event.timestamp|date:"d M, h:i A" }}</span>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Actor line: "Investigation by X for Y" -->
|
|
{% if event.type == 'staff_responded' %}
|
|
<p class="text-xs text-slate-500 mb-2">
|
|
{% trans "Investigation by" %} <span class="font-semibold text-slate-600">{{ event.investigator|default:"Department Champion" }}</span>
|
|
{% trans "for" %} <span class="font-semibold text-slate-600">{{ event.actor }}</span>
|
|
</p>
|
|
<!-- Questions + answers label -->
|
|
<p class="text-[10px] font-bold text-slate/40 uppercase mb-1">{% trans "Questions & Answers" %}</p>
|
|
{% elif event.type == 'reply_submitted' %}
|
|
<p class="text-xs text-slate-500 mb-2">
|
|
{% trans "Submitted by" %} <span class="font-semibold text-slate-600">{{ event.actor }}</span>
|
|
</p>
|
|
{% elif event.type == 'direct_reply' %}
|
|
<p class="text-xs text-slate-500 mb-2">
|
|
{% trans "Submitted by" %} <span class="font-semibold text-slate-600">{{ event.actor }}</span>
|
|
</p>
|
|
{% endif %}
|
|
|
|
<!-- Q&A pairs: one compact table -->
|
|
{% if event.type == 'staff_responded' and event.qa_pairs %}
|
|
<table class="w-full mt-2 text-[11px] border-collapse">
|
|
<thead>
|
|
<tr class="border-b-2 border-slate-200">
|
|
<th class="py-1 pr-3 text-left text-[9px] font-bold text-slate/50 uppercase tracking-wider" style="width:55%">{% trans "Question" %}</th>
|
|
<th class="py-1 text-left text-[9px] font-bold text-slate/50 uppercase tracking-wider">{% trans "Answer" %}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for qa in event.qa_pairs %}
|
|
<tr class="border-b border-slate-100 last:border-0">
|
|
<td class="py-1.5 pr-3 font-semibold text-slate-600 align-top">
|
|
{{ forloop.counter }}. {{ qa.question }}
|
|
</td>
|
|
<td class="py-1.5 text-slate-700 align-top">
|
|
{% if qa.question_type == 'yes_no' %}
|
|
{% if qa.answer == 'yes' %}
|
|
<span class="inline-flex items-center px-1.5 py-0.5 rounded text-[9px] font-bold bg-green-100 text-green-700">{% trans "Yes" %}</span>
|
|
{% elif qa.answer == 'no' %}
|
|
<span class="inline-flex items-center px-1.5 py-0.5 rounded text-[9px] font-bold bg-red-100 text-red-700">{% trans "No" %}</span>
|
|
{% else %}
|
|
<span class="text-slate-300">—</span>
|
|
{% endif %}
|
|
{% else %}
|
|
{{ qa.answer|truncatewords:25|default:"—" }}
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
{% endif %}
|
|
|
|
<!-- Final reply -->
|
|
{% if event.type == 'reply_submitted' %}
|
|
{% if event.final_reply %}
|
|
<div class="mt-2">
|
|
<p class="text-[10px] font-bold text-slate/40 uppercase tracking-wider mb-1">{% trans "Response" %}</p>
|
|
<div class="bg-green-50 rounded-lg p-2">
|
|
<p class="text-[11px] text-slate-700">{{ event.final_reply|truncatewords:50 }}</p>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
{% if event.negligence or event.policy_issue or event.improvement_project %}
|
|
<div class="mt-2">
|
|
<p class="text-[10px] font-bold text-slate/40 uppercase tracking-wider mb-1">{% trans "Assessment" %}</p>
|
|
<table class="w-full text-[11px] border-collapse">
|
|
<thead>
|
|
<tr class="border-b-2 border-slate-200">
|
|
<th class="py-1 pr-3 text-left text-[9px] font-bold text-slate/50 uppercase tracking-wider" style="width:55%">{% trans "Question" %}</th>
|
|
<th class="py-1 text-left text-[9px] font-bold text-slate/50 uppercase tracking-wider">{% trans "Answer" %}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="border-b border-slate-100">
|
|
<td class="py-1.5 pr-3 font-semibold text-slate-600 align-top">{% trans "Is there any negligence resulting from carelessness?" %}</td>
|
|
<td class="py-1.5 align-top">
|
|
{% if event.negligence == 'yes' %}
|
|
<span class="inline-flex items-center px-1.5 py-0.5 rounded text-[9px] font-bold bg-red-100 text-red-700">{% trans "Yes" %}</span>
|
|
{% elif event.negligence == 'no' %}
|
|
<span class="inline-flex items-center px-1.5 py-0.5 rounded text-[9px] font-bold bg-green-100 text-green-700">{% trans "No" %}</span>
|
|
{% else %}<span class="text-slate-300">—</span>{% endif %}
|
|
</td>
|
|
</tr>
|
|
<tr class="border-b border-slate-100">
|
|
<td class="py-1.5 pr-3 font-semibold text-slate-600 align-top">{% trans "Is it resulting from policies or regulations?" %}</td>
|
|
<td class="py-1.5 align-top">
|
|
{% if event.policy_issue == 'yes' %}
|
|
<span class="inline-flex items-center px-1.5 py-0.5 rounded text-[9px] font-bold bg-red-100 text-red-700">{% trans "Yes" %}</span>
|
|
{% elif event.policy_issue == 'no' %}
|
|
<span class="inline-flex items-center px-1.5 py-0.5 rounded text-[9px] font-bold bg-green-100 text-green-700">{% trans "No" %}</span>
|
|
{% else %}<span class="text-slate-300">—</span>{% endif %}
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="py-1.5 pr-3 font-semibold text-slate-600 align-top">{% trans "Does this complaint require an improvement project?" %}</td>
|
|
<td class="py-1.5 align-top">
|
|
{% if event.improvement_project == 'yes' %}
|
|
<span class="inline-flex items-center px-1.5 py-0.5 rounded text-[9px] font-bold bg-amber-100 text-amber-700">{% trans "Yes" %}</span>
|
|
{% elif event.improvement_project == 'no' %}
|
|
<span class="inline-flex items-center px-1.5 py-0.5 rounded text-[9px] font-bold bg-slate-100 text-slate-600">{% trans "No" %}</span>
|
|
{% else %}<span class="text-slate-300">—</span>{% endif %}
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
{% if event.improvement_project == 'yes' and event.improvement_note %}
|
|
<div class="bg-amber-50 rounded-lg p-2 mt-1.5">
|
|
<span class="text-[10px] font-bold text-amber-700">{% trans "Improvement Project:" %}</span>
|
|
<span class="text-[11px] text-amber-800">{{ event.improvement_note }}</span>
|
|
{% if can_admin %}
|
|
<a href="{% url 'projects:project_create' %}?related_model=complaint&related_id={{ complaint.pk }}&description={{ event.improvement_note|urlencode }}"
|
|
class="mt-1 inline-flex items-center gap-1 px-2 py-1 bg-amber-600 text-white rounded-md text-[10px] font-bold hover:bg-amber-700">
|
|
<i data-lucide="plus" class="w-3 h-3"></i> {% trans "Create Project" %}
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
{% endif %}
|
|
|
|
<!-- Direct reply -->
|
|
{% if event.type == 'direct_reply' and event.reply %}
|
|
<div class="mt-2">
|
|
<p class="text-[10px] font-bold text-slate/40 uppercase tracking-wider mb-1">{% trans "Response" %}</p>
|
|
<div class="bg-green-50 rounded-lg p-2">
|
|
<p class="text-[11px] text-slate-700">{{ event.reply|truncatewords:50 }}</p>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|