HH/templates/complaints/inquiry_detail.html
2026-02-22 08:35:53 +03:00

525 lines
25 KiB
HTML

{% extends 'layouts/base.html' %}
{% load i18n %}
{% load static %}
{% block title %}Inquiry #{{ inquiry.id|slice:":8" }} - PX360{% endblock %}
{% block extra_css %}
<style>
.timeline {
position: relative;
padding-left: 30px;
}
.timeline::before {
content: '';
position: absolute;
left: 8px;
top: 0;
bottom: 0;
width: 2px;
background: #e5e7eb;
}
.timeline-item {
position: relative;
padding-bottom: 30px;
}
.timeline-item::before {
content: '';
position: absolute;
left: -26px;
top: 5px;
width: 16px;
height: 16px;
border-radius: 50%;
background: white;
border: 3px solid #17a2b8;
z-index: 1;
}
.timeline-item.status_change::before {
border-color: #f97316;
}
.timeline-item.response::before {
border-color: #22c55e;
}
.timeline-item.note::before {
border-color: #3b82f6;
}
.info-label {
font-weight: 600;
color: #9ca3af;
font-size: 0.75rem;
text-transform: uppercase;
letter-spacing: 0.05em;
}
</style>
{% endblock %}
{% block content %}
<!-- Back Button -->
<div class="mb-6">
{% if source_user %}
<a href="{% url 'px_sources:source_user_inquiry_list' %}" class="inline-flex items-center gap-2 px-4 py-2 border border-gray-200 rounded-xl text-gray-600 hover:bg-gray-50 transition text-sm font-semibold">
<i data-lucide="arrow-left" class="w-4 h-4"></i> {% trans "Back to My Inquiries" %}
</a>
{% else %}
<a href="{% url 'complaints:inquiry_list' %}" class="inline-flex items-center gap-2 px-4 py-2 border border-gray-200 rounded-xl text-gray-600 hover:bg-gray-50 transition text-sm font-semibold">
<i data-lucide="arrow-left" class="w-4 h-4"></i> {% trans "Back to Inquiries" %}
</a>
{% endif %}
</div>
<!-- Inquiry Header -->
<div class="bg-gradient-to-r from-cyan-500 to-teal-500 rounded-2xl p-6 text-white mb-6">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div>
<div class="flex flex-wrap items-center gap-3 mb-4">
<h2 class="text-2xl font-bold">{{ inquiry.subject }}</h2>
<span class="px-3 py-1 bg-white/20 rounded-full text-sm font-semibold">
{% trans "Inquiry" %}
</span>
{% if inquiry.status == 'open' %}
<span class="px-3 py-1 bg-blue-500 rounded-full text-sm font-semibold">{% trans "Open" %}</span>
{% elif inquiry.status == 'in_progress' %}
<span class="px-3 py-1 bg-orange-500 rounded-full text-sm font-semibold">{% trans "In Progress" %}</span>
{% elif inquiry.status == 'resolved' %}
<span class="px-3 py-1 bg-green-500 rounded-full text-sm font-semibold">{% trans "Resolved" %}</span>
{% elif inquiry.status == 'closed' %}
<span class="px-3 py-1 bg-gray-500 rounded-full text-sm font-semibold">{% trans "Closed" %}</span>
{% endif %}
{% if inquiry.priority %}
{% if inquiry.priority == 'low' %}
<span class="px-3 py-1 bg-green-200 text-green-800 rounded-full text-sm font-semibold">{% trans "Low" %}</span>
{% elif inquiry.priority == 'medium' %}
<span class="px-3 py-1 bg-orange-200 text-orange-800 rounded-full text-sm font-semibold">{% trans "Medium" %}</span>
{% elif inquiry.priority == 'high' %}
<span class="px-3 py-1 bg-red-200 text-red-800 rounded-full text-sm font-semibold">{% trans "High" %}</span>
{% elif inquiry.priority == 'urgent' %}
<span class="px-3 py-1 bg-navy text-white rounded-full text-sm font-semibold">{% trans "Urgent" %}</span>
{% endif %}
{% endif %}
</div>
<div class="space-y-2 text-white/90">
<p class="flex items-center gap-2">
<i data-lucide="hash" class="w-4 h-4"></i>
<span><strong>{% trans "ID" %}:</strong> {{ inquiry.id|slice:":8" }}</span>
{% if inquiry.patient %}
<span class="mx-2">|</span>
<span><strong>{% trans "Patient" %}:</strong> {{ inquiry.patient.get_full_name }} ({% trans "MRN" %}: {{ inquiry.patient.mrn }})</span>
{% else %}
<span class="mx-2">|</span>
<span><strong>{% trans "Contact" %}:</strong> {{ inquiry.contact_name|default:inquiry.contact_email }}</span>
{% endif %}
</p>
<p class="flex items-center gap-2">
<i data-lucide="building-2" class="w-4 h-4"></i>
<span><strong>{% trans "Hospital" %}:</strong> {{ inquiry.hospital.name_en }}</span>
{% if inquiry.department %}
<span class="mx-2">|</span>
<span><strong>{% trans "Department" %}:</strong> {{ inquiry.department.name_en }}</span>
{% endif %}
</p>
</div>
</div>
{% if inquiry.due_date %}
<div class="bg-white/10 rounded-2xl p-5 text-center {% if inquiry.is_overdue %}bg-red-500/20{% endif %}">
<div class="flex items-center justify-center gap-2 mb-2">
<i data-lucide="clock" class="w-5 h-5"></i>
<strong>{% trans "Due Date" %}</strong>
</div>
<h3 class="text-2xl font-bold mb-2">{{ inquiry.due_date|date:"M d, Y H:i" }}</h3>
{% if inquiry.is_overdue %}
<div class="text-red-200 font-bold">
<i data-lucide="alert-triangle" class="w-4 h-4 inline"></i>
{% trans "OVERDUE" %}
</div>
{% else %}
<small class="text-white/80">{{ inquiry.due_date|timeuntil }} {% trans "remaining" %}</small>
{% endif %}
</div>
{% endif %}
</div>
</div>
<!-- Tab Navigation -->
<div class="bg-white rounded-t-2xl border-b border-gray-100 px-6">
<div class="flex gap-1 overflow-x-auto" role="tablist">
<button class="tab-btn active" data-target="details" role="tab">
<i data-lucide="info" class="w-4 h-4"></i> {% trans "Details" %}
</button>
<button class="tab-btn" data-target="timeline" role="tab">
<i data-lucide="clock-history" class="w-4 h-4"></i> {% trans "Timeline" %} ({{ timeline.count }})
</button>
<button class="tab-btn" data-target="attachments" role="tab">
<i data-lucide="paperclip" class="w-4 h-4"></i> {% trans "Attachments" %} ({{ attachments.count }})
</button>
</div>
</div>
<!-- Tab Content -->
<div class="bg-white rounded-b-2xl border border-gray-50 shadow-sm mb-6">
<div class="p-6">
<!-- Details Tab -->
<div class="tab-panel active" id="details">
<h3 class="text-xl font-bold text-gray-800 mb-6">{% trans "Inquiry Details" %}</h3>
<div class="space-y-6">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<div class="info-label mb-2">{% trans "Category" %}</div>
<span class="px-3 py-1 bg-gray-100 text-gray-700 rounded-lg text-sm font-semibold">{{ inquiry.get_category_display }}</span>
</div>
<div>
<div class="info-label mb-2">{% trans "Source" %}</div>
{% if inquiry.source %}
<span class="px-3 py-1 bg-blue-100 text-blue-700 rounded-lg text-sm font-semibold">{{ inquiry.get_source_display }}</span>
{% else %}
<span class="text-gray-400 text-sm">{% trans "N/A" %}</span>
{% endif %}
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<div class="info-label mb-2">{% trans "Channel" %}</div>
{% if inquiry.channel %}
<span class="text-gray-700 font-medium">{{ inquiry.get_channel_display }}</span>
{% else %}
<span class="text-gray-400 text-sm">{% trans "N/A" %}</span>
{% endif %}
</div>
<div>
<div class="info-label mb-2">{% trans "Assigned To" %}</div>
<span class="text-gray-700 font-medium">
{% if inquiry.assigned_to %}{{ inquiry.assigned_to.get_full_name }}{% else %}<span class="text-gray-400">{% trans "Unassigned" %}</span>{% endif %}
</span>
</div>
</div>
<hr class="border-gray-200">
<div>
<div class="info-label mb-2">{% trans "Message" %}</div>
<div class="bg-gray-50 rounded-xl p-4 text-gray-700">
{{ inquiry.message|linebreaks }}
</div>
</div>
{% if inquiry.response %}
<hr class="border-gray-200">
<div>
<div class="info-label mb-2">{% trans "Response" %}</div>
<div class="bg-green-50 border border-green-200 rounded-xl p-4">
<p class="text-gray-700 mb-3">{{ inquiry.response|linebreaks }}</p>
<small class="text-gray-500">
{% trans "Responded by" %} {{ inquiry.responded_by.get_full_name }} {% trans "on" %} {{ inquiry.responded_at|date:"M d, Y H:i" }}
</small>
</div>
</div>
{% endif %}
<hr class="border-gray-200">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<div class="info-label mb-2">{% trans "Created" %}</div>
<span class="text-gray-700 font-medium">{{ inquiry.created_at|date:"M d, Y H:i" }}</span>
</div>
<div>
<div class="info-label mb-2">{% trans "Last Updated" %}</div>
<span class="text-gray-700 font-medium">{{ inquiry.updated_at|date:"M d, Y H:i" }}</span>
</div>
</div>
</div>
</div>
<!-- Timeline Tab -->
<div class="tab-panel hidden" id="timeline">
<h3 class="text-xl font-bold text-gray-800 mb-6">{% trans "Activity Timeline" %}</h3>
{% if timeline %}
<div class="timeline">
{% for update in timeline %}
<div class="timeline-item {{ update.update_type }}">
<div class="bg-white border border-gray-200 rounded-xl p-4 shadow-sm hover:shadow-md transition">
<div class="flex justify-between items-start mb-2">
<div>
<span class="px-3 py-1 bg-cyan-500 text-white rounded-lg text-sm font-bold">{{ update.get_update_type_display }}</span>
{% if update.created_by %}
<span class="text-gray-500 text-sm ml-2">
by {{ update.created_by.get_full_name }}
</span>
{% endif %}
</div>
<small class="text-gray-400">
{{ update.created_at|date:"M d, Y H:i" }}
</small>
</div>
<p class="text-gray-700">{{ update.message }}</p>
{% if update.old_status and update.new_status %}
<div class="flex gap-2 mt-2">
<span class="px-2 py-1 bg-blue-100 text-blue-600 rounded-lg text-xs font-bold">{{ update.old_status }}</span>
<i data-lucide="arrow-right" class="w-4 h-4 text-gray-400"></i>
<span class="px-2 py-1 bg-green-100 text-green-600 rounded-lg text-xs font-bold">{{ update.new_status }}</span>
</div>
{% endif %}
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="text-center py-12">
<i data-lucide="clock-history" class="w-16 h-16 mx-auto text-gray-300 mb-4"></i>
<p class="text-gray-500">{% trans "No timeline entries yet" %}</p>
</div>
{% endif %}
</div>
<!-- Attachments Tab -->
<div class="tab-panel hidden" id="attachments">
<h3 class="text-xl font-bold text-gray-800 mb-6">{% trans "Attachments" %}</h3>
{% if attachments %}
<div class="space-y-3">
{% for attachment in attachments %}
<div class="bg-white border border-gray-200 rounded-xl p-4 flex justify-between items-center hover:shadow-md transition">
<div>
<div class="flex items-center gap-2 font-semibold text-gray-800 mb-1">
<i data-lucide="file" class="w-5 h-5"></i> {{ attachment.filename }}
</div>
<small class="text-gray-500">
{% trans "Uploaded by" %} {{ attachment.uploaded_by.get_full_name }}
{% trans "on" %} {{ attachment.created_at|date:"M d, Y H:i" }}
({{ attachment.file_size|filesizeformat }})
</small>
{% if attachment.description %}
<p class="text-sm text-gray-600 mt-1">{{ attachment.description }}</p>
{% endif %}
</div>
<a href="{{ attachment.file.url }}" class="p-2 bg-cyan-100 text-cyan-600 rounded-lg hover:bg-cyan-200 transition">
<i data-lucide="download" class="w-5 h-5"></i>
</a>
</div>
{% endfor %}
</div>
{% else %}
<div class="text-center py-12">
<i data-lucide="paperclip" class="w-16 h-16 mx-auto text-gray-300 mb-4"></i>
<p class="text-gray-500">{% trans "No attachments" %}</p>
</div>
{% endif %}
</div>
</div>
</div>
<!-- Sidebar Actions -->
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<div class="lg:col-span-2"></div>
<div class="space-y-4">
<!-- Quick Actions -->
{% if can_edit %}
<div class="bg-white rounded-2xl border border-gray-50 shadow-sm p-6">
<h4 class="font-bold text-gray-800 mb-4 flex items-center gap-2">
<i data-lucide="zap" class="w-5 h-5"></i> {% trans "Quick Actions" %}
</h4>
<!-- Activate -->
<form method="post" action="{% url 'complaints:inquiry_activate' inquiry.id %}" class="mb-4">
{% csrf_token %}
{% if inquiry.assigned_to and inquiry.assigned_to == user %}
<button type="submit" class="w-full px-4 py-3 bg-green-500 text-white rounded-xl font-semibold flex items-center justify-center gap-2" disabled>
<i data-lucide="check-circle" class="w-5 h-5"></i> {% trans "Activated (Assigned to You)" %}
</button>
{% else %}
<button type="submit" class="w-full px-4 py-3 bg-cyan-500 text-white rounded-xl font-semibold hover:bg-cyan-600 transition flex items-center justify-center gap-2">
<i data-lucide="zap" class="w-5 h-5"></i> {% trans "Activate" %}
</button>
{% endif %}
</form>
<!-- Change Status -->
<form method="post" action="{% url 'complaints:inquiry_change_status' inquiry.id %}" class="mb-4">
{% csrf_token %}
<label class="block text-sm font-semibold text-gray-700 mb-2">{% trans "Change Status" %}</label>
<select name="status" class="w-full px-4 py-3 border border-gray-200 rounded-xl text-gray-800 focus:ring-2 focus:ring-cyan-500 focus:border-transparent transition mb-2" required>
{% for value, label in status_choices %}
<option value="{{ value }}" {% if inquiry.status == value %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
<textarea name="note" class="w-full px-4 py-3 border border-gray-200 rounded-xl text-gray-800 focus:ring-2 focus:ring-cyan-500 focus:border-transparent transition mb-2" rows="2" placeholder="{% trans 'Optional note...' %}"></textarea>
<button type="submit" class="w-full px-4 py-3 bg-cyan-500 text-white rounded-xl font-semibold hover:bg-cyan-600 transition flex items-center justify-center gap-2">
<i data-lucide="refresh-cw" class="w-5 h-5"></i> {% trans "Update Status" %}
</button>
</form>
</div>
{% endif %}
<!-- Add Note -->
<div class="bg-white rounded-2xl border border-gray-50 shadow-sm p-6">
<h4 class="font-bold text-gray-800 mb-4 flex items-center gap-2">
<i data-lucide="message-circle" class="w-5 h-5"></i> {% trans "Add Note" %}
</h4>
<form method="post" action="{% url 'complaints:inquiry_add_note' inquiry.id %}">
{% csrf_token %}
<textarea name="note" class="w-full px-4 py-3 border border-gray-200 rounded-xl text-gray-800 focus:ring-2 focus:ring-cyan-500 focus:border-transparent transition mb-3" rows="3" placeholder="{% trans 'Enter your note...' %}" required></textarea>
<button type="submit" class="w-full px-4 py-3 bg-green-500 text-white rounded-xl font-semibold hover:bg-green-600 transition flex items-center justify-center gap-2">
<i data-lucide="plus-circle" class="w-5 h-5"></i> {% trans "Add Note" %}
</button>
</form>
</div>
<!-- Response Form -->
{% if can_edit and inquiry.status != 'resolved' and inquiry.status != 'closed' %}
<div class="bg-white rounded-2xl border border-gray-50 shadow-sm p-6">
<h4 class="font-bold text-gray-800 mb-4 flex items-center gap-2">
<i data-lucide="reply" class="w-5 h-5"></i> {% trans "Respond to Inquiry" %}
</h4>
<form method="post" action="{% url 'complaints:inquiry_respond' inquiry.id %}">
{% csrf_token %}
<textarea name="response" class="w-full px-4 py-3 border border-gray-200 rounded-xl text-gray-800 focus:ring-2 focus:ring-cyan-500 focus:border-transparent transition mb-3" rows="4" placeholder="{% trans 'Enter your response...' %}" required></textarea>
<button type="submit" class="w-full px-4 py-3 bg-cyan-500 text-white rounded-xl font-semibold hover:bg-cyan-600 transition flex items-center justify-center gap-2">
<i data-lucide="send" class="w-5 h-5"></i> {% trans "Send Response" %}
</button>
</form>
</div>
{% endif %}
<!-- Contact Information -->
<div class="bg-white rounded-2xl border border-gray-50 shadow-sm p-6">
<h4 class="font-bold text-gray-800 mb-4 flex items-center gap-2">
<i data-lucide="info" class="w-5 h-5"></i> {% trans "Contact Information" %}
</h4>
<div class="space-y-4">
{% if inquiry.patient %}
<div>
<div class="info-label mb-1">{% trans "Patient" %}</div>
<div class="text-gray-700 font-medium">
{{ inquiry.patient.get_full_name }}
<br>
<small class="text-gray-500">{% trans "MRN" %}: {{ inquiry.patient.mrn }}</small>
</div>
</div>
{% if inquiry.patient.phone %}
<div>
<div class="info-label mb-1">{% trans "Phone" %}</div>
<div class="text-gray-700 font-medium">{{ inquiry.patient.phone }}</div>
</div>
{% endif %}
{% if inquiry.patient.email %}
<div>
<div class="info-label mb-1">{% trans "Email" %}</div>
<div class="text-gray-700 font-medium">{{ inquiry.patient.email }}</div>
</div>
{% endif %}
{% else %}
{% if inquiry.contact_name %}
<div>
<div class="info-label mb-1">{% trans "Name" %}</div>
<div class="text-gray-700 font-medium">{{ inquiry.contact_name }}</div>
</div>
{% endif %}
{% if inquiry.contact_phone %}
<div>
<div class="info-label mb-1">{% trans "Phone" %}</div>
<div class="text-gray-700 font-medium">{{ inquiry.contact_phone }}</div>
</div>
{% endif %}
{% if inquiry.contact_email %}
<div>
<div class="info-label mb-1">{% trans "Email" %}</div>
<div class="text-gray-700 font-medium">{{ inquiry.contact_email }}</div>
</div>
{% endif %}
{% endif %}
</div>
</div>
<!-- Assignment Info -->
<div class="bg-white rounded-2xl border border-gray-50 shadow-sm p-6">
<h4 class="font-bold text-gray-800 mb-4 flex items-center gap-2">
<i data-lucide="user-check" class="w-5 h-5"></i> {% trans "Assignment Info" %}
</h4>
<div class="space-y-4">
<div>
<div class="info-label mb-1">{% trans "Assigned To" %}</div>
<div class="text-gray-700 font-medium">
{% if inquiry.assigned_to %}{{ inquiry.assigned_to.get_full_name }}{% else %}<span class="text-gray-400">{% trans "Unassigned" %}</span>{% endif %}
</div>
</div>
{% if inquiry.responded_by %}
<div>
<div class="info-label mb-1">{% trans "Responded By" %}</div>
<div class="text-gray-700 font-medium">
{{ inquiry.responded_by.get_full_name }}
<br>
<small class="text-gray-500">{{ inquiry.responded_at|date:"M d, Y H:i" }}</small>
</div>
</div>
{% endif %}
{% if inquiry.resolved_by %}
<div>
<div class="info-label mb-1">{% trans "Resolved By" %}</div>
<div class="text-gray-700 font-medium">
{{ inquiry.resolved_by.get_full_name }}
<br>
<small class="text-gray-500">{{ inquiry.resolved_at|date:"M d, Y H:i" }}</small>
</div>
</div>
{% endif %}
</div>
</div>
</div>
</div>
<script>
// Tab switching
document.querySelectorAll('.tab-btn').forEach(btn => {
btn.addEventListener('click', () => {
// Remove active class from all tabs and panels
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
document.querySelectorAll('.tab-panel').forEach(p => p.classList.add('hidden'));
// Add active class to clicked tab
btn.classList.add('active');
// Show corresponding panel
const target = btn.dataset.target;
document.getElementById(target).classList.remove('hidden');
});
});
</script>
<style>
.tab-btn {
@apply px-4 py-3 text-sm font-semibold text-gray-500 hover:text-gray-700 hover:bg-gray-50 transition border-b-2 border-transparent;
}
.tab-btn.active {
@apply text-cyan-500 border-cyan-500;
}
.tab-panel {
@apply block;
}
.tab-panel.hidden {
@apply hidden;
}
</style>
{% endblock %}