491 lines
12 KiB
HTML
491 lines
12 KiB
HTML
{% extends "layouts/public_base.html" %}
|
|
{% load i18n %}
|
|
|
|
{% block title %}{% trans "Track Your Complaint" %}{% endblock %}
|
|
|
|
{% block extra_css %}
|
|
<style>
|
|
.track-container {
|
|
max-width: 900px;
|
|
margin: 4rem auto;
|
|
padding: 2rem;
|
|
}
|
|
|
|
.search-card {
|
|
background: white;
|
|
border-radius: 12px;
|
|
padding: 3rem;
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
|
margin-bottom: 2rem;
|
|
}
|
|
|
|
.search-icon {
|
|
font-size: 4rem;
|
|
color: #3498db;
|
|
margin-bottom: 2rem;
|
|
}
|
|
|
|
.search-form {
|
|
max-width: 600px;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.search-input {
|
|
width: 100%;
|
|
padding: 1rem 1.5rem;
|
|
border: 2px solid #dee2e6;
|
|
border-radius: 8px;
|
|
font-size: 1.1rem;
|
|
margin-bottom: 1rem;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.search-input:focus {
|
|
outline: none;
|
|
border-color: #3498db;
|
|
box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.1);
|
|
}
|
|
|
|
.btn-search {
|
|
width: 100%;
|
|
background: linear-gradient(135deg, #3498db 0%, #2980b9 100%);
|
|
border: none;
|
|
padding: 1rem 2rem;
|
|
border-radius: 8px;
|
|
color: white;
|
|
font-weight: 600;
|
|
font-size: 1.1rem;
|
|
cursor: pointer;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.btn-search:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 4px 12px rgba(52, 152, 219, 0.4);
|
|
}
|
|
|
|
.complaint-card {
|
|
background: white;
|
|
border-radius: 12px;
|
|
padding: 2rem;
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
|
margin-bottom: 2rem;
|
|
}
|
|
|
|
.status-badge {
|
|
display: inline-block;
|
|
padding: 0.5rem 1.5rem;
|
|
border-radius: 20px;
|
|
font-weight: 600;
|
|
font-size: 1.1rem;
|
|
text-transform: uppercase;
|
|
letter-spacing: 1px;
|
|
}
|
|
|
|
.status-open {
|
|
background: #ffeeba;
|
|
color: #856404;
|
|
}
|
|
|
|
.status-in_progress {
|
|
background: #b8daff;
|
|
color: #004085;
|
|
}
|
|
|
|
.status-partially_resolved {
|
|
background: #fff3cd;
|
|
color: #856404;
|
|
}
|
|
|
|
.status-resolved {
|
|
background: #d4edda;
|
|
color: #155724;
|
|
}
|
|
|
|
.status-closed {
|
|
background: #e2e3e5;
|
|
color: #383d41;
|
|
}
|
|
|
|
.status-cancelled {
|
|
background: #f8d7da;
|
|
color: #721c24;
|
|
}
|
|
|
|
.complaint-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
gap: 1rem;
|
|
margin-bottom: 1.5rem;
|
|
padding-bottom: 1.5rem;
|
|
border-bottom: 1px solid #dee2e6;
|
|
}
|
|
|
|
.reference-display {
|
|
font-size: 1.5rem;
|
|
font-weight: 700;
|
|
color: #2c3e50;
|
|
}
|
|
|
|
.sla-section {
|
|
background: #e8f4f8;
|
|
border-radius: 8px;
|
|
padding: 1.5rem;
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
|
|
.sla-section.overdue {
|
|
background: #f8d7da;
|
|
border-left: 4px solid #dc3545;
|
|
}
|
|
|
|
.sla-section .icon {
|
|
font-size: 2rem;
|
|
color: #3498db;
|
|
}
|
|
|
|
.sla-section.overdue .icon {
|
|
color: #dc3545;
|
|
}
|
|
|
|
.info-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
gap: 1.5rem;
|
|
margin-bottom: 2rem;
|
|
}
|
|
|
|
.info-item {
|
|
background: #f8f9fa;
|
|
border-radius: 8px;
|
|
padding: 1rem;
|
|
}
|
|
|
|
.info-label {
|
|
font-size: 0.875rem;
|
|
color: #6c757d;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.info-value {
|
|
font-weight: 600;
|
|
color: #2c3e50;
|
|
}
|
|
|
|
.timeline-section {
|
|
margin-top: 2rem;
|
|
}
|
|
|
|
.timeline-header {
|
|
font-size: 1.25rem;
|
|
margin-bottom: 1.5rem;
|
|
color: #2c3e50;
|
|
}
|
|
|
|
.timeline {
|
|
position: relative;
|
|
padding-left: 2rem;
|
|
}
|
|
|
|
.timeline::before {
|
|
content: '';
|
|
position: absolute;
|
|
left: 0.5rem;
|
|
top: 0;
|
|
bottom: 0;
|
|
width: 2px;
|
|
background: #dee2e6;
|
|
}
|
|
|
|
.timeline-item {
|
|
position: relative;
|
|
margin-bottom: 1.5rem;
|
|
padding-bottom: 1.5rem;
|
|
border-bottom: 1px solid #f0f0f0;
|
|
}
|
|
|
|
.timeline-item:last-child {
|
|
border-bottom: none;
|
|
margin-bottom: 0;
|
|
padding-bottom: 0;
|
|
}
|
|
|
|
.timeline-dot {
|
|
position: absolute;
|
|
left: -1.75rem;
|
|
top: 0.25rem;
|
|
width: 12px;
|
|
height: 12px;
|
|
border-radius: 50%;
|
|
background: #3498db;
|
|
border: 2px solid white;
|
|
box-shadow: 0 0 0 2px #3498db;
|
|
}
|
|
|
|
.timeline-dot.status-change {
|
|
background: #f39c12;
|
|
box-shadow: 0 0 0 2px #f39c12;
|
|
}
|
|
|
|
.timeline-dot.resolution {
|
|
background: #27ae60;
|
|
box-shadow: 0 0 0 2px #27ae60;
|
|
}
|
|
|
|
.timeline-date {
|
|
font-size: 0.875rem;
|
|
color: #6c757d;
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
|
|
.timeline-title {
|
|
font-weight: 600;
|
|
color: #2c3e50;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.timeline-content {
|
|
color: #495057;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.alert-box {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: 1rem;
|
|
background: #fff3cd;
|
|
border: 1px solid #ffeeba;
|
|
border-radius: 8px;
|
|
padding: 1.5rem;
|
|
margin-bottom: 2rem;
|
|
color: #856404;
|
|
}
|
|
|
|
.alert-box i {
|
|
font-size: 1.5rem;
|
|
margin-top: 0.25rem;
|
|
}
|
|
|
|
.help-text {
|
|
text-align: center;
|
|
color: #6c757d;
|
|
margin-top: 1rem;
|
|
font-size: 0.9rem;
|
|
}
|
|
|
|
.no-updates {
|
|
text-align: center;
|
|
padding: 2rem;
|
|
color: #6c757d;
|
|
background: #f8f9fa;
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.back-link {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
color: #3498db;
|
|
text-decoration: none;
|
|
margin-bottom: 2rem;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.back-link:hover {
|
|
color: #2980b9;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.track-container {
|
|
margin: 2rem 1rem;
|
|
padding: 1rem;
|
|
}
|
|
|
|
.search-card {
|
|
padding: 2rem 1.5rem;
|
|
}
|
|
|
|
.complaint-header {
|
|
flex-direction: column;
|
|
text-align: center;
|
|
}
|
|
|
|
.info-grid {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="track-container">
|
|
<a href="{% url 'core:home' %}" class="back-link">
|
|
<i class="fas fa-arrow-left"></i> {% trans "Back to Home" %}
|
|
</a>
|
|
|
|
<!-- Search Form -->
|
|
<div class="search-card">
|
|
<div class="text-center">
|
|
<div class="search-icon">
|
|
<i class="fas fa-search-location"></i>
|
|
</div>
|
|
<h1 style="margin-bottom: 1rem; color: #2c3e50;">
|
|
{% trans "Track Your Complaint" %}
|
|
</h1>
|
|
<p class="lead" style="color: #6c757d; margin-bottom: 2rem;">
|
|
{% trans "Enter your reference number to check the status of your complaint" %}
|
|
</p>
|
|
</div>
|
|
|
|
<form method="POST" class="search-form">
|
|
{% csrf_token %}
|
|
<input
|
|
type="text"
|
|
name="reference_number"
|
|
class="search-input"
|
|
placeholder="{% trans 'e.g., CMP-20240101-123456' %}"
|
|
value="{{ reference_number }}"
|
|
required
|
|
>
|
|
<button type="submit" class="btn-search">
|
|
<i class="fas fa-search"></i> {% trans "Track Complaint" %}
|
|
</button>
|
|
</form>
|
|
<p class="help-text">
|
|
{% trans "Your reference number was provided when you submitted your complaint" %}
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Error Message -->
|
|
{% if error_message %}
|
|
<div class="alert-box">
|
|
<i class="fas fa-exclamation-triangle"></i>
|
|
<div>
|
|
<strong>{% trans "Not Found" %}</strong><br>
|
|
{{ error_message }}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Complaint Details -->
|
|
{% if complaint %}
|
|
<div class="complaint-card">
|
|
<div class="complaint-header">
|
|
<div class="reference-display">
|
|
<i class="fas fa-hashtag"></i> {{ complaint.reference_number }}
|
|
</div>
|
|
<div class="status-badge status-{{ complaint.status }}">
|
|
{{ complaint.get_status_display }}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- SLA Information -->
|
|
<div class="sla-section {% if complaint.is_overdue %}overdue{% endif %}">
|
|
<div style="display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;">
|
|
<div class="icon">
|
|
<i class="fas {% if complaint.is_overdue %}fa-exclamation-circle{% else %}fa-clock{% endif %}"></i>
|
|
</div>
|
|
<div style="flex: 1;">
|
|
<h4 style="margin-bottom: 0.5rem;">
|
|
{% if complaint.is_overdue %}
|
|
{% trans "Response Overdue" %}
|
|
{% else %}
|
|
{% trans "Expected Response Time" %}
|
|
{% endif %}
|
|
</h4>
|
|
<p style="margin-bottom: 0;">
|
|
<strong>{% trans "Due:" %}</strong>
|
|
{{ complaint.due_at|date:"F j, Y" }} at {{ complaint.due_at|time:"g:i A" }}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Information Grid -->
|
|
<div class="info-grid">
|
|
<div class="info-item">
|
|
<div class="info-label">
|
|
<i class="fas fa-calendar"></i> {% trans "Submitted On" %}
|
|
</div>
|
|
<div class="info-value">
|
|
{{ complaint.created_at|date:"F j, Y" }}
|
|
</div>
|
|
</div>
|
|
<div class="info-item">
|
|
<div class="info-label">
|
|
<i class="fas fa-hospital"></i> {% trans "Hospital" %}
|
|
</div>
|
|
<div class="info-value">
|
|
{{ complaint.hospital.name }}
|
|
</div>
|
|
</div>
|
|
{% if complaint.department %}
|
|
<div class="info-item">
|
|
<div class="info-label">
|
|
<i class="fas fa-building"></i> {% trans "Department" %}
|
|
</div>
|
|
<div class="info-value">
|
|
{{ complaint.department.name }}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
<div class="info-item">
|
|
<div class="info-label">
|
|
<i class="fas fa-list"></i> {% trans "Category" %}
|
|
</div>
|
|
<div class="info-value">
|
|
{% if complaint.category %}
|
|
{{ complaint.category.name_en }}
|
|
{% else %}
|
|
{% trans "Pending Classification" %}
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Timeline -->
|
|
{% if public_updates %}
|
|
<div class="timeline-section">
|
|
<h2 class="timeline-header">
|
|
<i class="fas fa-history"></i> {% trans "Complaint Timeline" %}
|
|
</h2>
|
|
<div class="timeline">
|
|
{% for update in public_updates %}
|
|
<div class="timeline-item">
|
|
<div class="timeline-dot {% if update.update_type == 'status_change' %}status-change{% elif update.update_type == 'resolution' %}resolution{% endif %}"></div>
|
|
<div class="timeline-date">
|
|
{{ update.created_at|date:"F j, Y" }} at {{ update.created_at|time:"g:i A" }}
|
|
</div>
|
|
<div class="timeline-title">
|
|
{% if update.update_type == 'status_change' %}
|
|
{% trans "Status Updated" %}
|
|
{% elif update.update_type == 'resolution' %}
|
|
{% trans "Resolution Added" %}
|
|
{% elif update.update_type == 'communication' %}
|
|
{% trans "Update" %}
|
|
{% else %}
|
|
{{ update.get_update_type_display }}
|
|
{% endif %}
|
|
</div>
|
|
{% if update.comments %}
|
|
<div class="timeline-content">
|
|
{{ update.comments|linebreaks }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<div class="no-updates">
|
|
<i class="fas fa-info-circle"></i>
|
|
{% trans "No updates available yet. You will be notified when there is progress on your complaint." %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endblock %}
|