214 lines
11 KiB
HTML
214 lines
11 KiB
HTML
{% extends "layouts/public_base.html" %}
|
|
{% load i18n %}
|
|
|
|
{% block title %}{% trans "Track Your Complaint" %}{% endblock %}
|
|
|
|
{% block extra_css %}
|
|
<style>
|
|
.glass-effect {
|
|
background: rgba(255, 255, 255, 0.7);
|
|
backdrop-filter: blur(12px);
|
|
-webkit-backdrop-filter: blur(12px);
|
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
|
}
|
|
|
|
.timeline-dot::after {
|
|
content: '';
|
|
position: absolute;
|
|
width: 2px;
|
|
height: 100%;
|
|
background: #e2e8f0;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
top: 24px;
|
|
z-index: 0;
|
|
}
|
|
|
|
.timeline-item:last-child .timeline-dot::after {
|
|
display: none;
|
|
}
|
|
|
|
@keyframes subtle-float {
|
|
0% { transform: translateY(0px); }
|
|
50% { transform: translateY(-5px); }
|
|
100% { transform: translateY(0px); }
|
|
}
|
|
.float-icon { animation: subtle-float 3s ease-in-out infinite; }
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="max-w-4xl mx-auto px-4 py-8 md:py-12">
|
|
<a href="/" class="inline-flex items-center gap-2 text-navy/70 hover:text-navy mb-8 transition-all font-medium group">
|
|
<div class="p-2 rounded-full group-hover:bg-navy/5 transition-colors">
|
|
<i data-lucide="arrow-left" class="w-5 h-5 group-hover:-translate-x-1 transition-transform"></i>
|
|
</div>
|
|
{% trans "Back to Home" %}
|
|
</a>
|
|
|
|
<div class="glass-card rounded-[2rem] shadow-xl border border-white/50 p-8 md:p-12 mb-10 transition-all hover:shadow-2xl animate-fade-in overflow-hidden relative">
|
|
<div class="absolute -top-24 -right-24 w-48 h-48 bg-blue/5 rounded-full blur-3xl"></div>
|
|
|
|
<div class="text-center mb-10 relative">
|
|
<div class="inline-flex items-center justify-center w-24 h-24 bg-gradient-to-tr from-navy via-navy to-blue rounded-3xl mb-6 shadow-xl rotate-3 float-icon">
|
|
<i data-lucide="search" class="w-10 h-10 text-white -rotate-3"></i>
|
|
</div>
|
|
<h1 class="text-4xl font-extrabold text-navy mb-3 tracking-tight">
|
|
{% trans "Track Your Complaint" %}
|
|
</h1>
|
|
<p class="text-slate/80 text-lg max-w-md mx-auto">
|
|
{% trans "Enter your reference number below to see real-time updates on your request." %}
|
|
</p>
|
|
</div>
|
|
|
|
<form method="POST" class="max-w-lg mx-auto relative">
|
|
{% csrf_token %}
|
|
<div class="relative group">
|
|
<div class="absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none">
|
|
<i data-lucide="hash" class="w-5 h-5 text-slate/40 group-focus-within:text-blue transition-colors"></i>
|
|
</div>
|
|
<input
|
|
type="text"
|
|
name="reference_number"
|
|
class="w-full pl-12 pr-6 py-5 border-2 border-slate-100 rounded-2xl text-navy text-lg focus:ring-4 focus:ring-blue/10 focus:border-blue transition-all duration-300 bg-white/80 placeholder:text-slate/30"
|
|
placeholder="{% trans 'e.g., CMP-20240101-123456' %}"
|
|
value="{{ reference_number }}"
|
|
required
|
|
>
|
|
</div>
|
|
<button type="submit" class="w-full mt-4 bg-navy hover:bg-navy/90 text-white px-8 py-5 rounded-2xl font-bold text-lg transition-all duration-300 shadow-lg shadow-navy/20 hover:shadow-xl hover:-translate-y-1 flex items-center justify-center gap-3">
|
|
<i data-lucide="crosshair" class="w-5 h-5"></i>
|
|
{% trans "Track Status" %}
|
|
</button>
|
|
</form>
|
|
<p class="text-center text-slate/50 text-xs mt-6 uppercase tracking-widest font-semibold">
|
|
<i data-lucide="info" class="w-3 h-3 inline mr-1"></i>
|
|
{% trans "Found in your confirmation email" %}
|
|
</p>
|
|
</div>
|
|
|
|
{% if error_message %}
|
|
<div class="bg-rose-50 border border-rose-100 rounded-2xl p-6 mb-8 flex items-center gap-4 animate-shake">
|
|
<div class="w-12 h-12 bg-rose-100 rounded-xl flex items-center justify-center text-rose-600 shrink-0">
|
|
<i data-lucide="alert-circle" class="w-6 h-6"></i>
|
|
</div>
|
|
<div>
|
|
<h3 class="font-bold text-rose-900">{% trans "Reference Not Found" %}</h3>
|
|
<p class="text-rose-700/80 text-sm">{{ error_message }}</p>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if complaint %}
|
|
<div class="animate-slide-up" style="animation-delay: 0.1s">
|
|
<div class="bg-white rounded-3xl shadow-lg border border-slate-100 p-6 md:p-8 mb-6 relative overflow-hidden">
|
|
<div class="flex flex-col md:flex-row md:items-center justify-between gap-6">
|
|
<div>
|
|
<span class="text-xs font-bold text-slate/40 uppercase tracking-widest block mb-1">{% trans "Case Reference" %}</span>
|
|
<h2 class="text-3xl font-black text-navy">{{ complaint.reference_number }}</h2>
|
|
</div>
|
|
<div class="flex items-center gap-3">
|
|
<div class="text-right hidden md:block">
|
|
<span class="text-xs font-bold text-slate/40 uppercase tracking-widest block mb-1">{% trans "Current Status" %}</span>
|
|
<p class="font-bold text-navy">{{ complaint.get_status_display }}</p>
|
|
</div>
|
|
<div class="px-6 py-3 rounded-2xl text-sm font-black uppercase tracking-wider shadow-sm border-b-4
|
|
{% if complaint.status == 'open' %}bg-amber-50 text-amber-700 border-amber-200
|
|
{% elif complaint.status == 'in_progress' %}bg-blue-50 text-blue-700 border-blue-200
|
|
{% elif complaint.status == 'resolved' %}bg-emerald-50 text-emerald-700 border-emerald-200
|
|
{% else %}bg-slate-50 text-slate-700 border-slate-200{% endif %}">
|
|
{{ complaint.status }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-8 h-2 w-full bg-slate-100 rounded-full overflow-hidden">
|
|
<div class="h-full bg-navy transition-all duration-1000"
|
|
style="width: {% if complaint.status == 'resolved' %}100%{% elif complaint.status == 'in_progress' %}50%{% else %}15%{% endif %}">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-10">
|
|
<div class="bg-white p-6 rounded-2xl border border-slate-100 shadow-sm transition-hover hover:shadow-md">
|
|
<i data-lucide="calendar" class="w-5 h-5 text-blue mb-3"></i>
|
|
<span class="block text-xs font-bold text-slate/50 uppercase">{% trans "Submitted" %}</span>
|
|
<p class="font-bold text-navy">{{ complaint.created_at|date:"M d, Y" }}</p>
|
|
</div>
|
|
<div class="bg-white p-6 rounded-2xl border border-slate-100 shadow-sm transition-hover hover:shadow-md">
|
|
<i data-lucide="building" class="w-5 h-5 text-blue mb-3"></i>
|
|
<span class="block text-xs font-bold text-slate/50 uppercase">{% trans "Department" %}</span>
|
|
<p class="font-bold text-navy truncate">{{ complaint.department.name|default:"General" }}</p>
|
|
</div>
|
|
<div class="bg-white p-6 rounded-2xl border border-slate-100 shadow-sm transition-hover hover:shadow-md relative overflow-hidden">
|
|
<i data-lucide="clock" class="w-5 h-5 {% if complaint.is_overdue %}text-rose-500{% else %}text-blue{% endif %} mb-3"></i>
|
|
<span class="block text-xs font-bold text-slate/50 uppercase">{% trans "SLA Deadline" %}</span>
|
|
<p class="font-bold text-navy">{{ complaint.due_at|date:"M d, H:i" }}</p>
|
|
{% if complaint.is_overdue %}
|
|
<span class="absolute top-2 right-2 flex h-2 w-2">
|
|
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-rose-400 opacity-75"></span>
|
|
<span class="relative inline-flex rounded-full h-2 w-2 bg-rose-500"></span>
|
|
</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bg-white rounded-3xl shadow-lg border border-slate-100 p-8 md:p-10">
|
|
<h3 class="text-2xl font-bold text-navy mb-10 flex items-center gap-3">
|
|
<div class="p-2 bg-navy text-white rounded-lg">
|
|
<i data-lucide="list-checks" class="w-5 h-5"></i>
|
|
</div>
|
|
{% trans "Resolution Journey" %}
|
|
</h3>
|
|
|
|
{% if public_updates %}
|
|
<div class="space-y-1">
|
|
{% for update in public_updates %}
|
|
<div class="timeline-item flex gap-6 pb-10 relative">
|
|
<div class="timeline-dot shrink-0 relative z-10">
|
|
<div class="w-12 h-12 rounded-2xl flex items-center justify-center shadow-sm border-2 border-white
|
|
{% if update.update_type == 'status_change' %}bg-amber-100 text-amber-600
|
|
{% elif update.update_type == 'resolution' %}bg-emerald-100 text-emerald-600
|
|
{% else %}bg-blue-50 text-blue-600{% endif %}">
|
|
<i data-lucide="{% if update.update_type == 'status_change' %}refresh-cw{% elif update.update_type == 'resolution' %}check-circle-2{% else %}message-square{% endif %}" class="w-6 h-6"></i>
|
|
</div>
|
|
</div>
|
|
<div class="flex-1 pt-1">
|
|
<div class="flex flex-col md:flex-row md:items-center justify-between mb-2">
|
|
<h4 class="font-black text-navy text-lg">
|
|
{% if update.update_type == 'status_change' %}{% trans "Status Updated" %}
|
|
{% elif update.update_type == 'resolution' %}{% trans "Final Resolution" %}
|
|
{% else %}{% trans "Update Received" %}{% endif %}
|
|
</h4>
|
|
<time class="text-sm font-medium text-slate/40">{{ update.created_at|date:"F j, Y • g:i A" }}</time>
|
|
</div>
|
|
{% if update.comments %}
|
|
<div class="bg-slate-50/50 rounded-2xl p-5 border border-slate-100 text-slate-700 leading-relaxed shadow-inner">
|
|
{{ update.comments|linebreaks }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% else %}
|
|
<div class="text-center py-12">
|
|
<div class="w-20 h-20 bg-slate-50 rounded-full flex items-center justify-center mx-auto mb-4">
|
|
<i data-lucide="loader" class="w-8 h-8 text-slate/30 animate-spin"></i>
|
|
</div>
|
|
<p class="text-slate/60 font-medium">{% trans "Your complaint is being reviewed. Updates will appear here." %}</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
if (typeof lucide !== 'undefined') {
|
|
lucide.createIcons();
|
|
}
|
|
});
|
|
</script>
|
|
{% endblock %} |