HH/templates/organizations/department_manager_review.html

298 lines
17 KiB
HTML

{% extends "layouts/base.html" %}
{% load i18n %}
{% block title %}{% trans "Manager Review" %} - {{ complaint.reference_number }} - PX360{% endblock %}
{% block content %}
<div class="p-6 max-w-4xl mx-auto">
<div class="flex items-center gap-2 text-sm text-slate-500 mb-4">
<a href="{% url 'organizations:department_list' %}" class="hover:text-navy transition">{% trans "Departments" %}</a>
<i data-lucide="chevron-right" class="w-4 h-4"></i>
<a href="{% url 'organizations:department_detail' department.pk %}" class="hover:text-navy transition">{{ department.get_localized_name }}</a>
<i data-lucide="chevron-right" class="w-4 h-4"></i>
<span class="text-navy font-semibold">{% trans "Manager Review" %}</span>
</div>
<div class="flex items-center gap-3 mb-6">
<div class="w-10 h-10 bg-amber-50 rounded-xl flex items-center justify-center">
<i data-lucide="shield-check" class="w-5 h-5 text-amber-600"></i>
</div>
<div>
<h1 class="text-xl font-bold text-navy">{% trans "Review Champion Response" %}</h1>
<p class="text-sm text-slate-500">{{ complaint.reference_number }} &middot; {{ department.get_localized_name }}</p>
</div>
</div>
<div class="space-y-6">
<!-- Enhanced Complaint Card -->
<div class="bg-white rounded-2xl border border-slate-200 p-6">
<div class="flex items-start justify-between mb-4">
<h3 class="text-sm font-bold text-navy flex items-center gap-2">
<i data-lucide="file-text" class="w-4 h-4"></i> {% trans "Complaint Details" %}
</h3>
<div class="flex items-center gap-2">
<span class="px-2.5 py-0.5 rounded-full text-[10px] font-bold uppercase
{% if complaint.status == 'open' %}bg-blue-50 text-blue-700
{% elif complaint.status == 'in_progress' %}bg-amber-50 text-amber-700
{% elif complaint.status == 'resolved' %}bg-green-50 text-green-700
{% else %}bg-slate-100 text-slate-600{% endif %}">
{{ complaint.get_status_display }}
</span>
{% if complaint.severity %}
<span class="px-2.5 py-0.5 rounded-full text-[10px] font-bold uppercase
{% if complaint.severity == 'critical' %}bg-gray-800 text-white
{% elif complaint.severity == 'high' %}bg-red-50 text-red-700
{% elif complaint.severity == 'medium' %}bg-amber-50 text-amber-700
{% else %}bg-green-50 text-green-700{% endif %}">
{{ complaint.get_severity_display }}
</span>
{% endif %}
</div>
</div>
<div class="grid grid-cols-2 gap-4 mb-4">
<div>
<p class="text-[10px] text-slate-400 uppercase font-bold mb-0.5">{% trans "Reference" %}</p>
<p class="text-sm font-bold text-navy">{{ complaint.reference_number }}</p>
</div>
<div>
<p class="text-[10px] text-slate-400 uppercase font-bold mb-0.5">{% trans "Patient" %}</p>
<p class="text-sm font-semibold text-slate-700">{{ complaint.patient_name|default:complaint.contact_name|default:"—" }}</p>
</div>
<div>
<p class="text-[10px] text-slate-400 uppercase font-bold mb-0.5">{% trans "Incident Date" %}</p>
<p class="text-sm font-semibold text-slate-700">{{ complaint.incident_date|date:"M d, Y"|default:"—" }}</p>
</div>
<div>
<p class="text-[10px] text-slate-400 uppercase font-bold mb-0.5">{% trans "Department" %}</p>
<p class="text-sm font-semibold text-slate-700">{{ complaint.department|default:"—" }}</p>
</div>
</div>
{% if complaint.involved_staff.exists %}
<div class="mb-4">
<p class="text-[10px] text-slate-400 uppercase font-bold mb-1.5">{% trans "Accused Staff" %}</p>
<div class="flex flex-wrap gap-2">
{% for inv_staff in complaint.involved_staff.all %}
{% if inv_staff.role == 'accused' or inv_staff.role == 'Accused/Involved' %}
<span class="inline-flex items-center gap-1.5 px-3 py-1 bg-red-50 text-red-700 rounded-lg text-xs font-semibold">
<i data-lucide="user" class="w-3 h-3"></i>
{{ inv_staff.staff.get_full_name }}
</span>
{% endif %}
{% endfor %}
</div>
</div>
{% endif %}
{% if complaint.title %}
<div class="mb-2">
<p class="text-[10px] text-slate-400 uppercase font-bold mb-0.5">{% trans "Title" %}</p>
<p class="text-sm font-semibold text-navy">{{ complaint.title }}</p>
</div>
{% endif %}
{% if complaint.description %}
<div>
<p class="text-[10px] text-slate-400 uppercase font-bold mb-0.5">{% trans "Description" %}</p>
<p class="text-sm text-slate-600 whitespace-pre-wrap">{{ complaint.description }}</p>
</div>
{% endif %}
</div>
{% if investigation and investigation_staff_data %}
<!-- Investigation Questions & Answers (before champion response) -->
<div class="bg-white rounded-2xl border border-blue-200 p-6">
<h3 class="text-sm font-bold text-navy mb-4 flex items-center gap-2">
<i data-lucide="search" class="w-4 h-4 text-blue-600"></i>
{% trans "Investigation Questions & Answers" %}
<span class="px-2 py-0.5 rounded-full text-[10px] font-bold uppercase
{% if investigation.status == 'questions_sent' %}bg-amber-100 text-amber-700
{% elif investigation.status == 'answers_received' %}bg-blue-100 text-blue-700
{% elif investigation.status == 'reply_submitted' %}bg-green-100 text-green-700{% endif %}">
{{ investigation.get_status_display }}
</span>
</h3>
<div class="space-y-4">
{% for sd in investigation_staff_data %}
<div class="border border-slate-200 rounded-xl p-4">
<div class="flex items-center justify-between mb-3 pb-2 border-b border-slate-100">
<div class="flex items-center gap-2">
<div class="w-8 h-8 rounded-full bg-navy/10 flex items-center justify-center">
<span class="text-xs font-bold text-navy">{{ sd.staff.first_name|first|default:"?" }}{{ sd.staff.last_name|first|default:"" }}</span>
</div>
<span class="font-semibold text-navy text-sm">{{ sd.staff.get_full_name }}</span>
</div>
{% if sd.is_completed %}
<span class="px-2 py-0.5 rounded-full text-[10px] font-bold bg-green-100 text-green-700 uppercase">{% trans "Responded" %}</span>
{% else %}
<span class="px-2 py-0.5 rounded-full text-[10px] font-bold bg-amber-100 text-amber-700 uppercase">{% trans "Pending" %}</span>
{% endif %}
</div>
{% if sd.is_completed %}
<div class="space-y-3">
{% for pair in sd.qa_pairs %}
<div class="bg-slate-50 rounded-lg p-3">
<p class="text-xs font-bold text-slate-500 uppercase mb-1">{% trans "Q" %}{{ forloop.counter }}</p>
<p class="text-sm font-semibold text-slate-700 mb-2">{{ pair.question.question_text }}</p>
<p class="text-xs font-bold text-slate-500 uppercase mb-1">{% trans "Answer" %}</p>
<p class="text-sm text-slate-600 whitespace-pre-wrap">{{ pair.answer|default:"—" }}</p>
</div>
{% endfor %}
</div>
{% else %}
<p class="text-sm text-slate-400 italic">{% trans "This staff member has not responded yet." %}</p>
{% endif %}
</div>
{% endfor %}
</div>
</div>
{% endif %}
<!-- Champion Response (after investigation) -->
<div class="bg-white rounded-2xl border border-slate-200 p-6">
<h3 class="text-sm font-bold text-navy mb-3 flex items-center gap-2">
<i data-lucide="message-square" class="w-4 h-4"></i> {% trans "Champion Response" %}
</h3>
{% if involved_dept.response_notes_en %}
<div class="bg-slate-50 rounded-xl p-4 border border-slate-200 mb-3">
<p class="text-[10px] text-slate-400 uppercase font-bold mb-1">{% trans "English" %}</p>
<p class="text-sm text-slate-700 whitespace-pre-wrap">{{ involved_dept.response_notes_en }}</p>
</div>
{% endif %}
{% if involved_dept.response_notes_ar %}
<div class="bg-slate-50 rounded-xl p-4 border border-slate-200">
<p class="text-[10px] text-slate-400 uppercase font-bold mb-1">{% trans "Arabic" %}</p>
<p class="text-sm text-slate-700 whitespace-pre-wrap" dir="rtl">{{ involved_dept.response_notes_ar }}</p>
</div>
{% endif %}
{% if involved_dept.response_submitted_at %}
<p class="text-xs text-slate-400 mt-2">
{% trans "Submitted" %}: {{ involved_dept.response_submitted_at|date:"Y-m-d H:i" }}
</p>
{% endif %}
</div>
<form method="post" id="managerReviewForm">
{% csrf_token %}
<input type="hidden" name="review_action" id="reviewAction" value="">
{% if questions %}
<div class="bg-white rounded-2xl border border-slate-200 p-6">
<h3 class="text-sm font-bold text-navy mb-4 flex items-center gap-2">
<i data-lucide="clipboard-list" class="w-4 h-4"></i> {% trans "Review Questions" %}
</h3>
<div class="space-y-5">
{% for q in questions %}
<div class="border-b border-slate-100 pb-4 last:border-0 last:pb-0">
<label class="block text-sm font-semibold text-slate-700 mb-2">
{{ q.get_localized_text }}
<span class="text-red-500">*</span>
</label>
{% if q.question_type == 'text' %}
<input type="text" name="question_{{ q.pk }}" required
class="w-full px-4 py-2.5 border-2 border-slate-200 rounded-xl text-sm focus:outline-none focus:border-navy focus:ring-2 focus:ring-navy/20">
{% elif q.question_type == 'textarea' %}
<textarea name="question_{{ q.pk }}" rows="3" required
class="w-full px-4 py-3 border-2 border-slate-200 rounded-xl text-sm focus:outline-none focus:border-navy focus:ring-2 focus:ring-navy/20 resize-none"></textarea>
{% elif q.question_type == 'yes_no' %}
<div class="flex gap-4 mt-1">
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="question_{{ q.pk }}" value="yes" required
class="w-4 h-4 text-navy border-slate-300 focus:ring-navy">
<span class="text-sm text-slate-700">{% trans "Yes" %}</span>
</label>
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="question_{{ q.pk }}" value="no"
class="w-4 h-4 text-navy border-slate-300 focus:ring-navy">
<span class="text-sm text-slate-700">{% trans "No" %}</span>
</label>
</div>
{% elif q.question_type == 'rating' %}
<div class="flex gap-2 mt-1">
{% for i in "12345" %}
<label class="cursor-pointer">
<input type="radio" name="question_{{ q.pk }}" value="{{ i }}" required
class="hidden peer">
<div class="w-10 h-10 rounded-lg border-2 border-slate-200 flex items-center justify-center text-sm font-bold text-slate-400 peer-checked:bg-navy peer-checked:text-white peer-checked:border-navy transition hover:border-navy">
{{ i }}
</div>
</label>
{% endfor %}
</div>
{% elif q.question_type == 'multiple_choice' %}
<div class="space-y-2 mt-1">
{% for choice in q.choices_json %}
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="question_{{ q.pk }}" value="{{ choice }}" required
class="w-4 h-4 text-navy border-slate-300 focus:ring-navy">
<span class="text-sm text-slate-700">{{ choice }}</span>
</label>
{% endfor %}
</div>
{% endif %}
</div>
{% endfor %}
</div>
</div>
{% endif %}
<div id="rejectionReasonBox" class="hidden bg-white rounded-2xl border border-red-200 p-6">
<h3 class="text-sm font-bold text-red-700 mb-2 flex items-center gap-2">
<i data-lucide="alert-circle" class="w-4 h-4"></i> {% trans "Rejection Reason" %}
</h3>
<textarea name="rejection_reason" id="rejectionReason" rows="3"
class="w-full px-4 py-3 border-2 border-red-200 rounded-xl text-sm focus:outline-none focus:border-red-400 focus:ring-2 focus:ring-red-200/40 resize-none"
placeholder="{% trans 'Please explain why you are rejecting this response...' %}"></textarea>
</div>
<div class="flex gap-3 pt-2">
<button type="button" onclick="submitReview('approve')"
class="flex-1 px-4 py-3 bg-green-600 text-white font-semibold rounded-xl hover:bg-green-700 transition flex items-center justify-center gap-2">
<i data-lucide="check-circle" class="w-5 h-5"></i> {% trans "Approve & Forward to PX Team" %}
</button>
<button type="button" onclick="handleReject()"
class="flex-1 px-4 py-3 bg-red-600 text-white font-semibold rounded-xl hover:bg-red-700 transition flex items-center justify-center gap-2">
<i data-lucide="x-circle" class="w-5 h-5"></i> {% trans "Reject & Return to Champion" %}
</button>
<a href="{% url 'organizations:department_detail' department.pk %}"
class="px-4 py-3 bg-slate-100 text-slate-700 font-semibold rounded-xl hover:bg-slate-200 transition text-center">
{% trans "Cancel" %}
</a>
</div>
</form>
</div>
</div>
<script>
function submitReview(action) {
document.getElementById('reviewAction').value = action;
document.getElementById('managerReviewForm').submit();
}
function handleReject() {
var box = document.getElementById('rejectionReasonBox');
box.classList.remove('hidden');
document.getElementById('rejectionReason').focus();
box.scrollIntoView({ behavior: 'smooth', block: 'center' });
var reasonEl = document.getElementById('rejectionReason');
reasonEl.setAttribute('required', 'required');
var submitBtn = box.closest('form').querySelectorAll('button')[1];
submitBtn.onclick = function() {
var reason = reasonEl.value.trim();
if (!reason) {
alert('{% trans "Please provide a rejection reason." %}');
return;
}
submitReview('reject');
};
}
</script>
{% endblock %}