HH/templates/appreciation/appreciation_list.html
2026-03-09 16:10:24 +03:00

325 lines
17 KiB
HTML

{% extends "layouts/base.html" %}
{% load i18n static %}
{% block title %}{% trans "Appreciation" %} - PX360{% endblock %}
{% block content %}
<!-- Header -->
<header class="mb-6">
<div class="flex justify-between items-start">
<div>
<h1 class="text-2xl font-bold text-navy flex items-center gap-3">
<i data-lucide="heart" class="w-7 h-7 text-rose-500"></i>
{% trans "Appreciation" %}
</h1>
<p class="text-sm text-slate mt-1">{% trans "Send appreciation to colleagues and celebrate achievements" %}</p>
</div>
<a href="{% url 'appreciation:appreciation_send' %}" class="bg-navy text-white px-5 py-2.5 rounded-xl text-sm font-bold shadow-lg shadow-navy/20 hover:bg-blue flex items-center gap-2 transition">
<i data-lucide="send" class="w-4 h-4"></i> {% trans "Send Appreciation" %}
</a>
</div>
</header>
<!-- Stats Cards -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6">
<div class="bg-white p-5 rounded-2xl shadow-sm border border-slate-100">
<div class="flex items-center gap-4">
<div class="p-3 bg-blue-50 rounded-xl">
<i data-lucide="inbox" class="w-6 h-6 text-blue-500"></i>
</div>
<div>
<p class="text-xs font-bold text-slate uppercase tracking-wider mb-1">{% trans "Received" %}</p>
<p class="text-2xl font-black text-navy" id="receivedCount">{{ stats.received }}</p>
</div>
</div>
</div>
<div class="bg-white p-5 rounded-2xl shadow-sm border border-slate-100">
<div class="flex items-center gap-4">
<div class="p-3 bg-green-50 rounded-xl">
<i data-lucide="send" class="w-6 h-6 text-green-500"></i>
</div>
<div>
<p class="text-xs font-bold text-slate uppercase tracking-wider mb-1">{% trans "Sent" %}</p>
<p class="text-2xl font-black text-navy" id="sentCount">{{ stats.sent }}</p>
</div>
</div>
</div>
<div class="bg-white p-5 rounded-2xl shadow-sm border border-slate-100">
<div class="flex items-center gap-4">
<div class="p-3 bg-amber-50 rounded-xl">
<i data-lucide="award" class="w-6 h-6 text-amber-500"></i>
</div>
<div>
<p class="text-xs font-bold text-slate uppercase tracking-wider mb-1">{% trans "Badges Earned" %}</p>
<p class="text-2xl font-black text-navy" id="badgesCount">{{ stats.badges_earned }}</p>
</div>
</div>
</div>
<div class="bg-white p-5 rounded-2xl shadow-sm border border-slate-100">
<div class="flex items-center gap-4">
<div class="p-3 bg-purple-50 rounded-xl">
<i data-lucide="trophy" class="w-6 h-6 text-purple-500"></i>
</div>
<div>
<p class="text-xs font-bold text-slate uppercase tracking-wider mb-1">{% trans "Leaderboard" %}</p>
<a href="{% url 'appreciation:leaderboard_view' %}" class="text-sm font-bold text-navy hover:text-blue transition flex items-center gap-1">
{% trans "View" %} <i data-lucide="arrow-right" class="w-4 h-4"></i>
</a>
</div>
</div>
</div>
</div>
<!-- Quick Actions -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
<a href="{% url 'appreciation:leaderboard_view' %}" class="group">
<div class="bg-white p-5 rounded-2xl shadow-sm border border-amber-200 hover:border-amber-300 hover:shadow-md transition">
<div class="flex items-center gap-4">
<div class="p-3 bg-amber-50 rounded-xl group-hover:bg-amber-100 transition">
<i data-lucide="trophy" class="w-6 h-6 text-amber-500"></i>
</div>
<div>
<h3 class="font-bold text-navy">{% trans "Leaderboard" %}</h3>
<p class="text-sm text-slate">{% trans "See top performers" %}</p>
</div>
</div>
</div>
</a>
<a href="{% url 'appreciation:my_badges_view' %}" class="group">
<div class="bg-white p-5 rounded-2xl shadow-sm border border-blue-200 hover:border-blue-300 hover:shadow-md transition">
<div class="flex items-center gap-4">
<div class="p-3 bg-blue-50 rounded-xl group-hover:bg-blue-100 transition">
<i data-lucide="award" class="w-6 h-6 text-blue-500"></i>
</div>
<div>
<h3 class="font-bold text-navy">{% trans "My Badges" %}</h3>
<p class="text-sm text-slate">{% trans "View earned badges" %}</p>
</div>
</div>
</div>
</a>
<a href="{% url 'appreciation:appreciation_send' %}" class="group">
<div class="bg-white p-5 rounded-2xl shadow-sm border border-green-200 hover:border-green-300 hover:shadow-md transition">
<div class="flex items-center gap-4">
<div class="p-3 bg-green-50 rounded-xl group-hover:bg-green-100 transition">
<i data-lucide="send" class="w-6 h-6 text-green-500"></i>
</div>
<div>
<h3 class="font-bold text-navy">{% trans "Send Appreciation" %}</h3>
<p class="text-sm text-slate">{% trans "Share appreciation" %}</p>
</div>
</div>
</div>
</a>
</div>
<!-- Filter Bar -->
<div class="bg-white rounded-2xl shadow-sm border-2 border-slate-200 mb-6">
<div class="px-6 py-4 border-b-2 border-slate-200 flex justify-between items-center bg-gradient-to-r from-slate-50 to-slate-100">
<h3 class="font-bold text-navy flex items-center gap-2">
<i data-lucide="filter" class="w-5 h-5 text-navy"></i>
{% trans "Filters" %}
</h3>
</div>
<div class="p-5">
<form method="get" class="grid grid-cols-1 md:grid-cols-4 gap-4">
<div>
<label class="block text-xs font-bold text-slate uppercase mb-2">{% trans "View" %}</label>
<select id="tab" name="tab" onchange="this.form.submit()"
class="w-full px-4 py-2.5 border border-slate-200 rounded-xl text-sm focus:ring-2 focus:ring-navy focus:border-transparent transition">
<option value="received" {% if current_tab == 'received' %}selected{% endif %}>
{% trans "My Appreciations" %}
</option>
<option value="sent" {% if current_tab == 'sent' %}selected{% endif %}>
{% trans "Sent by Me" %}
</option>
</select>
</div>
<div>
<label class="block text-xs font-bold text-slate uppercase mb-2">{% trans "Status" %}</label>
<select id="status" name="status" onchange="this.form.submit()"
class="w-full px-4 py-2.5 border border-slate-200 rounded-xl text-sm focus:ring-2 focus:ring-navy focus:border-transparent transition">
<option value="">{% trans "All Status" %}</option>
{% for choice in status_choices %}
<option value="{{ choice.0 }}" {% if filters.status == choice.0 %}selected{% endif %}>
{{ choice.1 }}
</option>
{% endfor %}
</select>
</div>
<div>
<label class="block text-xs font-bold text-slate uppercase mb-2">{% trans "Category" %}</label>
<select id="category" name="category" onchange="this.form.submit()"
class="w-full px-4 py-2.5 border border-slate-200 rounded-xl text-sm focus:ring-2 focus:ring-navy focus:border-transparent transition">
<option value="">{% trans "All Categories" %}</option>
{% for cat in categories %}
<option value="{{ cat.id }}" {% if filters.category == cat.id|stringformat:"s" %}selected{% endif %}>
{{ cat.name_en }}
</option>
{% endfor %}
</select>
</div>
<div>
<label class="block text-xs font-bold text-slate uppercase mb-2">{% trans "Search" %}</label>
<div class="flex gap-2">
<input type="text" id="search" name="search"
value="{{ filters.search|default:'' }}" placeholder="{% trans 'Search messages...' %}"
class="flex-1 px-4 py-2.5 border border-slate-200 rounded-xl text-sm focus:ring-2 focus:ring-navy focus:border-transparent transition">
<button type="submit" class="bg-navy text-white px-4 py-2.5 rounded-xl hover:bg-blue transition">
<i data-lucide="search" class="w-4 h-4"></i>
</button>
</div>
</div>
</form>
<div class="mt-4 pt-4 border-t border-slate-100">
<a href="{% url 'appreciation:appreciation_list' %}" class="text-sm font-bold text-slate hover:text-navy transition flex items-center gap-2">
<i data-lucide="rotate-ccw" class="w-4 h-4"></i> {% trans "Clear Filters" %}
</a>
</div>
</div>
</div>
<!-- Appreciations List -->
<div class="bg-white rounded-2xl shadow-sm border-2 border-slate-200 overflow-hidden">
<div class="px-6 py-4 border-b-2 border-slate-200 bg-gradient-to-r from-slate-50 to-slate-100">
<h3 class="font-bold text-navy flex items-center gap-2">
<i data-lucide="heart" class="w-5 h-5 text-rose-500"></i>
{% trans "Appreciations" %}
</h3>
</div>
<div class="p-6">
{% if page_obj %}
<div class="space-y-3">
{% for appreciation in page_obj %}
<a href="{% url 'appreciation:appreciation_detail' appreciation.id %}"
class="block p-4 rounded-xl border border-slate-100 hover:border-navy/30 hover:bg-light transition group">
<div class="flex justify-between items-start gap-4">
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2 mb-2">
{% if appreciation.category %}
<span class="inline-flex items-center px-2.5 py-1 rounded-lg text-xs font-bold bg-blue-100 text-blue-700">
<i data-lucide="{{ appreciation.category.icon|default:'heart' }}" class="w-3 h-3 mr-1"></i>
{{ appreciation.category.name_en }}
</span>
{% endif %}
<h4 class="font-bold text-navy">
{% if current_tab == 'received' %}
{{ appreciation.sender.get_full_name }}
{% else %}
{{ appreciation.recipient_name }}
{% endif %}
</h4>
</div>
<p class="text-sm text-slate mb-2 line-clamp-2">{{ appreciation.message_en|truncatewords:15 }}</p>
<div class="flex items-center gap-3 text-xs text-slate">
<span class="flex items-center gap-1">
<i data-lucide="clock" class="w-3 h-3"></i>
{{ appreciation.sent_at|date:"F j, Y, g:i A" }}
</span>
{% if appreciation.department %}
<span class="flex items-center gap-1">
<i data-lucide="building" class="w-3 h-3"></i>
{{ appreciation.department.name }}
</span>
{% endif %}
</div>
</div>
<div class="text-right">
<span class="inline-flex items-center px-3 py-1 rounded-full text-xs font-bold {% if appreciation.status == 'acknowledged' %}bg-green-100 text-green-700{% else %}bg-blue-100 text-blue-700{% endif %}">
{{ appreciation.get_status_display }}
</span>
<div class="text-xs text-slate mt-1">
{{ appreciation.get_visibility_display }}
</div>
</div>
</div>
</a>
{% endfor %}
</div>
<!-- Pagination -->
{% if page_obj.has_other_pages %}
<div class="mt-6 pt-6 border-t border-slate-100 flex justify-center">
<div class="flex items-center gap-2">
{% if page_obj.has_previous %}
<a href="?page={{ page_obj.previous_page_number }}&tab={{ current_tab }}{% if filters.urlencode %}&{{ filters.urlencode }}{% endif %}"
class="px-3 py-2 rounded-lg border border-slate-200 text-slate hover:bg-light transition">
{% trans "Previous" %}
</a>
{% else %}
<span class="px-3 py-2 rounded-lg border border-slate-200 text-gray-300 cursor-not-allowed">
{% trans "Previous" %}
</span>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<span class="px-4 py-2 rounded-lg bg-navy text-white font-bold">{{ num }}</span>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<a href="?page={{ num }}&tab={{ current_tab }}{% if filters.urlencode %}&{{ filters.urlencode }}{% endif %}"
class="px-4 py-2 rounded-lg border border-slate-200 text-slate hover:bg-light transition">
{{ num }}
</a>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}&tab={{ current_tab }}{% if filters.urlencode %}&{{ filters.urlencode }}{% endif %}"
class="px-3 py-2 rounded-lg border border-slate-200 text-slate hover:bg-light transition">
{% trans "Next" %}
</a>
{% else %}
<span class="px-3 py-2 rounded-lg border border-slate-200 text-gray-300 cursor-not-allowed">
{% trans "Next" %}
</span>
{% endif %}
</div>
</div>
{% endif %}
{% else %}
<div class="text-center py-12">
<div class="w-16 h-16 bg-rose-50 rounded-full flex items-center justify-center mx-auto mb-4">
<i data-lucide="heart" class="w-8 h-8 text-rose-400"></i>
</div>
<h4 class="text-lg font-bold text-navy mb-2">
{% if current_tab == 'received' %}
{% trans "No appreciations received yet" %}
{% else %}
{% trans "No appreciations sent yet" %}
{% endif %}
</h4>
<p class="text-slate mb-4">{% trans "Start sharing appreciation with your colleagues!" %}</p>
<a href="{% url 'appreciation:appreciation_send' %}" class="bg-navy text-white px-5 py-2.5 rounded-xl text-sm font-bold hover:bg-blue transition inline-flex items-center gap-2">
<i data-lucide="send" class="w-4 h-4"></i> {% trans "Send Your First Appreciation" %}
</a>
</div>
{% endif %}
</div>
</div>
{% endblock %}
{% block extra_js %}
{{ block.super }}
<script>
// Refresh summary statistics periodically (every 30 seconds)
function refreshSummary() {
fetch("{% url 'appreciation:appreciation_summary_ajax' %}")
.then(response => response.json())
.then(data => {
document.getElementById('receivedCount').textContent = data.total_received || 0;
document.getElementById('sentCount').textContent = data.total_sent || 0;
document.getElementById('badgesCount').textContent = data.badges_earned || 0;
})
.catch(error => {
console.error('Error refreshing summary:', error);
});
}
// Refresh summary every 30 seconds
setInterval(refreshSummary, 30000);
// Initial summary refresh after page load
setTimeout(refreshSummary, 1000);
</script>
{% endblock %}